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