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