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