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