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