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