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