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