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