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