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