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