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