Settings.java revision e84bdd38addecc80878d811ab279646acfe6ab19
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 = ai.dataDir;
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        flags = service.updateFlagsForResolve(flags, userId, intent);
3049        List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
3050                intent.getType(), flags, 0);
3051        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
3052                + " results: " + ri);
3053        int systemMatch = 0;
3054        int thirdPartyMatch = 0;
3055        if (ri != null && ri.size() > 1) {
3056            boolean haveAct = false;
3057            ComponentName haveNonSys = null;
3058            ComponentName[] set = new ComponentName[ri.size()];
3059            for (int i=0; i<ri.size(); i++) {
3060                ActivityInfo ai = ri.get(i).activityInfo;
3061                set[i] = new ComponentName(ai.packageName, ai.name);
3062                if ((ai.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3063                    if (ri.get(i).match >= thirdPartyMatch) {
3064                        // Keep track of the best match we find of all third
3065                        // party apps, for use later to determine if we actually
3066                        // want to set a preferred app for this intent.
3067                        if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3068                                + ai.packageName + "/" + ai.name + ": non-system!");
3069                        haveNonSys = set[i];
3070                        break;
3071                    }
3072                } else if (cn.getPackageName().equals(ai.packageName)
3073                        && cn.getClassName().equals(ai.name)) {
3074                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3075                            + ai.packageName + "/" + ai.name + ": default!");
3076                    haveAct = true;
3077                    systemMatch = ri.get(i).match;
3078                } else {
3079                    if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Result "
3080                            + ai.packageName + "/" + ai.name + ": skipped");
3081                }
3082            }
3083            if (haveNonSys != null && thirdPartyMatch < systemMatch) {
3084                // If we have a matching third party app, but its match is not as
3085                // good as the built-in system app, then we don't want to actually
3086                // consider it a match because presumably the built-in app is still
3087                // the thing we want users to see by default.
3088                haveNonSys = null;
3089            }
3090            if (haveAct && haveNonSys == null) {
3091                IntentFilter filter = new IntentFilter();
3092                if (intent.getAction() != null) {
3093                    filter.addAction(intent.getAction());
3094                }
3095                if (intent.getCategories() != null) {
3096                    for (String cat : intent.getCategories()) {
3097                        filter.addCategory(cat);
3098                    }
3099                }
3100                if ((flags & MATCH_DEFAULT_ONLY) != 0) {
3101                    filter.addCategory(Intent.CATEGORY_DEFAULT);
3102                }
3103                if (scheme != null) {
3104                    filter.addDataScheme(scheme);
3105                }
3106                if (ssp != null) {
3107                    filter.addDataSchemeSpecificPart(ssp.getPath(), ssp.getType());
3108                }
3109                if (auth != null) {
3110                    filter.addDataAuthority(auth);
3111                }
3112                if (path != null) {
3113                    filter.addDataPath(path);
3114                }
3115                if (intent.getType() != null) {
3116                    try {
3117                        filter.addDataType(intent.getType());
3118                    } catch (IntentFilter.MalformedMimeTypeException ex) {
3119                        Slog.w(TAG, "Malformed mimetype " + intent.getType() + " for " + cn);
3120                    }
3121                }
3122                PreferredActivity pa = new PreferredActivity(filter, systemMatch, set, cn, true);
3123                editPreferredActivitiesLPw(userId).addFilter(pa);
3124            } else if (haveNonSys == null) {
3125                StringBuilder sb = new StringBuilder();
3126                sb.append("No component ");
3127                sb.append(cn.flattenToShortString());
3128                sb.append(" found setting preferred ");
3129                sb.append(intent);
3130                sb.append("; possible matches are ");
3131                for (int i=0; i<set.length; i++) {
3132                    if (i > 0) sb.append(", ");
3133                    sb.append(set[i].flattenToShortString());
3134                }
3135                Slog.w(TAG, sb.toString());
3136            } else {
3137                Slog.i(TAG, "Not setting preferred " + intent + "; found third party match "
3138                        + haveNonSys.flattenToShortString());
3139            }
3140        } else {
3141            Slog.w(TAG, "No potential matches found for " + intent + " while setting preferred "
3142                    + cn.flattenToShortString());
3143        }
3144    }
3145
3146    private void readDefaultPreferredActivitiesLPw(PackageManagerService service,
3147            XmlPullParser parser, int userId)
3148            throws XmlPullParserException, IOException {
3149        int outerDepth = parser.getDepth();
3150        int type;
3151        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3152                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3153            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3154                continue;
3155            }
3156
3157            String tagName = parser.getName();
3158            if (tagName.equals(TAG_ITEM)) {
3159                PreferredActivity tmpPa = new PreferredActivity(parser);
3160                if (tmpPa.mPref.getParseError() == null) {
3161                    applyDefaultPreferredActivityLPw(service, tmpPa, tmpPa.mPref.mComponent,
3162                            userId);
3163                } else {
3164                    PackageManagerService.reportSettingsProblem(Log.WARN,
3165                            "Error in package manager settings: <preferred-activity> "
3166                                    + tmpPa.mPref.getParseError() + " at "
3167                                    + parser.getPositionDescription());
3168                }
3169            } else {
3170                PackageManagerService.reportSettingsProblem(Log.WARN,
3171                        "Unknown element under <preferred-activities>: " + parser.getName());
3172                XmlUtils.skipCurrentTag(parser);
3173            }
3174        }
3175    }
3176
3177    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
3178        String v = parser.getAttributeValue(ns, name);
3179        try {
3180            if (v == null) {
3181                return defValue;
3182            }
3183            return Integer.parseInt(v);
3184        } catch (NumberFormatException e) {
3185            PackageManagerService.reportSettingsProblem(Log.WARN,
3186                    "Error in package manager settings: attribute " + name
3187                            + " has bad integer value " + v + " at "
3188                            + parser.getPositionDescription());
3189        }
3190        return defValue;
3191    }
3192
3193    private void readPermissionsLPw(ArrayMap<String, BasePermission> out, XmlPullParser parser)
3194            throws IOException, XmlPullParserException {
3195        int outerDepth = parser.getDepth();
3196        int type;
3197        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3198                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3199            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3200                continue;
3201            }
3202
3203            final String tagName = parser.getName();
3204            if (tagName.equals(TAG_ITEM)) {
3205                final String name = parser.getAttributeValue(null, ATTR_NAME);
3206                final String sourcePackage = parser.getAttributeValue(null, "package");
3207                final String ptype = parser.getAttributeValue(null, "type");
3208                if (name != null && sourcePackage != null) {
3209                    final boolean dynamic = "dynamic".equals(ptype);
3210                    final BasePermission bp = new BasePermission(name.intern(), sourcePackage,
3211                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
3212                    bp.protectionLevel = readInt(parser, null, "protection",
3213                            PermissionInfo.PROTECTION_NORMAL);
3214                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
3215                    if (dynamic) {
3216                        PermissionInfo pi = new PermissionInfo();
3217                        pi.packageName = sourcePackage.intern();
3218                        pi.name = name.intern();
3219                        pi.icon = readInt(parser, null, "icon", 0);
3220                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
3221                        pi.protectionLevel = bp.protectionLevel;
3222                        bp.pendingInfo = pi;
3223                    }
3224                    out.put(bp.name, bp);
3225                } else {
3226                    PackageManagerService.reportSettingsProblem(Log.WARN,
3227                            "Error in package manager settings: permissions has" + " no name at "
3228                                    + parser.getPositionDescription());
3229                }
3230            } else {
3231                PackageManagerService.reportSettingsProblem(Log.WARN,
3232                        "Unknown element reading permissions: " + parser.getName() + " at "
3233                                + parser.getPositionDescription());
3234            }
3235            XmlUtils.skipCurrentTag(parser);
3236        }
3237    }
3238
3239    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
3240            IOException {
3241        String name = parser.getAttributeValue(null, ATTR_NAME);
3242        String realName = parser.getAttributeValue(null, "realName");
3243        String codePathStr = parser.getAttributeValue(null, "codePath");
3244        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3245
3246        String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
3247        String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3248
3249        String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
3250        String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
3251        String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
3252
3253        if (primaryCpuAbiStr == null && legacyCpuAbiStr != null) {
3254            primaryCpuAbiStr = legacyCpuAbiStr;
3255        }
3256
3257        if (resourcePathStr == null) {
3258            resourcePathStr = codePathStr;
3259        }
3260        String version = parser.getAttributeValue(null, "version");
3261        int versionCode = 0;
3262        if (version != null) {
3263            try {
3264                versionCode = Integer.parseInt(version);
3265            } catch (NumberFormatException e) {
3266            }
3267        }
3268
3269        int pkgFlags = 0;
3270        int pkgPrivateFlags = 0;
3271        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3272        final File codePathFile = new File(codePathStr);
3273        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
3274            pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3275        }
3276        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
3277                new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
3278                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags);
3279        String timeStampStr = parser.getAttributeValue(null, "ft");
3280        if (timeStampStr != null) {
3281            try {
3282                long timeStamp = Long.parseLong(timeStampStr, 16);
3283                ps.setTimeStamp(timeStamp);
3284            } catch (NumberFormatException e) {
3285            }
3286        } else {
3287            timeStampStr = parser.getAttributeValue(null, "ts");
3288            if (timeStampStr != null) {
3289                try {
3290                    long timeStamp = Long.parseLong(timeStampStr);
3291                    ps.setTimeStamp(timeStamp);
3292                } catch (NumberFormatException e) {
3293                }
3294            }
3295        }
3296        timeStampStr = parser.getAttributeValue(null, "it");
3297        if (timeStampStr != null) {
3298            try {
3299                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
3300            } catch (NumberFormatException e) {
3301            }
3302        }
3303        timeStampStr = parser.getAttributeValue(null, "ut");
3304        if (timeStampStr != null) {
3305            try {
3306                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
3307            } catch (NumberFormatException e) {
3308            }
3309        }
3310        String idStr = parser.getAttributeValue(null, "userId");
3311        ps.appId = idStr != null ? Integer.parseInt(idStr) : 0;
3312        if (ps.appId <= 0) {
3313            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3314            ps.appId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3315        }
3316
3317        int outerDepth = parser.getDepth();
3318        int type;
3319        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3320                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3321            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3322                continue;
3323            }
3324
3325            if (parser.getName().equals(TAG_PERMISSIONS)) {
3326                readInstallPermissionsLPr(parser, ps.getPermissionsState());
3327            } else {
3328                PackageManagerService.reportSettingsProblem(Log.WARN,
3329                        "Unknown element under <updated-package>: " + parser.getName());
3330                XmlUtils.skipCurrentTag(parser);
3331            }
3332        }
3333
3334        mDisabledSysPackages.put(name, ps);
3335    }
3336
3337    private static int PRE_M_APP_INFO_FLAG_HIDDEN = 1<<27;
3338    private static int PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE = 1<<28;
3339    private static int PRE_M_APP_INFO_FLAG_FORWARD_LOCK = 1<<29;
3340    private static int PRE_M_APP_INFO_FLAG_PRIVILEGED = 1<<30;
3341
3342    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
3343        String name = null;
3344        String realName = null;
3345        String idStr = null;
3346        String sharedIdStr = null;
3347        String codePathStr = null;
3348        String resourcePathStr = null;
3349        String legacyCpuAbiString = null;
3350        String legacyNativeLibraryPathStr = null;
3351        String primaryCpuAbiString = null;
3352        String secondaryCpuAbiString = null;
3353        String cpuAbiOverrideString = null;
3354        String systemStr = null;
3355        String installerPackageName = null;
3356        String volumeUuid = null;
3357        String uidError = null;
3358        int pkgFlags = 0;
3359        int pkgPrivateFlags = 0;
3360        long timeStamp = 0;
3361        long firstInstallTime = 0;
3362        long lastUpdateTime = 0;
3363        PackageSettingBase packageSetting = null;
3364        String version = null;
3365        int versionCode = 0;
3366        try {
3367            name = parser.getAttributeValue(null, ATTR_NAME);
3368            realName = parser.getAttributeValue(null, "realName");
3369            idStr = parser.getAttributeValue(null, "userId");
3370            uidError = parser.getAttributeValue(null, "uidError");
3371            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
3372            codePathStr = parser.getAttributeValue(null, "codePath");
3373            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
3374
3375            legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
3376
3377            legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
3378            primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
3379            secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
3380            cpuAbiOverrideString = parser.getAttributeValue(null, "cpuAbiOverride");
3381
3382            if (primaryCpuAbiString == null && legacyCpuAbiString != null) {
3383                primaryCpuAbiString = legacyCpuAbiString;
3384            }
3385
3386            version = parser.getAttributeValue(null, "version");
3387            if (version != null) {
3388                try {
3389                    versionCode = Integer.parseInt(version);
3390                } catch (NumberFormatException e) {
3391                }
3392            }
3393            installerPackageName = parser.getAttributeValue(null, "installer");
3394            volumeUuid = parser.getAttributeValue(null, "volumeUuid");
3395
3396            systemStr = parser.getAttributeValue(null, "publicFlags");
3397            if (systemStr != null) {
3398                try {
3399                    pkgFlags = Integer.parseInt(systemStr);
3400                } catch (NumberFormatException e) {
3401                }
3402                systemStr = parser.getAttributeValue(null, "privateFlags");
3403                if (systemStr != null) {
3404                    try {
3405                        pkgPrivateFlags = Integer.parseInt(systemStr);
3406                    } catch (NumberFormatException e) {
3407                    }
3408                }
3409            } else {
3410                // Pre-M -- both public and private flags were stored in one "flags" field.
3411                systemStr = parser.getAttributeValue(null, "flags");
3412                if (systemStr != null) {
3413                    try {
3414                        pkgFlags = Integer.parseInt(systemStr);
3415                    } catch (NumberFormatException e) {
3416                    }
3417                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_HIDDEN) != 0) {
3418                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
3419                    }
3420                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE) != 0) {
3421                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
3422                    }
3423                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_FORWARD_LOCK) != 0) {
3424                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
3425                    }
3426                    if ((pkgFlags & PRE_M_APP_INFO_FLAG_PRIVILEGED) != 0) {
3427                        pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
3428                    }
3429                    pkgFlags &= ~(PRE_M_APP_INFO_FLAG_HIDDEN
3430                            | PRE_M_APP_INFO_FLAG_CANT_SAVE_STATE
3431                            | PRE_M_APP_INFO_FLAG_FORWARD_LOCK
3432                            | PRE_M_APP_INFO_FLAG_PRIVILEGED);
3433                } else {
3434                    // For backward compatibility
3435                    systemStr = parser.getAttributeValue(null, "system");
3436                    if (systemStr != null) {
3437                        pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
3438                                : 0;
3439                    } else {
3440                        // Old settings that don't specify system... just treat
3441                        // them as system, good enough.
3442                        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3443                    }
3444                }
3445            }
3446            String timeStampStr = parser.getAttributeValue(null, "ft");
3447            if (timeStampStr != null) {
3448                try {
3449                    timeStamp = Long.parseLong(timeStampStr, 16);
3450                } catch (NumberFormatException e) {
3451                }
3452            } else {
3453                timeStampStr = parser.getAttributeValue(null, "ts");
3454                if (timeStampStr != null) {
3455                    try {
3456                        timeStamp = Long.parseLong(timeStampStr);
3457                    } catch (NumberFormatException e) {
3458                    }
3459                }
3460            }
3461            timeStampStr = parser.getAttributeValue(null, "it");
3462            if (timeStampStr != null) {
3463                try {
3464                    firstInstallTime = Long.parseLong(timeStampStr, 16);
3465                } catch (NumberFormatException e) {
3466                }
3467            }
3468            timeStampStr = parser.getAttributeValue(null, "ut");
3469            if (timeStampStr != null) {
3470                try {
3471                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
3472                } catch (NumberFormatException e) {
3473                }
3474            }
3475            if (PackageManagerService.DEBUG_SETTINGS)
3476                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
3477                        + " sharedUserId=" + sharedIdStr);
3478            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3479            if (resourcePathStr == null) {
3480                resourcePathStr = codePathStr;
3481            }
3482            if (realName != null) {
3483                realName = realName.intern();
3484            }
3485            if (name == null) {
3486                PackageManagerService.reportSettingsProblem(Log.WARN,
3487                        "Error in package manager settings: <package> has no name at "
3488                                + parser.getPositionDescription());
3489            } else if (codePathStr == null) {
3490                PackageManagerService.reportSettingsProblem(Log.WARN,
3491                        "Error in package manager settings: <package> has no codePath at "
3492                                + parser.getPositionDescription());
3493            } else if (userId > 0) {
3494                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
3495                        new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
3496                        secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
3497                        pkgPrivateFlags);
3498                if (PackageManagerService.DEBUG_SETTINGS)
3499                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
3500                            + userId + " pkg=" + packageSetting);
3501                if (packageSetting == null) {
3502                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
3503                            + userId + " while parsing settings at "
3504                            + parser.getPositionDescription());
3505                } else {
3506                    packageSetting.setTimeStamp(timeStamp);
3507                    packageSetting.firstInstallTime = firstInstallTime;
3508                    packageSetting.lastUpdateTime = lastUpdateTime;
3509                }
3510            } else if (sharedIdStr != null) {
3511                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
3512                if (userId > 0) {
3513                    packageSetting = new PendingPackage(name.intern(), realName, new File(
3514                            codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
3515                            primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
3516                            userId, versionCode, pkgFlags, pkgPrivateFlags);
3517                    packageSetting.setTimeStamp(timeStamp);
3518                    packageSetting.firstInstallTime = firstInstallTime;
3519                    packageSetting.lastUpdateTime = lastUpdateTime;
3520                    mPendingPackages.add((PendingPackage) packageSetting);
3521                    if (PackageManagerService.DEBUG_SETTINGS)
3522                        Log.i(PackageManagerService.TAG, "Reading package " + name
3523                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
3524                } else {
3525                    PackageManagerService.reportSettingsProblem(Log.WARN,
3526                            "Error in package manager settings: package " + name
3527                                    + " has bad sharedId " + sharedIdStr + " at "
3528                                    + parser.getPositionDescription());
3529                }
3530            } else {
3531                PackageManagerService.reportSettingsProblem(Log.WARN,
3532                        "Error in package manager settings: package " + name + " has bad userId "
3533                                + idStr + " at " + parser.getPositionDescription());
3534            }
3535        } catch (NumberFormatException e) {
3536            PackageManagerService.reportSettingsProblem(Log.WARN,
3537                    "Error in package manager settings: package " + name + " has bad userId "
3538                            + idStr + " at " + parser.getPositionDescription());
3539        }
3540        if (packageSetting != null) {
3541            packageSetting.uidError = "true".equals(uidError);
3542            packageSetting.installerPackageName = installerPackageName;
3543            packageSetting.volumeUuid = volumeUuid;
3544            packageSetting.legacyNativeLibraryPathString = legacyNativeLibraryPathStr;
3545            packageSetting.primaryCpuAbiString = primaryCpuAbiString;
3546            packageSetting.secondaryCpuAbiString = secondaryCpuAbiString;
3547            // Handle legacy string here for single-user mode
3548            final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
3549            if (enabledStr != null) {
3550                try {
3551                    packageSetting.setEnabled(Integer.parseInt(enabledStr), 0 /* userId */, null);
3552                } catch (NumberFormatException e) {
3553                    if (enabledStr.equalsIgnoreCase("true")) {
3554                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_ENABLED, 0, null);
3555                    } else if (enabledStr.equalsIgnoreCase("false")) {
3556                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DISABLED, 0, null);
3557                    } else if (enabledStr.equalsIgnoreCase("default")) {
3558                        packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3559                    } else {
3560                        PackageManagerService.reportSettingsProblem(Log.WARN,
3561                                "Error in package manager settings: package " + name
3562                                        + " has bad enabled value: " + idStr + " at "
3563                                        + parser.getPositionDescription());
3564                    }
3565                }
3566            } else {
3567                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
3568            }
3569
3570            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
3571            if (installStatusStr != null) {
3572                if (installStatusStr.equalsIgnoreCase("false")) {
3573                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
3574                } else {
3575                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
3576                }
3577            }
3578            int outerDepth = parser.getDepth();
3579            int type;
3580            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3581                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3582                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3583                    continue;
3584                }
3585
3586                String tagName = parser.getName();
3587                // Legacy
3588                if (tagName.equals(TAG_DISABLED_COMPONENTS)) {
3589                    readDisabledComponentsLPw(packageSetting, parser, 0);
3590                } else if (tagName.equals(TAG_ENABLED_COMPONENTS)) {
3591                    readEnabledComponentsLPw(packageSetting, parser, 0);
3592                } else if (tagName.equals("sigs")) {
3593                    packageSetting.signatures.readXml(parser, mPastSignatures);
3594                } else if (tagName.equals(TAG_PERMISSIONS)) {
3595                    readInstallPermissionsLPr(parser,
3596                            packageSetting.getPermissionsState());
3597                    packageSetting.installPermissionsFixed = true;
3598                } else if (tagName.equals("proper-signing-keyset")) {
3599                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3600                    Integer refCt = mKeySetRefs.get(id);
3601                    if (refCt != null) {
3602                        mKeySetRefs.put(id, refCt + 1);
3603                    } else {
3604                        mKeySetRefs.put(id, 1);
3605                    }
3606                    packageSetting.keySetData.setProperSigningKeySet(id);
3607                } else if (tagName.equals("signing-keyset")) {
3608                    // from v1 of keysetmanagerservice - no longer used
3609                } else if (tagName.equals("upgrade-keyset")) {
3610                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3611                    packageSetting.keySetData.addUpgradeKeySetById(id);
3612                } else if (tagName.equals("defined-keyset")) {
3613                    long id = Long.parseLong(parser.getAttributeValue(null, "identifier"));
3614                    String alias = parser.getAttributeValue(null, "alias");
3615                    Integer refCt = mKeySetRefs.get(id);
3616                    if (refCt != null) {
3617                        mKeySetRefs.put(id, refCt + 1);
3618                    } else {
3619                        mKeySetRefs.put(id, 1);
3620                    }
3621                    packageSetting.keySetData.addDefinedKeySet(id, alias);
3622                } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
3623                    readDomainVerificationLPw(parser, packageSetting);
3624                } else {
3625                    PackageManagerService.reportSettingsProblem(Log.WARN,
3626                            "Unknown element under <package>: " + parser.getName());
3627                    XmlUtils.skipCurrentTag(parser);
3628                }
3629            }
3630        } else {
3631            XmlUtils.skipCurrentTag(parser);
3632        }
3633    }
3634
3635    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3636            int userId) throws IOException, XmlPullParserException {
3637        int outerDepth = parser.getDepth();
3638        int type;
3639        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3640                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3641            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3642                continue;
3643            }
3644
3645            String tagName = parser.getName();
3646            if (tagName.equals(TAG_ITEM)) {
3647                String name = parser.getAttributeValue(null, ATTR_NAME);
3648                if (name != null) {
3649                    packageSetting.addDisabledComponent(name.intern(), userId);
3650                } else {
3651                    PackageManagerService.reportSettingsProblem(Log.WARN,
3652                            "Error in package manager settings: <disabled-components> has"
3653                                    + " no name at " + parser.getPositionDescription());
3654                }
3655            } else {
3656                PackageManagerService.reportSettingsProblem(Log.WARN,
3657                        "Unknown element under <disabled-components>: " + parser.getName());
3658            }
3659            XmlUtils.skipCurrentTag(parser);
3660        }
3661    }
3662
3663    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser,
3664            int userId) throws IOException, XmlPullParserException {
3665        int outerDepth = parser.getDepth();
3666        int type;
3667        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3668                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3669            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3670                continue;
3671            }
3672
3673            String tagName = parser.getName();
3674            if (tagName.equals(TAG_ITEM)) {
3675                String name = parser.getAttributeValue(null, ATTR_NAME);
3676                if (name != null) {
3677                    packageSetting.addEnabledComponent(name.intern(), userId);
3678                } else {
3679                    PackageManagerService.reportSettingsProblem(Log.WARN,
3680                            "Error in package manager settings: <enabled-components> has"
3681                                    + " no name at " + parser.getPositionDescription());
3682                }
3683            } else {
3684                PackageManagerService.reportSettingsProblem(Log.WARN,
3685                        "Unknown element under <enabled-components>: " + parser.getName());
3686            }
3687            XmlUtils.skipCurrentTag(parser);
3688        }
3689    }
3690
3691    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException,IOException {
3692        String name = null;
3693        String idStr = null;
3694        int pkgFlags = 0;
3695        int pkgPrivateFlags = 0;
3696        SharedUserSetting su = null;
3697        try {
3698            name = parser.getAttributeValue(null, ATTR_NAME);
3699            idStr = parser.getAttributeValue(null, "userId");
3700            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
3701            if ("true".equals(parser.getAttributeValue(null, "system"))) {
3702                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
3703            }
3704            if (name == null) {
3705                PackageManagerService.reportSettingsProblem(Log.WARN,
3706                        "Error in package manager settings: <shared-user> has no name at "
3707                                + parser.getPositionDescription());
3708            } else if (userId == 0) {
3709                PackageManagerService.reportSettingsProblem(Log.WARN,
3710                        "Error in package manager settings: shared-user " + name
3711                                + " has bad userId " + idStr + " at "
3712                                + parser.getPositionDescription());
3713            } else {
3714                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags, pkgPrivateFlags))
3715                        == null) {
3716                    PackageManagerService
3717                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
3718                                    + parser.getPositionDescription());
3719                }
3720            }
3721        } catch (NumberFormatException e) {
3722            PackageManagerService.reportSettingsProblem(Log.WARN,
3723                    "Error in package manager settings: package " + name + " has bad userId "
3724                            + idStr + " at " + parser.getPositionDescription());
3725        }
3726
3727        if (su != null) {
3728            int outerDepth = parser.getDepth();
3729            int type;
3730            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
3731                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
3732                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
3733                    continue;
3734                }
3735
3736                String tagName = parser.getName();
3737                if (tagName.equals("sigs")) {
3738                    su.signatures.readXml(parser, mPastSignatures);
3739                } else if (tagName.equals("perms")) {
3740                    readInstallPermissionsLPr(parser, su.getPermissionsState());
3741                } else {
3742                    PackageManagerService.reportSettingsProblem(Log.WARN,
3743                            "Unknown element under <shared-user>: " + parser.getName());
3744                    XmlUtils.skipCurrentTag(parser);
3745                }
3746            }
3747        } else {
3748            XmlUtils.skipCurrentTag(parser);
3749        }
3750    }
3751
3752    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
3753            int userHandle) {
3754        String[] volumeUuids;
3755        String[] names;
3756        int[] appIds;
3757        String[] seinfos;
3758        int[] targetSdkVersions;
3759        int packagesCount;
3760        synchronized (mPackages) {
3761            Collection<PackageSetting> packages = mPackages.values();
3762            packagesCount = packages.size();
3763            volumeUuids = new String[packagesCount];
3764            names = new String[packagesCount];
3765            appIds = new int[packagesCount];
3766            seinfos = new String[packagesCount];
3767            targetSdkVersions = new int[packagesCount];
3768            Iterator<PackageSetting> packagesIterator = packages.iterator();
3769            for (int i = 0; i < packagesCount; i++) {
3770                PackageSetting ps = packagesIterator.next();
3771                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
3772                    continue;
3773                }
3774                // Only system apps are initially installed.
3775                ps.setInstalled(ps.isSystem(), userHandle);
3776                // Need to create a data directory for all apps under this user. Accumulate all
3777                // required args and call the installer after mPackages lock has been released
3778                volumeUuids[i] = ps.volumeUuid;
3779                names[i] = ps.name;
3780                appIds[i] = ps.appId;
3781                seinfos[i] = ps.pkg.applicationInfo.seinfo;
3782                targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
3783            }
3784        }
3785        for (int i = 0; i < packagesCount; i++) {
3786            if (names[i] == null) {
3787                continue;
3788            }
3789            // TODO: triage flags!
3790            final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
3791            try {
3792                installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i],
3793                        seinfos[i], targetSdkVersions[i]);
3794            } catch (InstallerException e) {
3795                Slog.w(TAG, "Failed to prepare app data", e);
3796            }
3797        }
3798        synchronized (mPackages) {
3799            applyDefaultPreferredAppsLPw(service, userHandle);
3800            writePackageRestrictionsLPr(userHandle);
3801            writePackageListLPr(userHandle);
3802        }
3803    }
3804
3805    void removeUserLPw(int userId) {
3806        Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
3807        for (Entry<String, PackageSetting> entry : entries) {
3808            entry.getValue().removeUser(userId);
3809        }
3810        mPreferredActivities.remove(userId);
3811        File file = getUserPackagesStateFile(userId);
3812        file.delete();
3813        file = getUserPackagesStateBackupFile(userId);
3814        file.delete();
3815        removeCrossProfileIntentFiltersLPw(userId);
3816
3817        mRuntimePermissionsPersistence.onUserRemoved(userId);
3818
3819        writePackageListLPr();
3820    }
3821
3822    void removeCrossProfileIntentFiltersLPw(int userId) {
3823        synchronized (mCrossProfileIntentResolvers) {
3824            // userId is the source user
3825            if (mCrossProfileIntentResolvers.get(userId) != null) {
3826                mCrossProfileIntentResolvers.remove(userId);
3827                writePackageRestrictionsLPr(userId);
3828            }
3829            // userId is the target user
3830            int count = mCrossProfileIntentResolvers.size();
3831            for (int i = 0; i < count; i++) {
3832                int sourceUserId = mCrossProfileIntentResolvers.keyAt(i);
3833                CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId);
3834                boolean needsWriting = false;
3835                ArraySet<CrossProfileIntentFilter> cpifs =
3836                        new ArraySet<CrossProfileIntentFilter>(cpir.filterSet());
3837                for (CrossProfileIntentFilter cpif : cpifs) {
3838                    if (cpif.getTargetUserId() == userId) {
3839                        needsWriting = true;
3840                        cpir.removeFilter(cpif);
3841                    }
3842                }
3843                if (needsWriting) {
3844                    writePackageRestrictionsLPr(sourceUserId);
3845                }
3846            }
3847        }
3848    }
3849
3850    // This should be called (at least) whenever an application is removed
3851    private void setFirstAvailableUid(int uid) {
3852        if (uid > mFirstAvailableUid) {
3853            mFirstAvailableUid = uid;
3854        }
3855    }
3856
3857    // Returns -1 if we could not find an available UserId to assign
3858    private int newUserIdLPw(Object obj) {
3859        // Let's be stupidly inefficient for now...
3860        final int N = mUserIds.size();
3861        for (int i = mFirstAvailableUid; i < N; i++) {
3862            if (mUserIds.get(i) == null) {
3863                mUserIds.set(i, obj);
3864                return Process.FIRST_APPLICATION_UID + i;
3865            }
3866        }
3867
3868        // None left?
3869        if (N > (Process.LAST_APPLICATION_UID-Process.FIRST_APPLICATION_UID)) {
3870            return -1;
3871        }
3872
3873        mUserIds.add(obj);
3874        return Process.FIRST_APPLICATION_UID + N;
3875    }
3876
3877    public VerifierDeviceIdentity getVerifierDeviceIdentityLPw() {
3878        if (mVerifierDeviceIdentity == null) {
3879            mVerifierDeviceIdentity = VerifierDeviceIdentity.generate();
3880
3881            writeLPr();
3882        }
3883
3884        return mVerifierDeviceIdentity;
3885    }
3886
3887    public PackageSetting getDisabledSystemPkgLPr(String name) {
3888        PackageSetting ps = mDisabledSysPackages.get(name);
3889        return ps;
3890    }
3891
3892    private String compToString(ArraySet<String> cmp) {
3893        return cmp != null ? Arrays.toString(cmp.toArray()) : "[]";
3894    }
3895
3896    boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
3897        final PackageSetting ps = mPackages.get(componentInfo.packageName);
3898        if (ps == null) return false;
3899
3900        final PackageUserState userState = ps.readUserState(userId);
3901        return userState.isMatch(componentInfo, flags);
3902    }
3903
3904    String getInstallerPackageNameLPr(String packageName) {
3905        final PackageSetting pkg = mPackages.get(packageName);
3906        if (pkg == null) {
3907            throw new IllegalArgumentException("Unknown package: " + packageName);
3908        }
3909        return pkg.installerPackageName;
3910    }
3911
3912    int getApplicationEnabledSettingLPr(String packageName, int userId) {
3913        final PackageSetting pkg = mPackages.get(packageName);
3914        if (pkg == null) {
3915            throw new IllegalArgumentException("Unknown package: " + packageName);
3916        }
3917        return pkg.getEnabled(userId);
3918    }
3919
3920    int getComponentEnabledSettingLPr(ComponentName componentName, int userId) {
3921        final String packageName = componentName.getPackageName();
3922        final PackageSetting pkg = mPackages.get(packageName);
3923        if (pkg == null) {
3924            throw new IllegalArgumentException("Unknown component: " + componentName);
3925        }
3926        final String classNameStr = componentName.getClassName();
3927        return pkg.getCurrentEnabledStateLPr(classNameStr, userId);
3928    }
3929
3930    boolean setPackageStoppedStateLPw(PackageManagerService yucky, String packageName,
3931            boolean stopped, boolean allowedByPermission, int uid, int userId) {
3932        int appId = UserHandle.getAppId(uid);
3933        final PackageSetting pkgSetting = mPackages.get(packageName);
3934        if (pkgSetting == null) {
3935            throw new IllegalArgumentException("Unknown package: " + packageName);
3936        }
3937        if (!allowedByPermission && (appId != pkgSetting.appId)) {
3938            throw new SecurityException(
3939                    "Permission Denial: attempt to change stopped state from pid="
3940                    + Binder.getCallingPid()
3941                    + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
3942        }
3943        if (DEBUG_STOPPED) {
3944            if (stopped) {
3945                RuntimeException e = new RuntimeException("here");
3946                e.fillInStackTrace();
3947                Slog.i(TAG, "Stopping package " + packageName, e);
3948            }
3949        }
3950        if (pkgSetting.getStopped(userId) != stopped) {
3951            pkgSetting.setStopped(stopped, userId);
3952            // pkgSetting.pkg.mSetStopped = stopped;
3953            if (pkgSetting.getNotLaunched(userId)) {
3954                if (pkgSetting.installerPackageName != null) {
3955                    yucky.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
3956                            pkgSetting.name, null, 0,
3957                            pkgSetting.installerPackageName, null, new int[] {userId});
3958                }
3959                pkgSetting.setNotLaunched(false, userId);
3960            }
3961            return true;
3962        }
3963        return false;
3964    }
3965
3966    List<UserInfo> getAllUsers() {
3967        long id = Binder.clearCallingIdentity();
3968        try {
3969            return UserManagerService.getInstance().getUsers(false);
3970        } catch (NullPointerException npe) {
3971            // packagemanager not yet initialized
3972        } finally {
3973            Binder.restoreCallingIdentity(id);
3974        }
3975        return null;
3976    }
3977
3978    /**
3979     * Return all {@link PackageSetting} that are actively installed on the
3980     * given {@link VolumeInfo#fsUuid}.
3981     */
3982    List<PackageSetting> getVolumePackagesLPr(String volumeUuid) {
3983        ArrayList<PackageSetting> res = new ArrayList<>();
3984        for (int i = 0; i < mPackages.size(); i++) {
3985            final PackageSetting setting = mPackages.valueAt(i);
3986            if (Objects.equals(volumeUuid, setting.volumeUuid)) {
3987                res.add(setting);
3988            }
3989        }
3990        return res;
3991    }
3992
3993    static void printFlags(PrintWriter pw, int val, Object[] spec) {
3994        pw.print("[ ");
3995        for (int i=0; i<spec.length; i+=2) {
3996            int mask = (Integer)spec[i];
3997            if ((val & mask) != 0) {
3998                pw.print(spec[i+1]);
3999                pw.print(" ");
4000            }
4001        }
4002        pw.print("]");
4003    }
4004
4005    static final Object[] FLAG_DUMP_SPEC = new Object[] {
4006        ApplicationInfo.FLAG_SYSTEM, "SYSTEM",
4007        ApplicationInfo.FLAG_DEBUGGABLE, "DEBUGGABLE",
4008        ApplicationInfo.FLAG_HAS_CODE, "HAS_CODE",
4009        ApplicationInfo.FLAG_PERSISTENT, "PERSISTENT",
4010        ApplicationInfo.FLAG_FACTORY_TEST, "FACTORY_TEST",
4011        ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING, "ALLOW_TASK_REPARENTING",
4012        ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA, "ALLOW_CLEAR_USER_DATA",
4013        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, "UPDATED_SYSTEM_APP",
4014        ApplicationInfo.FLAG_TEST_ONLY, "TEST_ONLY",
4015        ApplicationInfo.FLAG_VM_SAFE_MODE, "VM_SAFE_MODE",
4016        ApplicationInfo.FLAG_ALLOW_BACKUP, "ALLOW_BACKUP",
4017        ApplicationInfo.FLAG_KILL_AFTER_RESTORE, "KILL_AFTER_RESTORE",
4018        ApplicationInfo.FLAG_RESTORE_ANY_VERSION, "RESTORE_ANY_VERSION",
4019        ApplicationInfo.FLAG_EXTERNAL_STORAGE, "EXTERNAL_STORAGE",
4020        ApplicationInfo.FLAG_LARGE_HEAP, "LARGE_HEAP",
4021    };
4022
4023    static final Object[] PRIVATE_FLAG_DUMP_SPEC = new Object[] {
4024        ApplicationInfo.PRIVATE_FLAG_PRIVILEGED, "PRIVILEGED",
4025        ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK, "FORWARD_LOCK",
4026        ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE, "CANT_SAVE_STATE",
4027    };
4028
4029    void dumpVersionLPr(IndentingPrintWriter pw) {
4030        pw.increaseIndent();
4031        for (int i= 0; i < mVersion.size(); i++) {
4032            final String volumeUuid = mVersion.keyAt(i);
4033            final VersionInfo ver = mVersion.valueAt(i);
4034            if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
4035                pw.println("Internal:");
4036            } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
4037                pw.println("External:");
4038            } else {
4039                pw.println("UUID " + volumeUuid + ":");
4040            }
4041            pw.increaseIndent();
4042            pw.printPair("sdkVersion", ver.sdkVersion);
4043            pw.printPair("databaseVersion", ver.databaseVersion);
4044            pw.println();
4045            pw.printPair("fingerprint", ver.fingerprint);
4046            pw.println();
4047            pw.decreaseIndent();
4048        }
4049        pw.decreaseIndent();
4050    }
4051
4052    void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
4053            ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
4054            Date date, List<UserInfo> users, boolean dumpAll) {
4055        if (checkinTag != null) {
4056            pw.print(checkinTag);
4057            pw.print(",");
4058            pw.print(ps.realName != null ? ps.realName : ps.name);
4059            pw.print(",");
4060            pw.print(ps.appId);
4061            pw.print(",");
4062            pw.print(ps.versionCode);
4063            pw.print(",");
4064            pw.print(ps.firstInstallTime);
4065            pw.print(",");
4066            pw.print(ps.lastUpdateTime);
4067            pw.print(",");
4068            pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
4069            pw.println();
4070            if (ps.pkg != null) {
4071                pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4072                pw.print("base,");
4073                pw.println(ps.pkg.baseRevisionCode);
4074                if (ps.pkg.splitNames != null) {
4075                    for (int i = 0; i < ps.pkg.splitNames.length; i++) {
4076                        pw.print(checkinTag); pw.print("-"); pw.print("splt,");
4077                        pw.print(ps.pkg.splitNames[i]); pw.print(",");
4078                        pw.println(ps.pkg.splitRevisionCodes[i]);
4079                    }
4080                }
4081            }
4082            for (UserInfo user : users) {
4083                pw.print(checkinTag);
4084                pw.print("-");
4085                pw.print("usr");
4086                pw.print(",");
4087                pw.print(user.id);
4088                pw.print(",");
4089                pw.print(ps.getInstalled(user.id) ? "I" : "i");
4090                pw.print(ps.getHidden(user.id) ? "B" : "b");
4091                pw.print(ps.getSuspended(user.id) ? "SU" : "su");
4092                pw.print(ps.getStopped(user.id) ? "S" : "s");
4093                pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
4094                pw.print(",");
4095                pw.print(ps.getEnabled(user.id));
4096                String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4097                pw.print(",");
4098                pw.print(lastDisabledAppCaller != null ? lastDisabledAppCaller : "?");
4099                pw.println();
4100            }
4101            return;
4102        }
4103
4104        pw.print(prefix); pw.print("Package [");
4105            pw.print(ps.realName != null ? ps.realName : ps.name);
4106            pw.print("] (");
4107            pw.print(Integer.toHexString(System.identityHashCode(ps)));
4108            pw.println("):");
4109
4110        if (ps.frozen) {
4111            pw.print(prefix); pw.println("  FROZEN!");
4112        }
4113
4114        if (ps.realName != null) {
4115            pw.print(prefix); pw.print("  compat name=");
4116            pw.println(ps.name);
4117        }
4118
4119        pw.print(prefix); pw.print("  userId="); pw.println(ps.appId);
4120
4121        if (ps.sharedUser != null) {
4122            pw.print(prefix); pw.print("  sharedUser="); pw.println(ps.sharedUser);
4123        }
4124        pw.print(prefix); pw.print("  pkg="); pw.println(ps.pkg);
4125        pw.print(prefix); pw.print("  codePath="); pw.println(ps.codePathString);
4126        if (permissionNames == null) {
4127            pw.print(prefix); pw.print("  resourcePath="); pw.println(ps.resourcePathString);
4128            pw.print(prefix); pw.print("  legacyNativeLibraryDir=");
4129            pw.println(ps.legacyNativeLibraryPathString);
4130            pw.print(prefix); pw.print("  primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
4131            pw.print(prefix); pw.print("  secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
4132        }
4133        pw.print(prefix); pw.print("  versionCode="); pw.print(ps.versionCode);
4134        if (ps.pkg != null) {
4135            pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
4136        }
4137        pw.println();
4138        if (ps.pkg != null) {
4139            pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
4140            pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
4141            pw.print(prefix); pw.print("  applicationInfo=");
4142                pw.println(ps.pkg.applicationInfo.toString());
4143            pw.print(prefix); pw.print("  flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
4144                    FLAG_DUMP_SPEC); pw.println();
4145            if (ps.pkg.applicationInfo.privateFlags != 0) {
4146                pw.print(prefix); pw.print("  privateFlags="); printFlags(pw,
4147                        ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
4148            }
4149            pw.print(prefix); pw.print("  dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
4150            pw.print(prefix); pw.print("  supportsScreens=[");
4151            boolean first = true;
4152            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
4153                if (!first)
4154                    pw.print(", ");
4155                first = false;
4156                pw.print("small");
4157            }
4158            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
4159                if (!first)
4160                    pw.print(", ");
4161                first = false;
4162                pw.print("medium");
4163            }
4164            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
4165                if (!first)
4166                    pw.print(", ");
4167                first = false;
4168                pw.print("large");
4169            }
4170            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
4171                if (!first)
4172                    pw.print(", ");
4173                first = false;
4174                pw.print("xlarge");
4175            }
4176            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
4177                if (!first)
4178                    pw.print(", ");
4179                first = false;
4180                pw.print("resizeable");
4181            }
4182            if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
4183                if (!first)
4184                    pw.print(", ");
4185                first = false;
4186                pw.print("anyDensity");
4187            }
4188            pw.println("]");
4189            if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
4190                pw.print(prefix); pw.println("  libraries:");
4191                for (int i=0; i<ps.pkg.libraryNames.size(); i++) {
4192                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.libraryNames.get(i));
4193                }
4194            }
4195            if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
4196                pw.print(prefix); pw.println("  usesLibraries:");
4197                for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
4198                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraries.get(i));
4199                }
4200            }
4201            if (ps.pkg.usesOptionalLibraries != null
4202                    && ps.pkg.usesOptionalLibraries.size() > 0) {
4203                pw.print(prefix); pw.println("  usesOptionalLibraries:");
4204                for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
4205                    pw.print(prefix); pw.print("    ");
4206                        pw.println(ps.pkg.usesOptionalLibraries.get(i));
4207                }
4208            }
4209            if (ps.pkg.usesLibraryFiles != null
4210                    && ps.pkg.usesLibraryFiles.length > 0) {
4211                pw.print(prefix); pw.println("  usesLibraryFiles:");
4212                for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
4213                    pw.print(prefix); pw.print("    "); pw.println(ps.pkg.usesLibraryFiles[i]);
4214                }
4215            }
4216        }
4217        pw.print(prefix); pw.print("  timeStamp=");
4218            date.setTime(ps.timeStamp);
4219            pw.println(sdf.format(date));
4220        pw.print(prefix); pw.print("  firstInstallTime=");
4221            date.setTime(ps.firstInstallTime);
4222            pw.println(sdf.format(date));
4223        pw.print(prefix); pw.print("  lastUpdateTime=");
4224            date.setTime(ps.lastUpdateTime);
4225            pw.println(sdf.format(date));
4226        if (ps.installerPackageName != null) {
4227            pw.print(prefix); pw.print("  installerPackageName=");
4228                    pw.println(ps.installerPackageName);
4229        }
4230        if (ps.volumeUuid != null) {
4231            pw.print(prefix); pw.print("  volumeUuid=");
4232                    pw.println(ps.volumeUuid);
4233        }
4234        pw.print(prefix); pw.print("  signatures="); pw.println(ps.signatures);
4235        pw.print(prefix); pw.print("  installPermissionsFixed=");
4236                pw.print(ps.installPermissionsFixed);
4237                pw.print(" installStatus="); pw.println(ps.installStatus);
4238        pw.print(prefix); pw.print("  pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
4239                pw.println();
4240
4241        if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
4242            final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
4243            pw.print(prefix); pw.println("  declared permissions:");
4244            for (int i=0; i<perms.size(); i++) {
4245                PackageParser.Permission perm = perms.get(i);
4246                if (permissionNames != null
4247                        && !permissionNames.contains(perm.info.name)) {
4248                    continue;
4249                }
4250                pw.print(prefix); pw.print("    "); pw.print(perm.info.name);
4251                pw.print(": prot=");
4252                pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
4253                if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
4254                    pw.print(", COSTS_MONEY");
4255                }
4256                if ((perm.info.flags&PermissionInfo.FLAG_HIDDEN) != 0) {
4257                    pw.print(", HIDDEN");
4258                }
4259                if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
4260                    pw.print(", INSTALLED");
4261                }
4262                pw.println();
4263            }
4264        }
4265
4266        if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null
4267                && ps.pkg.requestedPermissions.size() > 0) {
4268            final ArrayList<String> perms = ps.pkg.requestedPermissions;
4269            pw.print(prefix); pw.println("  requested permissions:");
4270            for (int i=0; i<perms.size(); i++) {
4271                String perm = perms.get(i);
4272                if (permissionNames != null
4273                        && !permissionNames.contains(perm)) {
4274                    continue;
4275                }
4276                pw.print(prefix); pw.print("    "); pw.println(perm);
4277            }
4278        }
4279
4280        if (ps.sharedUser == null || permissionNames != null || dumpAll) {
4281            PermissionsState permissionsState = ps.getPermissionsState();
4282            dumpInstallPermissionsLPr(pw, prefix + "  ", permissionNames, permissionsState);
4283        }
4284
4285        for (UserInfo user : users) {
4286            pw.print(prefix); pw.print("  User "); pw.print(user.id); pw.print(": ");
4287            pw.print(" installed=");
4288            pw.print(ps.getInstalled(user.id));
4289            pw.print(" hidden=");
4290            pw.print(ps.getHidden(user.id));
4291            pw.print(" suspended=");
4292            pw.print(ps.getSuspended(user.id));
4293            pw.print(" stopped=");
4294            pw.print(ps.getStopped(user.id));
4295            pw.print(" notLaunched=");
4296            pw.print(ps.getNotLaunched(user.id));
4297            pw.print(" enabled=");
4298            pw.println(ps.getEnabled(user.id));
4299            String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
4300            if (lastDisabledAppCaller != null) {
4301                pw.print(prefix); pw.print("    lastDisabledCaller: ");
4302                        pw.println(lastDisabledAppCaller);
4303            }
4304
4305            if (ps.sharedUser == null) {
4306                PermissionsState permissionsState = ps.getPermissionsState();
4307                dumpGidsLPr(pw, prefix + "    ", permissionsState.computeGids(user.id));
4308                dumpRuntimePermissionsLPr(pw, prefix + "    ", permissionNames, permissionsState
4309                        .getRuntimePermissionStates(user.id), dumpAll);
4310            }
4311
4312            if (permissionNames == null) {
4313                ArraySet<String> cmp = ps.getDisabledComponents(user.id);
4314                if (cmp != null && cmp.size() > 0) {
4315                    pw.print(prefix); pw.println("    disabledComponents:");
4316                    for (String s : cmp) {
4317                        pw.print(prefix); pw.print("      "); pw.println(s);
4318                    }
4319                }
4320                cmp = ps.getEnabledComponents(user.id);
4321                if (cmp != null && cmp.size() > 0) {
4322                    pw.print(prefix); pw.println("    enabledComponents:");
4323                    for (String s : cmp) {
4324                        pw.print(prefix); pw.print("      "); pw.println(s);
4325                    }
4326                }
4327            }
4328        }
4329    }
4330
4331    void dumpPackagesLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4332            DumpState dumpState, boolean checkin) {
4333        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
4334        final Date date = new Date();
4335        boolean printedSomething = false;
4336        List<UserInfo> users = getAllUsers();
4337        for (final PackageSetting ps : mPackages.values()) {
4338            if (packageName != null && !packageName.equals(ps.realName)
4339                    && !packageName.equals(ps.name)) {
4340                continue;
4341            }
4342            if (permissionNames != null
4343                    && !ps.getPermissionsState().hasRequestedPermission(permissionNames)) {
4344                continue;
4345            }
4346
4347            if (!checkin && packageName != null) {
4348                dumpState.setSharedUser(ps.sharedUser);
4349            }
4350
4351            if (!checkin && !printedSomething) {
4352                if (dumpState.onTitlePrinted())
4353                    pw.println();
4354                pw.println("Packages:");
4355                printedSomething = true;
4356            }
4357            dumpPackageLPr(pw, "  ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
4358                    packageName != null);
4359        }
4360
4361        printedSomething = false;
4362        if (mRenamedPackages.size() > 0 && permissionNames == null) {
4363            for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
4364                if (packageName != null && !packageName.equals(e.getKey())
4365                        && !packageName.equals(e.getValue())) {
4366                    continue;
4367                }
4368                if (!checkin) {
4369                    if (!printedSomething) {
4370                        if (dumpState.onTitlePrinted())
4371                            pw.println();
4372                        pw.println("Renamed packages:");
4373                        printedSomething = true;
4374                    }
4375                    pw.print("  ");
4376                } else {
4377                    pw.print("ren,");
4378                }
4379                pw.print(e.getKey());
4380                pw.print(checkin ? " -> " : ",");
4381                pw.println(e.getValue());
4382            }
4383        }
4384
4385        printedSomething = false;
4386        if (mDisabledSysPackages.size() > 0 && permissionNames == null) {
4387            for (final PackageSetting ps : mDisabledSysPackages.values()) {
4388                if (packageName != null && !packageName.equals(ps.realName)
4389                        && !packageName.equals(ps.name)) {
4390                    continue;
4391                }
4392                if (!checkin && !printedSomething) {
4393                    if (dumpState.onTitlePrinted())
4394                        pw.println();
4395                    pw.println("Hidden system packages:");
4396                    printedSomething = true;
4397                }
4398                dumpPackageLPr(pw, "  ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
4399                        users, packageName != null);
4400            }
4401        }
4402    }
4403
4404    void dumpPermissionsLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4405            DumpState dumpState) {
4406        boolean printedSomething = false;
4407        for (BasePermission p : mPermissions.values()) {
4408            if (packageName != null && !packageName.equals(p.sourcePackage)) {
4409                continue;
4410            }
4411            if (permissionNames != null && !permissionNames.contains(p.name)) {
4412                continue;
4413            }
4414            if (!printedSomething) {
4415                if (dumpState.onTitlePrinted())
4416                    pw.println();
4417                pw.println("Permissions:");
4418                printedSomething = true;
4419            }
4420            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
4421                    pw.print(Integer.toHexString(System.identityHashCode(p)));
4422                    pw.println("):");
4423            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
4424            pw.print("    uid="); pw.print(p.uid);
4425                    pw.print(" gids="); pw.print(Arrays.toString(
4426                            p.computeGids(UserHandle.USER_SYSTEM)));
4427                    pw.print(" type="); pw.print(p.type);
4428                    pw.print(" prot=");
4429                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
4430            if (p.perm != null) {
4431                pw.print("    perm="); pw.println(p.perm);
4432                if ((p.perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
4433                        || (p.perm.info.flags & PermissionInfo.FLAG_HIDDEN) != 0) {
4434                    pw.print("    flags=0x"); pw.println(Integer.toHexString(p.perm.info.flags));
4435                }
4436            }
4437            if (p.packageSetting != null) {
4438                pw.print("    packageSetting="); pw.println(p.packageSetting);
4439            }
4440            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
4441                pw.print("    enforced=");
4442                pw.println(mReadExternalStorageEnforced);
4443            }
4444        }
4445    }
4446
4447    void dumpSharedUsersLPr(PrintWriter pw, String packageName, ArraySet<String> permissionNames,
4448            DumpState dumpState, boolean checkin) {
4449        boolean printedSomething = false;
4450        for (SharedUserSetting su : mSharedUsers.values()) {
4451            if (packageName != null && su != dumpState.getSharedUser()) {
4452                continue;
4453            }
4454            if (permissionNames != null
4455                    && !su.getPermissionsState().hasRequestedPermission(permissionNames)) {
4456                continue;
4457            }
4458            if (!checkin) {
4459                if (!printedSomething) {
4460                    if (dumpState.onTitlePrinted())
4461                        pw.println();
4462                    pw.println("Shared users:");
4463                    printedSomething = true;
4464                }
4465                pw.print("  SharedUser [");
4466                pw.print(su.name);
4467                pw.print("] (");
4468                pw.print(Integer.toHexString(System.identityHashCode(su)));
4469                        pw.println("):");
4470
4471                String prefix = "    ";
4472                pw.print(prefix); pw.print("userId="); pw.println(su.userId);
4473
4474                PermissionsState permissionsState = su.getPermissionsState();
4475                dumpInstallPermissionsLPr(pw, prefix, permissionNames, permissionsState);
4476
4477                for (int userId : UserManagerService.getInstance().getUserIds()) {
4478                    final int[] gids = permissionsState.computeGids(userId);
4479                    List<PermissionState> permissions = permissionsState
4480                            .getRuntimePermissionStates(userId);
4481                    if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
4482                        pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
4483                        dumpGidsLPr(pw, prefix + "  ", gids);
4484                        dumpRuntimePermissionsLPr(pw, prefix + "  ", permissionNames, permissions,
4485                                packageName != null);
4486                    }
4487                }
4488            } else {
4489                pw.print("suid,"); pw.print(su.userId); pw.print(","); pw.println(su.name);
4490            }
4491        }
4492    }
4493
4494    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
4495        pw.println("Settings parse messages:");
4496        pw.print(mReadMessages.toString());
4497    }
4498
4499    void dumpRestoredPermissionGrantsLPr(PrintWriter pw, DumpState dumpState) {
4500        if (mRestoredUserGrants.size() > 0) {
4501            pw.println();
4502            pw.println("Restored (pending) permission grants:");
4503            for (int userIndex = 0; userIndex < mRestoredUserGrants.size(); userIndex++) {
4504                ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4505                        mRestoredUserGrants.valueAt(userIndex);
4506                if (grantsByPackage != null && grantsByPackage.size() > 0) {
4507                    final int userId = mRestoredUserGrants.keyAt(userIndex);
4508                    pw.print("  User "); pw.println(userId);
4509
4510                    for (int pkgIndex = 0; pkgIndex < grantsByPackage.size(); pkgIndex++) {
4511                        ArraySet<RestoredPermissionGrant> grants = grantsByPackage.valueAt(pkgIndex);
4512                        if (grants != null && grants.size() > 0) {
4513                            final String pkgName = grantsByPackage.keyAt(pkgIndex);
4514                            pw.print("    "); pw.print(pkgName); pw.println(" :");
4515
4516                            for (RestoredPermissionGrant g : grants) {
4517                                pw.print("      ");
4518                                pw.print(g.permissionName);
4519                                if (g.granted) {
4520                                    pw.print(" GRANTED");
4521                                }
4522                                if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4523                                    pw.print(" user_set");
4524                                }
4525                                if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4526                                    pw.print(" user_fixed");
4527                                }
4528                                if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4529                                    pw.print(" revoke_on_upgrade");
4530                                }
4531                                pw.println();
4532                            }
4533                        }
4534                    }
4535                }
4536            }
4537            pw.println();
4538        }
4539    }
4540
4541    private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
4542        if (pkg == null) {
4543            pw.print("unknown");
4544        } else {
4545            // [base:10, config.mdpi, config.xhdpi:12]
4546            pw.print("[");
4547            pw.print("base");
4548            if (pkg.baseRevisionCode != 0) {
4549                pw.print(":"); pw.print(pkg.baseRevisionCode);
4550            }
4551            if (pkg.splitNames != null) {
4552                for (int i = 0; i < pkg.splitNames.length; i++) {
4553                    pw.print(", ");
4554                    pw.print(pkg.splitNames[i]);
4555                    if (pkg.splitRevisionCodes[i] != 0) {
4556                        pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
4557                    }
4558                }
4559            }
4560            pw.print("]");
4561        }
4562    }
4563
4564    void dumpGidsLPr(PrintWriter pw, String prefix, int[] gids) {
4565        if (!ArrayUtils.isEmpty(gids)) {
4566            pw.print(prefix);
4567            pw.print("gids="); pw.println(
4568                    PackageManagerService.arrayToString(gids));
4569        }
4570    }
4571
4572    void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4573            List<PermissionState> permissionStates, boolean dumpAll) {
4574        if (!permissionStates.isEmpty() || dumpAll) {
4575            pw.print(prefix); pw.println("runtime permissions:");
4576            for (PermissionState permissionState : permissionStates) {
4577                if (permissionNames != null
4578                        && !permissionNames.contains(permissionState.getName())) {
4579                    continue;
4580                }
4581                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4582                pw.print(": granted="); pw.print(permissionState.isGranted());
4583                    pw.println(permissionFlagsToString(", flags=",
4584                            permissionState.getFlags()));
4585            }
4586        }
4587    }
4588
4589    private static String permissionFlagsToString(String prefix, int flags) {
4590        StringBuilder flagsString = null;
4591        while (flags != 0) {
4592            if (flagsString == null) {
4593                flagsString = new StringBuilder();
4594                flagsString.append(prefix);
4595                flagsString.append("[ ");
4596            }
4597            final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4598            flags &= ~flag;
4599            flagsString.append(PackageManager.permissionFlagToString(flag));
4600            flagsString.append(' ');
4601        }
4602        if (flagsString != null) {
4603            flagsString.append(']');
4604            return flagsString.toString();
4605        } else {
4606            return "";
4607        }
4608    }
4609
4610    void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
4611            PermissionsState permissionsState) {
4612        List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
4613        if (!permissionStates.isEmpty()) {
4614            pw.print(prefix); pw.println("install permissions:");
4615            for (PermissionState permissionState : permissionStates) {
4616                if (permissionNames != null
4617                        && !permissionNames.contains(permissionState.getName())) {
4618                    continue;
4619                }
4620                pw.print(prefix); pw.print("  "); pw.print(permissionState.getName());
4621                    pw.print(": granted="); pw.print(permissionState.isGranted());
4622                    pw.println(permissionFlagsToString(", flags=",
4623                        permissionState.getFlags()));
4624            }
4625        }
4626    }
4627
4628    public void writeRuntimePermissionsForUserLPr(int userId, boolean sync) {
4629        if (sync) {
4630            mRuntimePermissionsPersistence.writePermissionsForUserSyncLPr(userId);
4631        } else {
4632            mRuntimePermissionsPersistence.writePermissionsForUserAsyncLPr(userId);
4633        }
4634    }
4635
4636    private final class RuntimePermissionPersistence {
4637        private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200;
4638        private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000;
4639
4640        private final Handler mHandler = new MyHandler();
4641
4642        private final Object mLock;
4643
4644        @GuardedBy("mLock")
4645        private final SparseBooleanArray mWriteScheduled = new SparseBooleanArray();
4646
4647        @GuardedBy("mLock")
4648        // The mapping keys are user ids.
4649        private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray();
4650
4651        @GuardedBy("mLock")
4652        // The mapping keys are user ids.
4653        private final SparseArray<String> mFingerprints = new SparseArray<>();
4654
4655        @GuardedBy("mLock")
4656        // The mapping keys are user ids.
4657        private final SparseBooleanArray mDefaultPermissionsGranted = new SparseBooleanArray();
4658
4659        public RuntimePermissionPersistence(Object lock) {
4660            mLock = lock;
4661        }
4662
4663        public boolean areDefaultRuntimPermissionsGrantedLPr(int userId) {
4664            return mDefaultPermissionsGranted.get(userId);
4665        }
4666
4667        public void onDefaultRuntimePermissionsGrantedLPr(int userId) {
4668            mFingerprints.put(userId, Build.FINGERPRINT);
4669            writePermissionsForUserAsyncLPr(userId);
4670        }
4671
4672        public void writePermissionsForUserSyncLPr(int userId) {
4673            mHandler.removeMessages(userId);
4674            writePermissionsSync(userId);
4675        }
4676
4677        public void writePermissionsForUserAsyncLPr(int userId) {
4678            final long currentTimeMillis = SystemClock.uptimeMillis();
4679
4680            if (mWriteScheduled.get(userId)) {
4681                mHandler.removeMessages(userId);
4682
4683                // If enough time passed, write without holding off anymore.
4684                final long lastNotWrittenMutationTimeMillis = mLastNotWrittenMutationTimesMillis
4685                        .get(userId);
4686                final long timeSinceLastNotWrittenMutationMillis = currentTimeMillis
4687                        - lastNotWrittenMutationTimeMillis;
4688                if (timeSinceLastNotWrittenMutationMillis >= MAX_WRITE_PERMISSIONS_DELAY_MILLIS) {
4689                    mHandler.obtainMessage(userId).sendToTarget();
4690                    return;
4691                }
4692
4693                // Hold off a bit more as settings are frequently changing.
4694                final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis
4695                        + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0);
4696                final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS,
4697                        maxDelayMillis);
4698
4699                Message message = mHandler.obtainMessage(userId);
4700                mHandler.sendMessageDelayed(message, writeDelayMillis);
4701            } else {
4702                mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis);
4703                Message message = mHandler.obtainMessage(userId);
4704                mHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS);
4705                mWriteScheduled.put(userId, true);
4706            }
4707        }
4708
4709        private void writePermissionsSync(int userId) {
4710            AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId));
4711
4712            ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
4713            ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
4714
4715            synchronized (mLock) {
4716                mWriteScheduled.delete(userId);
4717
4718                final int packageCount = mPackages.size();
4719                for (int i = 0; i < packageCount; i++) {
4720                    String packageName = mPackages.keyAt(i);
4721                    PackageSetting packageSetting = mPackages.valueAt(i);
4722                    if (packageSetting.sharedUser == null) {
4723                        PermissionsState permissionsState = packageSetting.getPermissionsState();
4724                        List<PermissionState> permissionsStates = permissionsState
4725                                .getRuntimePermissionStates(userId);
4726                        if (!permissionsStates.isEmpty()) {
4727                            permissionsForPackage.put(packageName, permissionsStates);
4728                        }
4729                    }
4730                }
4731
4732                final int sharedUserCount = mSharedUsers.size();
4733                for (int i = 0; i < sharedUserCount; i++) {
4734                    String sharedUserName = mSharedUsers.keyAt(i);
4735                    SharedUserSetting sharedUser = mSharedUsers.valueAt(i);
4736                    PermissionsState permissionsState = sharedUser.getPermissionsState();
4737                    List<PermissionState> permissionsStates = permissionsState
4738                            .getRuntimePermissionStates(userId);
4739                    if (!permissionsStates.isEmpty()) {
4740                        permissionsForSharedUser.put(sharedUserName, permissionsStates);
4741                    }
4742                }
4743            }
4744
4745            FileOutputStream out = null;
4746            try {
4747                out = destination.startWrite();
4748
4749                XmlSerializer serializer = Xml.newSerializer();
4750                serializer.setOutput(out, StandardCharsets.UTF_8.name());
4751                serializer.setFeature(
4752                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
4753                serializer.startDocument(null, true);
4754
4755                serializer.startTag(null, TAG_RUNTIME_PERMISSIONS);
4756
4757                String fingerprint = mFingerprints.get(userId);
4758                if (fingerprint != null) {
4759                    serializer.attribute(null, ATTR_FINGERPRINT, fingerprint);
4760                }
4761
4762                final int packageCount = permissionsForPackage.size();
4763                for (int i = 0; i < packageCount; i++) {
4764                    String packageName = permissionsForPackage.keyAt(i);
4765                    List<PermissionState> permissionStates = permissionsForPackage.valueAt(i);
4766                    serializer.startTag(null, TAG_PACKAGE);
4767                    serializer.attribute(null, ATTR_NAME, packageName);
4768                    writePermissions(serializer, permissionStates);
4769                    serializer.endTag(null, TAG_PACKAGE);
4770                }
4771
4772                final int sharedUserCount = permissionsForSharedUser.size();
4773                for (int i = 0; i < sharedUserCount; i++) {
4774                    String packageName = permissionsForSharedUser.keyAt(i);
4775                    List<PermissionState> permissionStates = permissionsForSharedUser.valueAt(i);
4776                    serializer.startTag(null, TAG_SHARED_USER);
4777                    serializer.attribute(null, ATTR_NAME, packageName);
4778                    writePermissions(serializer, permissionStates);
4779                    serializer.endTag(null, TAG_SHARED_USER);
4780                }
4781
4782                serializer.endTag(null, TAG_RUNTIME_PERMISSIONS);
4783
4784                // Now any restored permission grants that are waiting for the apps
4785                // in question to be installed.  These are stored as per-package
4786                // TAG_RESTORED_RUNTIME_PERMISSIONS blocks, each containing some
4787                // number of individual permission grant entities.
4788                if (mRestoredUserGrants.get(userId) != null) {
4789                    ArrayMap<String, ArraySet<RestoredPermissionGrant>> restoredGrants =
4790                            mRestoredUserGrants.get(userId);
4791                    if (restoredGrants != null) {
4792                        final int pkgCount = restoredGrants.size();
4793                        for (int i = 0; i < pkgCount; i++) {
4794                            final ArraySet<RestoredPermissionGrant> pkgGrants =
4795                                    restoredGrants.valueAt(i);
4796                            if (pkgGrants != null && pkgGrants.size() > 0) {
4797                                final String pkgName = restoredGrants.keyAt(i);
4798                                serializer.startTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
4799                                serializer.attribute(null, ATTR_PACKAGE_NAME, pkgName);
4800
4801                                final int N = pkgGrants.size();
4802                                for (int z = 0; z < N; z++) {
4803                                    RestoredPermissionGrant g = pkgGrants.valueAt(z);
4804                                    serializer.startTag(null, TAG_PERMISSION_ENTRY);
4805                                    serializer.attribute(null, ATTR_NAME, g.permissionName);
4806
4807                                    if (g.granted) {
4808                                        serializer.attribute(null, ATTR_GRANTED, "true");
4809                                    }
4810
4811                                    if ((g.grantBits&FLAG_PERMISSION_USER_SET) != 0) {
4812                                        serializer.attribute(null, ATTR_USER_SET, "true");
4813                                    }
4814                                    if ((g.grantBits&FLAG_PERMISSION_USER_FIXED) != 0) {
4815                                        serializer.attribute(null, ATTR_USER_FIXED, "true");
4816                                    }
4817                                    if ((g.grantBits&FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
4818                                        serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
4819                                    }
4820                                    serializer.endTag(null, TAG_PERMISSION_ENTRY);
4821                                }
4822                                serializer.endTag(null, TAG_RESTORED_RUNTIME_PERMISSIONS);
4823                            }
4824                        }
4825                    }
4826                }
4827
4828                serializer.endDocument();
4829                destination.finishWrite(out);
4830
4831                if (Build.FINGERPRINT.equals(fingerprint)) {
4832                    mDefaultPermissionsGranted.put(userId, true);
4833                }
4834            // Any error while writing is fatal.
4835            } catch (Throwable t) {
4836                Slog.wtf(PackageManagerService.TAG,
4837                        "Failed to write settings, restoring backup", t);
4838                destination.failWrite(out);
4839            } finally {
4840                IoUtils.closeQuietly(out);
4841            }
4842        }
4843
4844        private void onUserRemoved(int userId) {
4845            // Make sure we do not
4846            mHandler.removeMessages(userId);
4847
4848            for (SettingBase sb : mPackages.values()) {
4849                revokeRuntimePermissionsAndClearFlags(sb, userId);
4850            }
4851
4852            for (SettingBase sb : mSharedUsers.values()) {
4853                revokeRuntimePermissionsAndClearFlags(sb, userId);
4854            }
4855        }
4856
4857        private void revokeRuntimePermissionsAndClearFlags(SettingBase sb, int userId) {
4858            PermissionsState permissionsState = sb.getPermissionsState();
4859            for (PermissionState permissionState
4860                    : permissionsState.getRuntimePermissionStates(userId)) {
4861                BasePermission bp = mPermissions.get(permissionState.getName());
4862                if (bp != null) {
4863                    permissionsState.revokeRuntimePermission(bp, userId);
4864                    permissionsState.updatePermissionFlags(bp, userId,
4865                            PackageManager.MASK_PERMISSION_FLAGS, 0);
4866                }
4867            }
4868        }
4869
4870        public void deleteUserRuntimePermissionsFile(int userId) {
4871            getUserRuntimePermissionsFile(userId).delete();
4872        }
4873
4874        public void readStateForUserSyncLPr(int userId) {
4875            File permissionsFile = getUserRuntimePermissionsFile(userId);
4876            if (!permissionsFile.exists()) {
4877                return;
4878            }
4879
4880            FileInputStream in;
4881            try {
4882                in = new AtomicFile(permissionsFile).openRead();
4883            } catch (FileNotFoundException fnfe) {
4884                Slog.i(PackageManagerService.TAG, "No permissions state");
4885                return;
4886            }
4887
4888            try {
4889                XmlPullParser parser = Xml.newPullParser();
4890                parser.setInput(in, null);
4891                parseRuntimePermissionsLPr(parser, userId);
4892
4893            } catch (XmlPullParserException | IOException e) {
4894                throw new IllegalStateException("Failed parsing permissions file: "
4895                        + permissionsFile , e);
4896            } finally {
4897                IoUtils.closeQuietly(in);
4898            }
4899        }
4900
4901        // Backup/restore support
4902
4903        public void rememberRestoredUserGrantLPr(String pkgName, String permission,
4904                boolean isGranted, int restoredFlagSet, int userId) {
4905            // This change will be remembered at write-settings time
4906            ArrayMap<String, ArraySet<RestoredPermissionGrant>> grantsByPackage =
4907                    mRestoredUserGrants.get(userId);
4908            if (grantsByPackage == null) {
4909                grantsByPackage = new ArrayMap<String, ArraySet<RestoredPermissionGrant>>();
4910                mRestoredUserGrants.put(userId, grantsByPackage);
4911            }
4912
4913            ArraySet<RestoredPermissionGrant> grants = grantsByPackage.get(pkgName);
4914            if (grants == null) {
4915                grants = new ArraySet<RestoredPermissionGrant>();
4916                grantsByPackage.put(pkgName, grants);
4917            }
4918
4919            RestoredPermissionGrant grant = new RestoredPermissionGrant(permission,
4920                    isGranted, restoredFlagSet);
4921            grants.add(grant);
4922        }
4923
4924        // Private internals
4925
4926        private void parseRuntimePermissionsLPr(XmlPullParser parser, int userId)
4927                throws IOException, XmlPullParserException {
4928            final int outerDepth = parser.getDepth();
4929            int type;
4930            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4931                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4932                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4933                    continue;
4934                }
4935
4936                switch (parser.getName()) {
4937                    case TAG_RUNTIME_PERMISSIONS: {
4938                        String fingerprint = parser.getAttributeValue(null, ATTR_FINGERPRINT);
4939                        mFingerprints.put(userId, fingerprint);
4940                        final boolean defaultsGranted = Build.FINGERPRINT.equals(fingerprint);
4941                        mDefaultPermissionsGranted.put(userId, defaultsGranted);
4942                    } break;
4943
4944                    case TAG_PACKAGE: {
4945                        String name = parser.getAttributeValue(null, ATTR_NAME);
4946                        PackageSetting ps = mPackages.get(name);
4947                        if (ps == null) {
4948                            Slog.w(PackageManagerService.TAG, "Unknown package:" + name);
4949                            XmlUtils.skipCurrentTag(parser);
4950                            continue;
4951                        }
4952                        parsePermissionsLPr(parser, ps.getPermissionsState(), userId);
4953                    } break;
4954
4955                    case TAG_SHARED_USER: {
4956                        String name = parser.getAttributeValue(null, ATTR_NAME);
4957                        SharedUserSetting sus = mSharedUsers.get(name);
4958                        if (sus == null) {
4959                            Slog.w(PackageManagerService.TAG, "Unknown shared user:" + name);
4960                            XmlUtils.skipCurrentTag(parser);
4961                            continue;
4962                        }
4963                        parsePermissionsLPr(parser, sus.getPermissionsState(), userId);
4964                    } break;
4965
4966                    case TAG_RESTORED_RUNTIME_PERMISSIONS: {
4967                        final String pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
4968                        parseRestoredRuntimePermissionsLPr(parser, pkgName, userId);
4969                    } break;
4970                }
4971            }
4972        }
4973
4974        private void parseRestoredRuntimePermissionsLPr(XmlPullParser parser,
4975                final String pkgName, final int userId) throws IOException, XmlPullParserException {
4976            final int outerDepth = parser.getDepth();
4977            int type;
4978            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
4979                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
4980                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
4981                    continue;
4982                }
4983
4984                switch (parser.getName()) {
4985                    case TAG_PERMISSION_ENTRY: {
4986                        final String permName = parser.getAttributeValue(null, ATTR_NAME);
4987                        final boolean isGranted = "true".equals(
4988                                parser.getAttributeValue(null, ATTR_GRANTED));
4989
4990                        int permBits = 0;
4991                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
4992                            permBits |= FLAG_PERMISSION_USER_SET;
4993                        }
4994                        if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
4995                            permBits |= FLAG_PERMISSION_USER_FIXED;
4996                        }
4997                        if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
4998                            permBits |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
4999                        }
5000
5001                        if (isGranted || permBits != 0) {
5002                            rememberRestoredUserGrantLPr(pkgName, permName, isGranted, permBits, userId);
5003                        }
5004                    } break;
5005                }
5006            }
5007        }
5008
5009        private void parsePermissionsLPr(XmlPullParser parser, PermissionsState permissionsState,
5010                int userId) throws IOException, XmlPullParserException {
5011            final int outerDepth = parser.getDepth();
5012            int type;
5013            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
5014                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
5015                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
5016                    continue;
5017                }
5018
5019                switch (parser.getName()) {
5020                    case TAG_ITEM: {
5021                        String name = parser.getAttributeValue(null, ATTR_NAME);
5022                        BasePermission bp = mPermissions.get(name);
5023                        if (bp == null) {
5024                            Slog.w(PackageManagerService.TAG, "Unknown permission:" + name);
5025                            XmlUtils.skipCurrentTag(parser);
5026                            continue;
5027                        }
5028
5029                        String grantedStr = parser.getAttributeValue(null, ATTR_GRANTED);
5030                        final boolean granted = grantedStr == null
5031                                || Boolean.parseBoolean(grantedStr);
5032
5033                        String flagsStr = parser.getAttributeValue(null, ATTR_FLAGS);
5034                        final int flags = (flagsStr != null)
5035                                ? Integer.parseInt(flagsStr, 16) : 0;
5036
5037                        if (granted) {
5038                            permissionsState.grantRuntimePermission(bp, userId);
5039                            permissionsState.updatePermissionFlags(bp, userId,
5040                                        PackageManager.MASK_PERMISSION_FLAGS, flags);
5041                        } else {
5042                            permissionsState.updatePermissionFlags(bp, userId,
5043                                    PackageManager.MASK_PERMISSION_FLAGS, flags);
5044                        }
5045
5046                    } break;
5047                }
5048            }
5049        }
5050
5051        private void writePermissions(XmlSerializer serializer,
5052                List<PermissionState> permissionStates) throws IOException {
5053            for (PermissionState permissionState : permissionStates) {
5054                serializer.startTag(null, TAG_ITEM);
5055                serializer.attribute(null, ATTR_NAME,permissionState.getName());
5056                serializer.attribute(null, ATTR_GRANTED,
5057                        String.valueOf(permissionState.isGranted()));
5058                serializer.attribute(null, ATTR_FLAGS,
5059                        Integer.toHexString(permissionState.getFlags()));
5060                serializer.endTag(null, TAG_ITEM);
5061            }
5062        }
5063
5064        private final class MyHandler extends Handler {
5065            public MyHandler() {
5066                super(BackgroundThread.getHandler().getLooper());
5067            }
5068
5069            @Override
5070            public void handleMessage(Message message) {
5071                final int userId = message.what;
5072                Runnable callback = (Runnable) message.obj;
5073                writePermissionsSync(userId);
5074                if (callback != null) {
5075                    callback.run();
5076                }
5077            }
5078        }
5079    }
5080}
5081