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