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