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