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