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