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