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