Settings.java revision b8f400020b201cc40f5e16277af0dbafec38b8a3
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_USER;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
23
24import com.android.internal.util.FastXmlSerializer;
25import com.android.internal.util.JournaledFile;
26import com.android.internal.util.XmlUtils;
27import com.android.server.IntentResolver;
28import com.android.server.pm.PackageManagerService.DumpState;
29
30import org.xmlpull.v1.XmlPullParser;
31import org.xmlpull.v1.XmlPullParserException;
32import org.xmlpull.v1.XmlSerializer;
33
34import android.content.ComponentName;
35import android.content.Intent;
36import android.content.pm.ApplicationInfo;
37import android.content.pm.ComponentInfo;
38import android.content.pm.PackageManager;
39import android.content.pm.PackageParser;
40import android.content.pm.PermissionInfo;
41import android.content.pm.Signature;
42import android.os.Binder;
43import android.os.Environment;
44import android.os.FileUtils;
45import android.os.Process;
46import android.util.Log;
47import android.util.Slog;
48import android.util.SparseArray;
49import android.util.Xml;
50
51import java.io.BufferedOutputStream;
52import java.io.File;
53import java.io.FileInputStream;
54import java.io.FileOutputStream;
55import java.io.IOException;
56import java.io.PrintWriter;
57import java.text.SimpleDateFormat;
58import java.util.ArrayList;
59import java.util.Arrays;
60import java.util.Date;
61import java.util.HashMap;
62import java.util.HashSet;
63import java.util.Iterator;
64
65/**
66 * Holds information about dynamic settings.
67 */
68final class Settings {
69    private static final String TAG = "PackageSettings";
70
71    private static final boolean DEBUG_STOPPED = false;
72
73    private final File mSettingsFilename;
74    private final File mBackupSettingsFilename;
75    private final File mPackageListFilename;
76    private final File mStoppedPackagesFilename;
77    private final File mBackupStoppedPackagesFilename;
78    final HashMap<String, PackageSetting> mPackages =
79            new HashMap<String, PackageSetting>();
80    // List of replaced system applications
81    final HashMap<String, PackageSetting> mDisabledSysPackages =
82        new HashMap<String, PackageSetting>();
83
84    // These are the last platform API version we were using for
85    // the apps installed on internal and external storage.  It is
86    // used to grant newer permissions one time during a system upgrade.
87    int mInternalSdkPlatform;
88    int mExternalSdkPlatform;
89
90    // The user's preferred activities associated with particular intent
91    // filters.
92    final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
93                new IntentResolver<PreferredActivity, PreferredActivity>() {
94        @Override
95        protected String packageForFilter(PreferredActivity filter) {
96            return filter.mPref.mComponent.getPackageName();
97        }
98        @Override
99        protected void dumpFilter(PrintWriter out, String prefix,
100                PreferredActivity filter) {
101            filter.mPref.dump(out, prefix, filter);
102        }
103    };
104    final HashMap<String, SharedUserSetting> mSharedUsers =
105            new HashMap<String, SharedUserSetting>();
106    private final ArrayList<Object> mUserIds = new ArrayList<Object>();
107    private final SparseArray<Object> mOtherUserIds =
108            new SparseArray<Object>();
109
110    // For reading/writing settings file.
111    private final ArrayList<Signature> mPastSignatures =
112            new ArrayList<Signature>();
113
114    // Mapping from permission names to info about them.
115    final HashMap<String, BasePermission> mPermissions =
116            new HashMap<String, BasePermission>();
117
118    // Mapping from permission tree names to info about them.
119    final HashMap<String, BasePermission> mPermissionTrees =
120            new HashMap<String, BasePermission>();
121
122    // Packages that have been uninstalled and still need their external
123    // storage data deleted.
124    final ArrayList<String> mPackagesToBeCleaned = new ArrayList<String>();
125
126    // Packages that have been renamed since they were first installed.
127    // Keys are the new names of the packages, values are the original
128    // names.  The packages appear everwhere else under their original
129    // names.
130    final HashMap<String, String> mRenamedPackages = new HashMap<String, String>();
131
132    final StringBuilder mReadMessages = new StringBuilder();
133
134    /**
135     * Used to track packages that have a shared user ID that hasn't been read
136     * in yet.
137     * <p>
138     * TODO: make this just a local variable that is passed in during package
139     * scanning to make it less confusing.
140     */
141    private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
142
143    Settings() {
144        File dataDir = Environment.getDataDirectory();
145        File systemDir = new File(dataDir, "system");
146        systemDir.mkdirs();
147        FileUtils.setPermissions(systemDir.toString(),
148                FileUtils.S_IRWXU|FileUtils.S_IRWXG
149                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
150                -1, -1);
151        mSettingsFilename = new File(systemDir, "packages.xml");
152        mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
153        mPackageListFilename = new File(systemDir, "packages.list");
154        mStoppedPackagesFilename = new File(systemDir, "packages-stopped.xml");
155        mBackupStoppedPackagesFilename = new File(systemDir, "packages-stopped-backup.xml");
156    }
157
158    PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
159            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
160            String nativeLibraryPathString, int pkgFlags, boolean create, boolean add) {
161        final String name = pkg.packageName;
162        PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
163                resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags, create, add);
164        return p;
165    }
166
167    PackageSetting peekPackageLPr(String name) {
168        return mPackages.get(name);
169    }
170
171    void setInstallStatus(String pkgName, int status) {
172        PackageSetting p = mPackages.get(pkgName);
173        if(p != null) {
174            if(p.getInstallStatus() != status) {
175                p.setInstallStatus(status);
176            }
177        }
178    }
179
180    void setInstallerPackageName(String pkgName,
181            String installerPkgName) {
182        PackageSetting p = mPackages.get(pkgName);
183        if(p != null) {
184            p.setInstallerPackageName(installerPkgName);
185        }
186    }
187
188    SharedUserSetting getSharedUserLPw(String name,
189            int pkgFlags, boolean create) {
190        SharedUserSetting s = mSharedUsers.get(name);
191        if (s == null) {
192            if (!create) {
193                return null;
194            }
195            s = new SharedUserSetting(name, pkgFlags);
196            if (PackageManagerService.MULTIPLE_APPLICATION_UIDS) {
197                s.userId = newUserIdLPw(s);
198            } else {
199                s.userId = PackageManagerService.FIRST_APPLICATION_UID;
200            }
201            Log.i(PackageManagerService.TAG, "New shared user " + name + ": id=" + s.userId);
202            // < 0 means we couldn't assign a userid; fall out and return
203            // s, which is currently null
204            if (s.userId >= 0) {
205                mSharedUsers.put(name, s);
206            }
207        }
208
209        return s;
210    }
211
212    boolean disableSystemPackageLPw(String name) {
213        final PackageSetting p = mPackages.get(name);
214        if(p == null) {
215            Log.w(PackageManagerService.TAG, "Package:"+name+" is not an installed package");
216            return false;
217        }
218        final PackageSetting dp = mDisabledSysPackages.get(name);
219        // always make sure the system package code and resource paths dont change
220        if (dp == null) {
221            if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
222                p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
223            }
224            mDisabledSysPackages.put(name, p);
225
226            // a little trick...  when we install the new package, we don't
227            // want to modify the existing PackageSetting for the built-in
228            // version.  so at this point we need a new PackageSetting that
229            // is okay to muck with.
230            PackageSetting newp = new PackageSetting(p);
231            replacePackageLPw(name, newp);
232            return true;
233        }
234        return false;
235    }
236
237    PackageSetting enableSystemPackageLPw(String name) {
238        PackageSetting p = mDisabledSysPackages.get(name);
239        if(p == null) {
240            Log.w(PackageManagerService.TAG, "Package:"+name+" is not disabled");
241            return null;
242        }
243        // Reset flag in ApplicationInfo object
244        if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
245            p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
246        }
247        PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
248                p.nativeLibraryPathString, p.userId, p.versionCode, p.pkgFlags);
249        mDisabledSysPackages.remove(name);
250        return ret;
251    }
252
253    PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
254            String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
255        PackageSetting p = mPackages.get(name);
256        if (p != null) {
257            if (p.userId == uid) {
258                return p;
259            }
260            PackageManagerService.reportSettingsProblem(Log.ERROR,
261                    "Adding duplicate package, keeping first: " + name);
262            return null;
263        }
264        p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
265                vc, pkgFlags);
266        p.userId = uid;
267        if (addUserIdLPw(uid, p, name)) {
268            mPackages.put(name, p);
269            return p;
270        }
271        return null;
272    }
273
274    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags) {
275        SharedUserSetting s = mSharedUsers.get(name);
276        if (s != null) {
277            if (s.userId == uid) {
278                return s;
279            }
280            PackageManagerService.reportSettingsProblem(Log.ERROR,
281                    "Adding duplicate shared user, keeping first: " + name);
282            return null;
283        }
284        s = new SharedUserSetting(name, pkgFlags);
285        s.userId = uid;
286        if (addUserIdLPw(uid, s, name)) {
287            mSharedUsers.put(name, s);
288            return s;
289        }
290        return null;
291    }
292
293    // Transfer ownership of permissions from one package to another.
294    void transferPermissionsLPw(String origPkg, String newPkg) {
295        // Transfer ownership of permissions to the new package.
296        for (int i=0; i<2; i++) {
297            HashMap<String, BasePermission> permissions =
298                    i == 0 ? mPermissionTrees : mPermissions;
299            for (BasePermission bp : permissions.values()) {
300                if (origPkg.equals(bp.sourcePackage)) {
301                    if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG,
302                            "Moving permission " + bp.name
303                            + " from pkg " + bp.sourcePackage
304                            + " to " + newPkg);
305                    bp.sourcePackage = newPkg;
306                    bp.packageSetting = null;
307                    bp.perm = null;
308                    if (bp.pendingInfo != null) {
309                        bp.pendingInfo.packageName = newPkg;
310                    }
311                    bp.uid = 0;
312                    bp.gids = null;
313                }
314            }
315        }
316    }
317
318    private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
319            String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
320            String nativeLibraryPathString, int vc, int pkgFlags, boolean create, boolean add) {
321        PackageSetting p = mPackages.get(name);
322        if (p != null) {
323            if (!p.codePath.equals(codePath)) {
324                // Check to see if its a disabled system app
325                if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
326                    // This is an updated system app with versions in both system
327                    // and data partition. Just let the most recent version
328                    // take precedence.
329                    Slog.w(PackageManagerService.TAG, "Trying to update system app code path from " +
330                            p.codePathString + " to " + codePath.toString());
331                } else {
332                    // Just a change in the code path is not an issue, but
333                    // let's log a message about it.
334                    Slog.i(PackageManagerService.TAG, "Package " + name + " codePath changed from " + p.codePath
335                            + " to " + codePath + "; Retaining data and using new");
336                    /*
337                     * Since we've changed paths, we need to prefer the new
338                     * native library path over the one stored in the
339                     * package settings since we might have moved from
340                     * internal to external storage or vice versa.
341                     */
342                    p.nativeLibraryPathString = nativeLibraryPathString;
343                }
344            }
345            if (p.sharedUser != sharedUser) {
346                PackageManagerService.reportSettingsProblem(Log.WARN,
347                        "Package " + name + " shared user changed from "
348                        + (p.sharedUser != null ? p.sharedUser.name : "<nothing>")
349                        + " to "
350                        + (sharedUser != null ? sharedUser.name : "<nothing>")
351                        + "; replacing with new");
352                p = null;
353            } else {
354                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
355                    // If what we are scanning is a system package, then
356                    // make it so, regardless of whether it was previously
357                    // installed only in the data partition.
358                    p.pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
359                }
360            }
361        }
362        if (p == null) {
363            // Create a new PackageSettings entry. this can end up here because
364            // of code path mismatch or user id mismatch of an updated system partition
365            if (!create) {
366                return null;
367            }
368            if (origPackage != null) {
369                // We are consuming the data from an existing package.
370                p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
371                        nativeLibraryPathString, vc, pkgFlags);
372                if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package " + name
373                        + " is adopting original package " + origPackage.name);
374                // Note that we will retain the new package's signature so
375                // that we can keep its data.
376                PackageSignatures s = p.signatures;
377                p.copyFrom(origPackage);
378                p.signatures = s;
379                p.sharedUser = origPackage.sharedUser;
380                p.userId = origPackage.userId;
381                p.origPackage = origPackage;
382                mRenamedPackages.put(name, origPackage.name);
383                name = origPackage.name;
384                // Update new package state.
385                p.setTimeStamp(codePath.lastModified());
386            } else {
387                p = new PackageSetting(name, realName, codePath, resourcePath,
388                        nativeLibraryPathString, vc, pkgFlags);
389                p.setTimeStamp(codePath.lastModified());
390                p.sharedUser = sharedUser;
391                // If this is not a system app, it starts out stopped.
392                if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
393                    if (DEBUG_STOPPED) {
394                        RuntimeException e = new RuntimeException("here");
395                        e.fillInStackTrace();
396                        Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
397                    }
398                    p.stopped = true;
399                    p.notLaunched = true;
400                }
401                if (sharedUser != null) {
402                    p.userId = sharedUser.userId;
403                } else if (PackageManagerService.MULTIPLE_APPLICATION_UIDS) {
404                    // Clone the setting here for disabled system packages
405                    PackageSetting dis = mDisabledSysPackages.get(name);
406                    if (dis != null) {
407                        // For disabled packages a new setting is created
408                        // from the existing user id. This still has to be
409                        // added to list of user id's
410                        // Copy signatures from previous setting
411                        if (dis.signatures.mSignatures != null) {
412                            p.signatures.mSignatures = dis.signatures.mSignatures.clone();
413                        }
414                        p.userId = dis.userId;
415                        // Clone permissions
416                        p.grantedPermissions = new HashSet<String>(dis.grantedPermissions);
417                        // Clone component info
418                        p.disabledComponents = new HashSet<String>(dis.disabledComponents);
419                        p.enabledComponents = new HashSet<String>(dis.enabledComponents);
420                        // Add new setting to list of user ids
421                        addUserIdLPw(p.userId, p, name);
422                    } else {
423                        // Assign new user id
424                        p.userId = newUserIdLPw(p);
425                    }
426                } else {
427                    p.userId = PackageManagerService.FIRST_APPLICATION_UID;
428                }
429            }
430            if (p.userId < 0) {
431                PackageManagerService.reportSettingsProblem(Log.WARN,
432                        "Package " + name + " could not be assigned a valid uid");
433                return null;
434            }
435            if (add) {
436                // Finish adding new package by adding it and updating shared
437                // user preferences
438                addPackageSettingLPw(p, name, sharedUser);
439            }
440        }
441        return p;
442    }
443
444    void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
445        p.pkg = pkg;
446        pkg.mSetEnabled = p.enabled;
447        pkg.mSetStopped = p.stopped;
448        final String codePath = pkg.applicationInfo.sourceDir;
449        final String resourcePath = pkg.applicationInfo.publicSourceDir;
450        // Update code path if needed
451        if (!codePath.equalsIgnoreCase(p.codePathString)) {
452            Slog.w(PackageManagerService.TAG, "Code path for pkg : " + p.pkg.packageName +
453                    " changing from " + p.codePathString + " to " + codePath);
454            p.codePath = new File(codePath);
455            p.codePathString = codePath;
456        }
457        //Update resource path if needed
458        if (!resourcePath.equalsIgnoreCase(p.resourcePathString)) {
459            Slog.w(PackageManagerService.TAG, "Resource path for pkg : " + p.pkg.packageName +
460                    " changing from " + p.resourcePathString + " to " + resourcePath);
461            p.resourcePath = new File(resourcePath);
462            p.resourcePathString = resourcePath;
463        }
464        // Update the native library path if needed
465        final String nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
466        if (nativeLibraryPath != null
467                && !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
468            p.nativeLibraryPathString = nativeLibraryPath;
469        }
470        // Update version code if needed
471         if (pkg.mVersionCode != p.versionCode) {
472            p.versionCode = pkg.mVersionCode;
473        }
474         // Update signatures if needed.
475         if (p.signatures.mSignatures == null) {
476             p.signatures.assignSignatures(pkg.mSignatures);
477         }
478         // If this app defines a shared user id initialize
479         // the shared user signatures as well.
480         if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
481             p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
482         }
483        addPackageSettingLPw(p, pkg.packageName, p.sharedUser);
484    }
485
486    // Utility method that adds a PackageSetting to mPackages and
487    // completes updating the shared user attributes
488    private void addPackageSettingLPw(PackageSetting p, String name,
489            SharedUserSetting sharedUser) {
490        mPackages.put(name, p);
491        if (sharedUser != null) {
492            if (p.sharedUser != null && p.sharedUser != sharedUser) {
493                PackageManagerService.reportSettingsProblem(Log.ERROR,
494                        "Package " + p.name + " was user "
495                        + p.sharedUser + " but is now " + sharedUser
496                        + "; I am not changing its files so it will probably fail!");
497                p.sharedUser.packages.remove(p);
498            } else if (p.userId != sharedUser.userId) {
499                PackageManagerService.reportSettingsProblem(Log.ERROR,
500                    "Package " + p.name + " was user id " + p.userId
501                    + " but is now user " + sharedUser
502                    + " with id " + sharedUser.userId
503                    + "; I am not changing its files so it will probably fail!");
504            }
505
506            sharedUser.packages.add(p);
507            p.sharedUser = sharedUser;
508            p.userId = sharedUser.userId;
509        }
510    }
511
512    /*
513     * Update the shared user setting when a package using
514     * specifying the shared user id is removed. The gids
515     * associated with each permission of the deleted package
516     * are removed from the shared user's gid list only if its
517     * not in use by other permissions of packages in the
518     * shared user setting.
519     */
520    void updateSharedUserPermsLPw(PackageSetting deletedPs, int[] globalGids) {
521        if ((deletedPs == null) || (deletedPs.pkg == null)) {
522            Slog.i(PackageManagerService.TAG,
523                    "Trying to update info for null package. Just ignoring");
524            return;
525        }
526        // No sharedUserId
527        if (deletedPs.sharedUser == null) {
528            return;
529        }
530        SharedUserSetting sus = deletedPs.sharedUser;
531        // Update permissions
532        for (String eachPerm : deletedPs.pkg.requestedPermissions) {
533            boolean used = false;
534            if (!sus.grantedPermissions.contains(eachPerm)) {
535                continue;
536            }
537            for (PackageSetting pkg:sus.packages) {
538                if (pkg.pkg != null &&
539                        !pkg.pkg.packageName.equals(deletedPs.pkg.packageName) &&
540                        pkg.pkg.requestedPermissions.contains(eachPerm)) {
541                    used = true;
542                    break;
543                }
544            }
545            if (!used) {
546                // can safely delete this permission from list
547                sus.grantedPermissions.remove(eachPerm);
548            }
549        }
550        // Update gids
551        int newGids[] = globalGids;
552        for (String eachPerm : sus.grantedPermissions) {
553            BasePermission bp = mPermissions.get(eachPerm);
554            if (bp != null) {
555                newGids = PackageManagerService.appendInts(newGids, bp.gids);
556            }
557        }
558        sus.gids = newGids;
559    }
560
561    int removePackageLPw(String name) {
562        final PackageSetting p = mPackages.get(name);
563        if (p != null) {
564            mPackages.remove(name);
565            if (p.sharedUser != null) {
566                p.sharedUser.packages.remove(p);
567                if (p.sharedUser.packages.size() == 0) {
568                    mSharedUsers.remove(p.sharedUser.name);
569                    removeUserIdLPw(p.sharedUser.userId);
570                    return p.sharedUser.userId;
571                }
572            } else {
573                removeUserIdLPw(p.userId);
574                return p.userId;
575            }
576        }
577        return -1;
578    }
579
580    private void replacePackageLPw(String name, PackageSetting newp) {
581        final PackageSetting p = mPackages.get(name);
582        if (p != null) {
583            if (p.sharedUser != null) {
584                p.sharedUser.packages.remove(p);
585                p.sharedUser.packages.add(newp);
586            } else {
587                replaceUserIdLPw(p.userId, newp);
588            }
589        }
590        mPackages.put(name, newp);
591    }
592
593    private boolean addUserIdLPw(int uid, Object obj, Object name) {
594        if (uid >= PackageManagerService.FIRST_APPLICATION_UID + PackageManagerService.MAX_APPLICATION_UIDS) {
595            return false;
596        }
597
598        if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
599            int N = mUserIds.size();
600            final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
601            while (index >= N) {
602                mUserIds.add(null);
603                N++;
604            }
605            if (mUserIds.get(index) != null) {
606                PackageManagerService.reportSettingsProblem(Log.ERROR,
607                        "Adding duplicate user id: " + uid
608                        + " name=" + name);
609                return false;
610            }
611            mUserIds.set(index, obj);
612        } else {
613            if (mOtherUserIds.get(uid) != null) {
614                PackageManagerService.reportSettingsProblem(Log.ERROR,
615                        "Adding duplicate shared id: " + uid
616                        + " name=" + name);
617                return false;
618            }
619            mOtherUserIds.put(uid, obj);
620        }
621        return true;
622    }
623
624    public Object getUserIdLPr(int uid) {
625        if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
626            final int N = mUserIds.size();
627            final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
628            return index < N ? mUserIds.get(index) : null;
629        } else {
630            return mOtherUserIds.get(uid);
631        }
632    }
633
634    private void removeUserIdLPw(int uid) {
635        if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
636            final int N = mUserIds.size();
637            final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
638            if (index < N) mUserIds.set(index, null);
639        } else {
640            mOtherUserIds.remove(uid);
641        }
642    }
643
644    private void replaceUserIdLPw(int uid, Object obj) {
645        if (uid >= PackageManagerService.FIRST_APPLICATION_UID) {
646            final int N = mUserIds.size();
647            final int index = uid - PackageManagerService.FIRST_APPLICATION_UID;
648            if (index < N) mUserIds.set(index, obj);
649        } else {
650            mOtherUserIds.put(uid, obj);
651        }
652    }
653
654    void writeStoppedLPr() {
655        // Keep the old stopped packages around until we know the new ones have
656        // been successfully written.
657        if (mStoppedPackagesFilename.exists()) {
658            // Presence of backup settings file indicates that we failed
659            // to persist packages earlier. So preserve the older
660            // backup for future reference since the current packages
661            // might have been corrupted.
662            if (!mBackupStoppedPackagesFilename.exists()) {
663                if (!mStoppedPackagesFilename.renameTo(mBackupStoppedPackagesFilename)) {
664                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager stopped packages, "
665                            + "current changes will be lost at reboot");
666                    return;
667                }
668            } else {
669                mStoppedPackagesFilename.delete();
670                Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
671            }
672        }
673
674        try {
675            final FileOutputStream fstr = new FileOutputStream(mStoppedPackagesFilename);
676            final BufferedOutputStream str = new BufferedOutputStream(fstr);
677
678            //XmlSerializer serializer = XmlUtils.serializerInstance();
679            final XmlSerializer serializer = new FastXmlSerializer();
680            serializer.setOutput(str, "utf-8");
681            serializer.startDocument(null, true);
682            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
683
684            serializer.startTag(null, "stopped-packages");
685
686            for (final PackageSetting pkg : mPackages.values()) {
687                if (pkg.stopped) {
688                    serializer.startTag(null, "pkg");
689                    serializer.attribute(null, "name", pkg.name);
690                    if (pkg.notLaunched) {
691                        serializer.attribute(null, "nl", "1");
692                    }
693                    serializer.endTag(null, "pkg");
694                }
695            }
696
697            serializer.endTag(null, "stopped-packages");
698
699            serializer.endDocument();
700
701            str.flush();
702            FileUtils.sync(fstr);
703            str.close();
704
705            // New settings successfully written, old ones are no longer
706            // needed.
707            mBackupStoppedPackagesFilename.delete();
708            FileUtils.setPermissions(mStoppedPackagesFilename.toString(),
709                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
710                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP
711                    |FileUtils.S_IROTH,
712                    -1, -1);
713
714            // Done, all is good!
715            return;
716        } catch(java.io.IOException e) {
717            Log.wtf(PackageManagerService.TAG, "Unable to write package manager stopped packages, "
718                    + " current changes will be lost at reboot", e);
719        }
720
721        // Clean up partially written files
722        if (mStoppedPackagesFilename.exists()) {
723            if (!mStoppedPackagesFilename.delete()) {
724                Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " + mStoppedPackagesFilename);
725            }
726        }
727    }
728
729    // Note: assumed "stopped" field is already cleared in all packages.
730    void readStoppedLPw() {
731        FileInputStream str = null;
732        if (mBackupStoppedPackagesFilename.exists()) {
733            try {
734                str = new FileInputStream(mBackupStoppedPackagesFilename);
735                mReadMessages.append("Reading from backup stopped packages file\n");
736                PackageManagerService.reportSettingsProblem(Log.INFO, "Need to read from backup stopped packages file");
737                if (mSettingsFilename.exists()) {
738                    // If both the backup and normal file exist, we
739                    // ignore the normal one since it might have been
740                    // corrupted.
741                    Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
742                            + mStoppedPackagesFilename);
743                    mStoppedPackagesFilename.delete();
744                }
745            } catch (java.io.IOException e) {
746                // We'll try for the normal settings file.
747            }
748        }
749
750        try {
751            if (str == null) {
752                if (!mStoppedPackagesFilename.exists()) {
753                    mReadMessages.append("No stopped packages file found\n");
754                    PackageManagerService.reportSettingsProblem(Log.INFO, "No stopped packages file file; "
755                            + "assuming all started");
756                    // At first boot, make sure no packages are stopped.
757                    // We usually want to have third party apps initialize
758                    // in the stopped state, but not at first boot.
759                    for (PackageSetting pkg : mPackages.values()) {
760                        pkg.stopped = false;
761                        pkg.notLaunched = false;
762                    }
763                    return;
764                }
765                str = new FileInputStream(mStoppedPackagesFilename);
766            }
767            final XmlPullParser parser = Xml.newPullParser();
768            parser.setInput(str, null);
769
770            int type;
771            while ((type=parser.next()) != XmlPullParser.START_TAG
772                       && type != XmlPullParser.END_DOCUMENT) {
773                ;
774            }
775
776            if (type != XmlPullParser.START_TAG) {
777                mReadMessages.append("No start tag found in stopped packages file\n");
778                PackageManagerService.reportSettingsProblem(Log.WARN,
779                        "No start tag found in package manager stopped packages");
780                return;
781            }
782
783            int outerDepth = parser.getDepth();
784            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
785                   && (type != XmlPullParser.END_TAG
786                           || parser.getDepth() > outerDepth)) {
787                if (type == XmlPullParser.END_TAG
788                        || type == XmlPullParser.TEXT) {
789                    continue;
790                }
791
792                String tagName = parser.getName();
793                if (tagName.equals("pkg")) {
794                    String name = parser.getAttributeValue(null, "name");
795                    PackageSetting ps = mPackages.get(name);
796                    if (ps != null) {
797                        ps.stopped = true;
798                        if ("1".equals(parser.getAttributeValue(null, "nl"))) {
799                            ps.notLaunched = true;
800                        }
801                    } else {
802                        Slog.w(PackageManagerService.TAG, "No package known for stopped package: " + name);
803                    }
804                    XmlUtils.skipCurrentTag(parser);
805                } else {
806                    Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
807                          + parser.getName());
808                    XmlUtils.skipCurrentTag(parser);
809                }
810            }
811
812            str.close();
813
814        } catch(XmlPullParserException e) {
815            mReadMessages.append("Error reading: " + e.toString());
816            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e);
817            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
818
819        } catch(java.io.IOException e) {
820            mReadMessages.append("Error reading: " + e.toString());
821            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
822            Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e);
823
824        }
825    }
826
827    void writeLPr() {
828        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
829
830        // Keep the old settings around until we know the new ones have
831        // been successfully written.
832        if (mSettingsFilename.exists()) {
833            // Presence of backup settings file indicates that we failed
834            // to persist settings earlier. So preserve the older
835            // backup for future reference since the current settings
836            // might have been corrupted.
837            if (!mBackupSettingsFilename.exists()) {
838                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
839                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
840                            + " current changes will be lost at reboot");
841                    return;
842                }
843            } else {
844                mSettingsFilename.delete();
845                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
846            }
847        }
848
849        mPastSignatures.clear();
850
851        try {
852            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
853            BufferedOutputStream str = new BufferedOutputStream(fstr);
854
855            //XmlSerializer serializer = XmlUtils.serializerInstance();
856            XmlSerializer serializer = new FastXmlSerializer();
857            serializer.setOutput(str, "utf-8");
858            serializer.startDocument(null, true);
859            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
860
861            serializer.startTag(null, "packages");
862
863            serializer.startTag(null, "last-platform-version");
864            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
865            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
866            serializer.endTag(null, "last-platform-version");
867
868            serializer.startTag(null, "permission-trees");
869            for (BasePermission bp : mPermissionTrees.values()) {
870                writePermissionLPr(serializer, bp);
871            }
872            serializer.endTag(null, "permission-trees");
873
874            serializer.startTag(null, "permissions");
875            for (BasePermission bp : mPermissions.values()) {
876                writePermissionLPr(serializer, bp);
877            }
878            serializer.endTag(null, "permissions");
879
880            for (final PackageSetting pkg : mPackages.values()) {
881                writePackageLPr(serializer, pkg);
882            }
883
884            for (final PackageSetting pkg : mDisabledSysPackages.values()) {
885                writeDisabledSysPackageLPr(serializer, pkg);
886            }
887
888            serializer.startTag(null, "preferred-activities");
889            for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
890                serializer.startTag(null, "item");
891                pa.writeToXml(serializer);
892                serializer.endTag(null, "item");
893            }
894            serializer.endTag(null, "preferred-activities");
895
896            for (final SharedUserSetting usr : mSharedUsers.values()) {
897                serializer.startTag(null, "shared-user");
898                serializer.attribute(null, "name", usr.name);
899                serializer.attribute(null, "userId",
900                        Integer.toString(usr.userId));
901                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
902                serializer.startTag(null, "perms");
903                for (String name : usr.grantedPermissions) {
904                    serializer.startTag(null, "item");
905                    serializer.attribute(null, "name", name);
906                    serializer.endTag(null, "item");
907                }
908                serializer.endTag(null, "perms");
909                serializer.endTag(null, "shared-user");
910            }
911
912            if (mPackagesToBeCleaned.size() > 0) {
913                for (int i=0; i<mPackagesToBeCleaned.size(); i++) {
914                    serializer.startTag(null, "cleaning-package");
915                    serializer.attribute(null, "name", mPackagesToBeCleaned.get(i));
916                    serializer.endTag(null, "cleaning-package");
917                }
918            }
919
920            if (mRenamedPackages.size() > 0) {
921                for (HashMap.Entry<String, String> e : mRenamedPackages.entrySet()) {
922                    serializer.startTag(null, "renamed-package");
923                    serializer.attribute(null, "new", e.getKey());
924                    serializer.attribute(null, "old", e.getValue());
925                    serializer.endTag(null, "renamed-package");
926                }
927            }
928
929            serializer.endTag(null, "packages");
930
931            serializer.endDocument();
932
933            str.flush();
934            FileUtils.sync(fstr);
935            str.close();
936
937            // New settings successfully written, old ones are no longer
938            // needed.
939            mBackupSettingsFilename.delete();
940            FileUtils.setPermissions(mSettingsFilename.toString(),
941                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
942                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP
943                    |FileUtils.S_IROTH,
944                    -1, -1);
945
946            // Write package list file now, use a JournaledFile.
947            //
948            File tempFile = new File(mPackageListFilename.toString() + ".tmp");
949            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
950
951            fstr = new FileOutputStream(journal.chooseForWrite());
952            str = new BufferedOutputStream(fstr);
953            try {
954                StringBuilder sb = new StringBuilder();
955                for (final PackageSetting pkg : mPackages.values()) {
956                    ApplicationInfo ai = pkg.pkg.applicationInfo;
957                    String dataPath = ai.dataDir;
958                    boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
959
960                    // Avoid any application that has a space in its path
961                    // or that is handled by the system.
962                    if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
963                        continue;
964
965                    // we store on each line the following information for now:
966                    //
967                    // pkgName    - package name
968                    // userId     - application-specific user id
969                    // debugFlag  - 0 or 1 if the package is debuggable.
970                    // dataPath   - path to package's data path
971                    //
972                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.
973                    //
974                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
975                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
976                    //   system/core/run-as/run-as.c
977                    //
978                    sb.setLength(0);
979                    sb.append(ai.packageName);
980                    sb.append(" ");
981                    sb.append((int)ai.uid);
982                    sb.append(isDebug ? " 1 " : " 0 ");
983                    sb.append(dataPath);
984                    sb.append("\n");
985                    str.write(sb.toString().getBytes());
986                }
987                str.flush();
988                FileUtils.sync(fstr);
989                str.close();
990                journal.commit();
991            }
992            catch (Exception  e) {
993                journal.rollback();
994            }
995
996            FileUtils.setPermissions(mPackageListFilename.toString(),
997                    FileUtils.S_IRUSR|FileUtils.S_IWUSR
998                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP
999                    |FileUtils.S_IROTH,
1000                    -1, -1);
1001
1002            writeStoppedLPr();
1003
1004            return;
1005
1006        } catch(XmlPullParserException e) {
1007            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1008                    + "current changes will be lost at reboot", e);
1009        } catch(java.io.IOException e) {
1010            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
1011                    + "current changes will be lost at reboot", e);
1012        }
1013        // Clean up partially written files
1014        if (mSettingsFilename.exists()) {
1015            if (!mSettingsFilename.delete()) {
1016                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename);
1017            }
1018        }
1019        //Debug.stopMethodTracing();
1020    }
1021
1022    void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1023            throws java.io.IOException {
1024        serializer.startTag(null, "updated-package");
1025        serializer.attribute(null, "name", pkg.name);
1026        if (pkg.realName != null) {
1027            serializer.attribute(null, "realName", pkg.realName);
1028        }
1029        serializer.attribute(null, "codePath", pkg.codePathString);
1030        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1031        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1032        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1033        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1034        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1035            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1036        }
1037        if (pkg.nativeLibraryPathString != null) {
1038            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1039        }
1040        if (pkg.sharedUser == null) {
1041            serializer.attribute(null, "userId", Integer.toString(pkg.userId));
1042        } else {
1043            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId));
1044        }
1045        serializer.startTag(null, "perms");
1046        if (pkg.sharedUser == null) {
1047            // If this is a shared user, the permissions will
1048            // be written there. We still need to write an
1049            // empty permissions list so permissionsFixed will
1050            // be set.
1051            for (final String name : pkg.grantedPermissions) {
1052                BasePermission bp = mPermissions.get(name);
1053                if (bp != null) {
1054                    // We only need to write signature or system permissions but
1055                    // this wont
1056                    // match the semantics of grantedPermissions. So write all
1057                    // permissions.
1058                    serializer.startTag(null, "item");
1059                    serializer.attribute(null, "name", name);
1060                    serializer.endTag(null, "item");
1061                }
1062            }
1063        }
1064        serializer.endTag(null, "perms");
1065        serializer.endTag(null, "updated-package");
1066    }
1067
1068    void writePackageLPr(XmlSerializer serializer, final PackageSetting pkg)
1069            throws java.io.IOException {
1070        serializer.startTag(null, "package");
1071        serializer.attribute(null, "name", pkg.name);
1072        if (pkg.realName != null) {
1073            serializer.attribute(null, "realName", pkg.realName);
1074        }
1075        serializer.attribute(null, "codePath", pkg.codePathString);
1076        if (!pkg.resourcePathString.equals(pkg.codePathString)) {
1077            serializer.attribute(null, "resourcePath", pkg.resourcePathString);
1078        }
1079        if (pkg.nativeLibraryPathString != null) {
1080            serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
1081        }
1082        serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
1083        serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
1084        serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
1085        serializer.attribute(null, "ut", Long.toHexString(pkg.lastUpdateTime));
1086        serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
1087        if (pkg.sharedUser == null) {
1088            serializer.attribute(null, "userId", Integer.toString(pkg.userId));
1089        } else {
1090            serializer.attribute(null, "sharedUserId", Integer.toString(pkg.userId));
1091        }
1092        if (pkg.uidError) {
1093            serializer.attribute(null, "uidError", "true");
1094        }
1095        if (pkg.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
1096            serializer.attribute(null, "enabled", Integer.toString(pkg.enabled));
1097        }
1098        if (pkg.installStatus == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1099            serializer.attribute(null, "installStatus", "false");
1100        }
1101        if (pkg.installerPackageName != null) {
1102            serializer.attribute(null, "installer", pkg.installerPackageName);
1103        }
1104        pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
1105        if ((pkg.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1106            serializer.startTag(null, "perms");
1107            if (pkg.sharedUser == null) {
1108                // If this is a shared user, the permissions will
1109                // be written there. We still need to write an
1110                // empty permissions list so permissionsFixed will
1111                // be set.
1112                for (final String name : pkg.grantedPermissions) {
1113                    serializer.startTag(null, "item");
1114                    serializer.attribute(null, "name", name);
1115                    serializer.endTag(null, "item");
1116                }
1117            }
1118            serializer.endTag(null, "perms");
1119        }
1120        if (pkg.disabledComponents.size() > 0) {
1121            serializer.startTag(null, "disabled-components");
1122            for (final String name : pkg.disabledComponents) {
1123                serializer.startTag(null, "item");
1124                serializer.attribute(null, "name", name);
1125                serializer.endTag(null, "item");
1126            }
1127            serializer.endTag(null, "disabled-components");
1128        }
1129        if (pkg.enabledComponents.size() > 0) {
1130            serializer.startTag(null, "enabled-components");
1131            for (final String name : pkg.enabledComponents) {
1132                serializer.startTag(null, "item");
1133                serializer.attribute(null, "name", name);
1134                serializer.endTag(null, "item");
1135            }
1136            serializer.endTag(null, "enabled-components");
1137        }
1138
1139        serializer.endTag(null, "package");
1140    }
1141
1142    void writePermissionLPr(XmlSerializer serializer, BasePermission bp)
1143            throws XmlPullParserException, java.io.IOException {
1144        if (bp.type != BasePermission.TYPE_BUILTIN && bp.sourcePackage != null) {
1145            serializer.startTag(null, "item");
1146            serializer.attribute(null, "name", bp.name);
1147            serializer.attribute(null, "package", bp.sourcePackage);
1148            if (bp.protectionLevel != PermissionInfo.PROTECTION_NORMAL) {
1149                serializer.attribute(null, "protection", Integer.toString(bp.protectionLevel));
1150            }
1151            if (PackageManagerService.DEBUG_SETTINGS)
1152                Log.v(PackageManagerService.TAG, "Writing perm: name=" + bp.name + " type="
1153                        + bp.type);
1154            if (bp.type == BasePermission.TYPE_DYNAMIC) {
1155                final PermissionInfo pi = bp.perm != null ? bp.perm.info : bp.pendingInfo;
1156                if (pi != null) {
1157                    serializer.attribute(null, "type", "dynamic");
1158                    if (pi.icon != 0) {
1159                        serializer.attribute(null, "icon", Integer.toString(pi.icon));
1160                    }
1161                    if (pi.nonLocalizedLabel != null) {
1162                        serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
1163                    }
1164                }
1165            }
1166            serializer.endTag(null, "item");
1167        }
1168    }
1169
1170    ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() {
1171        final HashSet<String> kList = new HashSet<String>(mPackages.keySet());
1172        final Iterator<String> its = kList.iterator();
1173        final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>();
1174        while (its.hasNext()) {
1175            final String key = its.next();
1176            final PackageSetting ps = mPackages.get(key);
1177            if (ps.getInstallStatus() == PackageSettingBase.PKG_INSTALL_INCOMPLETE) {
1178                ret.add(ps);
1179            }
1180        }
1181        return ret;
1182    }
1183
1184    boolean readLPw() {
1185        FileInputStream str = null;
1186        if (mBackupSettingsFilename.exists()) {
1187            try {
1188                str = new FileInputStream(mBackupSettingsFilename);
1189                mReadMessages.append("Reading from backup settings file\n");
1190                PackageManagerService.reportSettingsProblem(Log.INFO,
1191                        "Need to read from backup settings file");
1192                if (mSettingsFilename.exists()) {
1193                    // If both the backup and settings file exist, we
1194                    // ignore the settings since it might have been
1195                    // corrupted.
1196                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
1197                            + mSettingsFilename);
1198                    mSettingsFilename.delete();
1199                }
1200            } catch (java.io.IOException e) {
1201                // We'll try for the normal settings file.
1202            }
1203        }
1204
1205        mPendingPackages.clear();
1206        mPastSignatures.clear();
1207
1208        try {
1209            if (str == null) {
1210                if (!mSettingsFilename.exists()) {
1211                    mReadMessages.append("No settings file found\n");
1212                    PackageManagerService.reportSettingsProblem(Log.INFO,
1213                            "No settings file; creating initial state");
1214                    return false;
1215                }
1216                str = new FileInputStream(mSettingsFilename);
1217            }
1218            XmlPullParser parser = Xml.newPullParser();
1219            parser.setInput(str, null);
1220
1221            int type;
1222            while ((type = parser.next()) != XmlPullParser.START_TAG
1223                    && type != XmlPullParser.END_DOCUMENT) {
1224                ;
1225            }
1226
1227            if (type != XmlPullParser.START_TAG) {
1228                mReadMessages.append("No start tag found in settings file\n");
1229                PackageManagerService.reportSettingsProblem(Log.WARN,
1230                        "No start tag found in package manager settings");
1231                Log
1232                        .wtf(PackageManagerService.TAG,
1233                                "No start tag found in package manager settings");
1234                return false;
1235            }
1236
1237            int outerDepth = parser.getDepth();
1238            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1239                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1240                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1241                    continue;
1242                }
1243
1244                String tagName = parser.getName();
1245                if (tagName.equals("package")) {
1246                    readPackageLPw(parser);
1247                } else if (tagName.equals("permissions")) {
1248                    readPermissionsLPw(mPermissions, parser);
1249                } else if (tagName.equals("permission-trees")) {
1250                    readPermissionsLPw(mPermissionTrees, parser);
1251                } else if (tagName.equals("shared-user")) {
1252                    readSharedUserLPw(parser);
1253                } else if (tagName.equals("preferred-packages")) {
1254                    // no longer used.
1255                } else if (tagName.equals("preferred-activities")) {
1256                    readPreferredActivitiesLPw(parser);
1257                } else if (tagName.equals("updated-package")) {
1258                    readDisabledSysPackageLPw(parser);
1259                } else if (tagName.equals("cleaning-package")) {
1260                    String name = parser.getAttributeValue(null, "name");
1261                    if (name != null) {
1262                        mPackagesToBeCleaned.add(name);
1263                    }
1264                } else if (tagName.equals("renamed-package")) {
1265                    String nname = parser.getAttributeValue(null, "new");
1266                    String oname = parser.getAttributeValue(null, "old");
1267                    if (nname != null && oname != null) {
1268                        mRenamedPackages.put(nname, oname);
1269                    }
1270                } else if (tagName.equals("last-platform-version")) {
1271                    mInternalSdkPlatform = mExternalSdkPlatform = 0;
1272                    try {
1273                        String internal = parser.getAttributeValue(null, "internal");
1274                        if (internal != null) {
1275                            mInternalSdkPlatform = Integer.parseInt(internal);
1276                        }
1277                        String external = parser.getAttributeValue(null, "external");
1278                        if (external != null) {
1279                            mExternalSdkPlatform = Integer.parseInt(external);
1280                        }
1281                    } catch (NumberFormatException e) {
1282                    }
1283                } else {
1284                    Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
1285                            + parser.getName());
1286                    XmlUtils.skipCurrentTag(parser);
1287                }
1288            }
1289
1290            str.close();
1291
1292        } catch (XmlPullParserException e) {
1293            mReadMessages.append("Error reading: " + e.toString());
1294            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1295            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1296
1297        } catch (java.io.IOException e) {
1298            mReadMessages.append("Error reading: " + e.toString());
1299            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
1300            Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
1301
1302        }
1303
1304        final int N = mPendingPackages.size();
1305        for (int i = 0; i < N; i++) {
1306            final PendingPackage pp = mPendingPackages.get(i);
1307            Object idObj = getUserIdLPr(pp.sharedId);
1308            if (idObj != null && idObj instanceof SharedUserSetting) {
1309                PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
1310                        (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
1311                        pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags, true, true);
1312                if (p == null) {
1313                    PackageManagerService.reportSettingsProblem(Log.WARN,
1314                            "Unable to create application package for " + pp.name);
1315                    continue;
1316                }
1317                p.copyFrom(pp);
1318            } else if (idObj != null) {
1319                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1320                        + pp.sharedId + " that is not a shared uid\n";
1321                mReadMessages.append(msg);
1322                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1323            } else {
1324                String msg = "Bad package setting: package " + pp.name + " has shared uid "
1325                        + pp.sharedId + " that is not defined\n";
1326                mReadMessages.append(msg);
1327                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
1328            }
1329        }
1330        mPendingPackages.clear();
1331
1332        /*
1333         * Make sure all the updated system packages have their shared users
1334         * associated with them.
1335         */
1336        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
1337        while (disabledIt.hasNext()) {
1338            final PackageSetting disabledPs = disabledIt.next();
1339            final Object id = getUserIdLPr(disabledPs.userId);
1340            if (id != null && id instanceof SharedUserSetting) {
1341                disabledPs.sharedUser = (SharedUserSetting) id;
1342            }
1343        }
1344
1345        readStoppedLPw();
1346
1347        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
1348                + mSharedUsers.size() + " shared uids\n");
1349
1350        return true;
1351    }
1352
1353    private int readInt(XmlPullParser parser, String ns, String name, int defValue) {
1354        String v = parser.getAttributeValue(ns, name);
1355        try {
1356            if (v == null) {
1357                return defValue;
1358            }
1359            return Integer.parseInt(v);
1360        } catch (NumberFormatException e) {
1361            PackageManagerService.reportSettingsProblem(Log.WARN,
1362                    "Error in package manager settings: attribute " + name
1363                            + " has bad integer value " + v + " at "
1364                            + parser.getPositionDescription());
1365        }
1366        return defValue;
1367    }
1368
1369    private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser)
1370            throws IOException, XmlPullParserException {
1371        int outerDepth = parser.getDepth();
1372        int type;
1373        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1374                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1375            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1376                continue;
1377            }
1378
1379            final String tagName = parser.getName();
1380            if (tagName.equals("item")) {
1381                final String name = parser.getAttributeValue(null, "name");
1382                final String sourcePackage = parser.getAttributeValue(null, "package");
1383                final String ptype = parser.getAttributeValue(null, "type");
1384                if (name != null && sourcePackage != null) {
1385                    final boolean dynamic = "dynamic".equals(ptype);
1386                    final BasePermission bp = new BasePermission(name, sourcePackage,
1387                            dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
1388                    bp.protectionLevel = readInt(parser, null, "protection",
1389                            PermissionInfo.PROTECTION_NORMAL);
1390                    if (dynamic) {
1391                        PermissionInfo pi = new PermissionInfo();
1392                        pi.packageName = sourcePackage.intern();
1393                        pi.name = name.intern();
1394                        pi.icon = readInt(parser, null, "icon", 0);
1395                        pi.nonLocalizedLabel = parser.getAttributeValue(null, "label");
1396                        pi.protectionLevel = bp.protectionLevel;
1397                        bp.pendingInfo = pi;
1398                    }
1399                    out.put(bp.name, bp);
1400                } else {
1401                    PackageManagerService.reportSettingsProblem(Log.WARN,
1402                            "Error in package manager settings: permissions has" + " no name at "
1403                                    + parser.getPositionDescription());
1404                }
1405            } else {
1406                PackageManagerService.reportSettingsProblem(Log.WARN,
1407                        "Unknown element reading permissions: " + parser.getName() + " at "
1408                                + parser.getPositionDescription());
1409            }
1410            XmlUtils.skipCurrentTag(parser);
1411        }
1412    }
1413
1414    private void readDisabledSysPackageLPw(XmlPullParser parser) throws XmlPullParserException,
1415            IOException {
1416        String name = parser.getAttributeValue(null, "name");
1417        String realName = parser.getAttributeValue(null, "realName");
1418        String codePathStr = parser.getAttributeValue(null, "codePath");
1419        String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1420        String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1421        if (resourcePathStr == null) {
1422            resourcePathStr = codePathStr;
1423        }
1424        String version = parser.getAttributeValue(null, "version");
1425        int versionCode = 0;
1426        if (version != null) {
1427            try {
1428                versionCode = Integer.parseInt(version);
1429            } catch (NumberFormatException e) {
1430            }
1431        }
1432
1433        int pkgFlags = 0;
1434        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1435        PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
1436                new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
1437        String timeStampStr = parser.getAttributeValue(null, "ft");
1438        if (timeStampStr != null) {
1439            try {
1440                long timeStamp = Long.parseLong(timeStampStr, 16);
1441                ps.setTimeStamp(timeStamp);
1442            } catch (NumberFormatException e) {
1443            }
1444        } else {
1445            timeStampStr = parser.getAttributeValue(null, "ts");
1446            if (timeStampStr != null) {
1447                try {
1448                    long timeStamp = Long.parseLong(timeStampStr);
1449                    ps.setTimeStamp(timeStamp);
1450                } catch (NumberFormatException e) {
1451                }
1452            }
1453        }
1454        timeStampStr = parser.getAttributeValue(null, "it");
1455        if (timeStampStr != null) {
1456            try {
1457                ps.firstInstallTime = Long.parseLong(timeStampStr, 16);
1458            } catch (NumberFormatException e) {
1459            }
1460        }
1461        timeStampStr = parser.getAttributeValue(null, "ut");
1462        if (timeStampStr != null) {
1463            try {
1464                ps.lastUpdateTime = Long.parseLong(timeStampStr, 16);
1465            } catch (NumberFormatException e) {
1466            }
1467        }
1468        String idStr = parser.getAttributeValue(null, "userId");
1469        ps.userId = idStr != null ? Integer.parseInt(idStr) : 0;
1470        if (ps.userId <= 0) {
1471            String sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1472            ps.userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1473        }
1474        int outerDepth = parser.getDepth();
1475        int type;
1476        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1477                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1478            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1479                continue;
1480            }
1481
1482            String tagName = parser.getName();
1483            if (tagName.equals("perms")) {
1484                readGrantedPermissionsLPw(parser, ps.grantedPermissions);
1485            } else {
1486                PackageManagerService.reportSettingsProblem(Log.WARN,
1487                        "Unknown element under <updated-package>: " + parser.getName());
1488                XmlUtils.skipCurrentTag(parser);
1489            }
1490        }
1491        mDisabledSysPackages.put(name, ps);
1492    }
1493
1494    private void readPackageLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
1495        String name = null;
1496        String realName = null;
1497        String idStr = null;
1498        String sharedIdStr = null;
1499        String codePathStr = null;
1500        String resourcePathStr = null;
1501        String nativeLibraryPathStr = null;
1502        String systemStr = null;
1503        String installerPackageName = null;
1504        String uidError = null;
1505        int pkgFlags = 0;
1506        long timeStamp = 0;
1507        long firstInstallTime = 0;
1508        long lastUpdateTime = 0;
1509        PackageSettingBase packageSetting = null;
1510        String version = null;
1511        int versionCode = 0;
1512        try {
1513            name = parser.getAttributeValue(null, "name");
1514            realName = parser.getAttributeValue(null, "realName");
1515            idStr = parser.getAttributeValue(null, "userId");
1516            uidError = parser.getAttributeValue(null, "uidError");
1517            sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
1518            codePathStr = parser.getAttributeValue(null, "codePath");
1519            resourcePathStr = parser.getAttributeValue(null, "resourcePath");
1520            nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
1521            version = parser.getAttributeValue(null, "version");
1522            if (version != null) {
1523                try {
1524                    versionCode = Integer.parseInt(version);
1525                } catch (NumberFormatException e) {
1526                }
1527            }
1528            installerPackageName = parser.getAttributeValue(null, "installer");
1529
1530            systemStr = parser.getAttributeValue(null, "flags");
1531            if (systemStr != null) {
1532                try {
1533                    pkgFlags = Integer.parseInt(systemStr);
1534                } catch (NumberFormatException e) {
1535                }
1536            } else {
1537                // For backward compatibility
1538                systemStr = parser.getAttributeValue(null, "system");
1539                if (systemStr != null) {
1540                    pkgFlags |= ("true".equalsIgnoreCase(systemStr)) ? ApplicationInfo.FLAG_SYSTEM
1541                            : 0;
1542                } else {
1543                    // Old settings that don't specify system... just treat
1544                    // them as system, good enough.
1545                    pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1546                }
1547            }
1548            String timeStampStr = parser.getAttributeValue(null, "ft");
1549            if (timeStampStr != null) {
1550                try {
1551                    timeStamp = Long.parseLong(timeStampStr, 16);
1552                } catch (NumberFormatException e) {
1553                }
1554            } else {
1555                timeStampStr = parser.getAttributeValue(null, "ts");
1556                if (timeStampStr != null) {
1557                    try {
1558                        timeStamp = Long.parseLong(timeStampStr);
1559                    } catch (NumberFormatException e) {
1560                    }
1561                }
1562            }
1563            timeStampStr = parser.getAttributeValue(null, "it");
1564            if (timeStampStr != null) {
1565                try {
1566                    firstInstallTime = Long.parseLong(timeStampStr, 16);
1567                } catch (NumberFormatException e) {
1568                }
1569            }
1570            timeStampStr = parser.getAttributeValue(null, "ut");
1571            if (timeStampStr != null) {
1572                try {
1573                    lastUpdateTime = Long.parseLong(timeStampStr, 16);
1574                } catch (NumberFormatException e) {
1575                }
1576            }
1577            if (PackageManagerService.DEBUG_SETTINGS)
1578                Log.v(PackageManagerService.TAG, "Reading package: " + name + " userId=" + idStr
1579                        + " sharedUserId=" + sharedIdStr);
1580            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
1581            if (resourcePathStr == null) {
1582                resourcePathStr = codePathStr;
1583            }
1584            if (realName != null) {
1585                realName = realName.intern();
1586            }
1587            if (name == null) {
1588                PackageManagerService.reportSettingsProblem(Log.WARN,
1589                        "Error in package manager settings: <package> has no name at "
1590                                + parser.getPositionDescription());
1591            } else if (codePathStr == null) {
1592                PackageManagerService.reportSettingsProblem(Log.WARN,
1593                        "Error in package manager settings: <package> has no codePath at "
1594                                + parser.getPositionDescription());
1595            } else if (userId > 0) {
1596                packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
1597                        new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
1598                        pkgFlags);
1599                if (PackageManagerService.DEBUG_SETTINGS)
1600                    Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
1601                            + userId + " pkg=" + packageSetting);
1602                if (packageSetting == null) {
1603                    PackageManagerService.reportSettingsProblem(Log.ERROR, "Failure adding uid "
1604                            + userId + " while parsing settings at "
1605                            + parser.getPositionDescription());
1606                } else {
1607                    packageSetting.setTimeStamp(timeStamp);
1608                    packageSetting.firstInstallTime = firstInstallTime;
1609                    packageSetting.lastUpdateTime = lastUpdateTime;
1610                }
1611            } else if (sharedIdStr != null) {
1612                userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
1613                if (userId > 0) {
1614                    packageSetting = new PendingPackage(name.intern(), realName, new File(
1615                            codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
1616                            versionCode, pkgFlags);
1617                    packageSetting.setTimeStamp(timeStamp);
1618                    packageSetting.firstInstallTime = firstInstallTime;
1619                    packageSetting.lastUpdateTime = lastUpdateTime;
1620                    mPendingPackages.add((PendingPackage) packageSetting);
1621                    if (PackageManagerService.DEBUG_SETTINGS)
1622                        Log.i(PackageManagerService.TAG, "Reading package " + name
1623                                + ": sharedUserId=" + userId + " pkg=" + packageSetting);
1624                } else {
1625                    PackageManagerService.reportSettingsProblem(Log.WARN,
1626                            "Error in package manager settings: package " + name
1627                                    + " has bad sharedId " + sharedIdStr + " at "
1628                                    + parser.getPositionDescription());
1629                }
1630            } else {
1631                PackageManagerService.reportSettingsProblem(Log.WARN,
1632                        "Error in package manager settings: package " + name + " has bad userId "
1633                                + idStr + " at " + parser.getPositionDescription());
1634            }
1635        } catch (NumberFormatException e) {
1636            PackageManagerService.reportSettingsProblem(Log.WARN,
1637                    "Error in package manager settings: package " + name + " has bad userId "
1638                            + idStr + " at " + parser.getPositionDescription());
1639        }
1640        if (packageSetting != null) {
1641            packageSetting.uidError = "true".equals(uidError);
1642            packageSetting.installerPackageName = installerPackageName;
1643            packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
1644            final String enabledStr = parser.getAttributeValue(null, "enabled");
1645            if (enabledStr != null) {
1646                try {
1647                    packageSetting.enabled = Integer.parseInt(enabledStr);
1648                } catch (NumberFormatException e) {
1649                    if (enabledStr.equalsIgnoreCase("true")) {
1650                        packageSetting.enabled = COMPONENT_ENABLED_STATE_ENABLED;
1651                    } else if (enabledStr.equalsIgnoreCase("false")) {
1652                        packageSetting.enabled = COMPONENT_ENABLED_STATE_DISABLED;
1653                    } else if (enabledStr.equalsIgnoreCase("default")) {
1654                        packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
1655                    } else {
1656                        PackageManagerService.reportSettingsProblem(Log.WARN,
1657                                "Error in package manager settings: package " + name
1658                                        + " has bad enabled value: " + idStr + " at "
1659                                        + parser.getPositionDescription());
1660                    }
1661                }
1662            } else {
1663                packageSetting.enabled = COMPONENT_ENABLED_STATE_DEFAULT;
1664            }
1665            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
1666            if (installStatusStr != null) {
1667                if (installStatusStr.equalsIgnoreCase("false")) {
1668                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_INCOMPLETE;
1669                } else {
1670                    packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
1671                }
1672            }
1673
1674            int outerDepth = parser.getDepth();
1675            int type;
1676            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1677                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1678                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1679                    continue;
1680                }
1681
1682                String tagName = parser.getName();
1683                if (tagName.equals("disabled-components")) {
1684                    readDisabledComponentsLPw(packageSetting, parser);
1685                } else if (tagName.equals("enabled-components")) {
1686                    readEnabledComponentsLPw(packageSetting, parser);
1687                } else if (tagName.equals("sigs")) {
1688                    packageSetting.signatures.readXml(parser, mPastSignatures);
1689                } else if (tagName.equals("perms")) {
1690                    readGrantedPermissionsLPw(parser, packageSetting.grantedPermissions);
1691                    packageSetting.permissionsFixed = true;
1692                } else {
1693                    PackageManagerService.reportSettingsProblem(Log.WARN,
1694                            "Unknown element under <package>: " + parser.getName());
1695                    XmlUtils.skipCurrentTag(parser);
1696                }
1697            }
1698        } else {
1699            XmlUtils.skipCurrentTag(parser);
1700        }
1701    }
1702
1703    private void readDisabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)
1704            throws IOException, XmlPullParserException {
1705        int outerDepth = parser.getDepth();
1706        int type;
1707        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1708                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1709            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1710                continue;
1711            }
1712
1713            String tagName = parser.getName();
1714            if (tagName.equals("item")) {
1715                String name = parser.getAttributeValue(null, "name");
1716                if (name != null) {
1717                    packageSetting.disabledComponents.add(name.intern());
1718                } else {
1719                    PackageManagerService.reportSettingsProblem(Log.WARN,
1720                            "Error in package manager settings: <disabled-components> has"
1721                                    + " no name at " + parser.getPositionDescription());
1722                }
1723            } else {
1724                PackageManagerService.reportSettingsProblem(Log.WARN,
1725                        "Unknown element under <disabled-components>: " + parser.getName());
1726            }
1727            XmlUtils.skipCurrentTag(parser);
1728        }
1729    }
1730
1731    private void readEnabledComponentsLPw(PackageSettingBase packageSetting, XmlPullParser parser)
1732            throws IOException, XmlPullParserException {
1733        int outerDepth = parser.getDepth();
1734        int type;
1735        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1736                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1737            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1738                continue;
1739            }
1740
1741            String tagName = parser.getName();
1742            if (tagName.equals("item")) {
1743                String name = parser.getAttributeValue(null, "name");
1744                if (name != null) {
1745                    packageSetting.enabledComponents.add(name.intern());
1746                } else {
1747                    PackageManagerService.reportSettingsProblem(Log.WARN,
1748                            "Error in package manager settings: <enabled-components> has"
1749                                    + " no name at " + parser.getPositionDescription());
1750                }
1751            } else {
1752                PackageManagerService.reportSettingsProblem(Log.WARN,
1753                        "Unknown element under <enabled-components>: " + parser.getName());
1754            }
1755            XmlUtils.skipCurrentTag(parser);
1756        }
1757    }
1758
1759    private void readSharedUserLPw(XmlPullParser parser) throws XmlPullParserException, IOException {
1760        String name = null;
1761        String idStr = null;
1762        int pkgFlags = 0;
1763        SharedUserSetting su = null;
1764        try {
1765            name = parser.getAttributeValue(null, "name");
1766            idStr = parser.getAttributeValue(null, "userId");
1767            int userId = idStr != null ? Integer.parseInt(idStr) : 0;
1768            if ("true".equals(parser.getAttributeValue(null, "system"))) {
1769                pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
1770            }
1771            if (name == null) {
1772                PackageManagerService.reportSettingsProblem(Log.WARN,
1773                        "Error in package manager settings: <shared-user> has no name at "
1774                                + parser.getPositionDescription());
1775            } else if (userId == 0) {
1776                PackageManagerService.reportSettingsProblem(Log.WARN,
1777                        "Error in package manager settings: shared-user " + name
1778                                + " has bad userId " + idStr + " at "
1779                                + parser.getPositionDescription());
1780            } else {
1781                if ((su = addSharedUserLPw(name.intern(), userId, pkgFlags)) == null) {
1782                    PackageManagerService
1783                            .reportSettingsProblem(Log.ERROR, "Occurred while parsing settings at "
1784                                    + parser.getPositionDescription());
1785                }
1786            }
1787        } catch (NumberFormatException e) {
1788            PackageManagerService.reportSettingsProblem(Log.WARN,
1789                    "Error in package manager settings: package " + name + " has bad userId "
1790                            + idStr + " at " + parser.getPositionDescription());
1791        }
1792        ;
1793
1794        if (su != null) {
1795            int outerDepth = parser.getDepth();
1796            int type;
1797            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1798                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1799                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1800                    continue;
1801                }
1802
1803                String tagName = parser.getName();
1804                if (tagName.equals("sigs")) {
1805                    su.signatures.readXml(parser, mPastSignatures);
1806                } else if (tagName.equals("perms")) {
1807                    readGrantedPermissionsLPw(parser, su.grantedPermissions);
1808                } else {
1809                    PackageManagerService.reportSettingsProblem(Log.WARN,
1810                            "Unknown element under <shared-user>: " + parser.getName());
1811                    XmlUtils.skipCurrentTag(parser);
1812                }
1813            }
1814
1815        } else {
1816            XmlUtils.skipCurrentTag(parser);
1817        }
1818    }
1819
1820    private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms)
1821            throws IOException, XmlPullParserException {
1822        int outerDepth = parser.getDepth();
1823        int type;
1824        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1825                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1826            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1827                continue;
1828            }
1829
1830            String tagName = parser.getName();
1831            if (tagName.equals("item")) {
1832                String name = parser.getAttributeValue(null, "name");
1833                if (name != null) {
1834                    outPerms.add(name.intern());
1835                } else {
1836                    PackageManagerService.reportSettingsProblem(Log.WARN,
1837                            "Error in package manager settings: <perms> has" + " no name at "
1838                                    + parser.getPositionDescription());
1839                }
1840            } else {
1841                PackageManagerService.reportSettingsProblem(Log.WARN,
1842                        "Unknown element under <perms>: " + parser.getName());
1843            }
1844            XmlUtils.skipCurrentTag(parser);
1845        }
1846    }
1847
1848    private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException,
1849            IOException {
1850        int outerDepth = parser.getDepth();
1851        int type;
1852        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
1853                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
1854            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
1855                continue;
1856            }
1857
1858            String tagName = parser.getName();
1859            if (tagName.equals("item")) {
1860                PreferredActivity pa = new PreferredActivity(parser);
1861                if (pa.mPref.getParseError() == null) {
1862                    mPreferredActivities.addFilter(pa);
1863                } else {
1864                    PackageManagerService.reportSettingsProblem(Log.WARN,
1865                            "Error in package manager settings: <preferred-activity> "
1866                                    + pa.mPref.getParseError() + " at "
1867                                    + parser.getPositionDescription());
1868                }
1869            } else {
1870                PackageManagerService.reportSettingsProblem(Log.WARN,
1871                        "Unknown element under <preferred-activities>: " + parser.getName());
1872                XmlUtils.skipCurrentTag(parser);
1873            }
1874        }
1875    }
1876
1877    // Returns -1 if we could not find an available UserId to assign
1878    private int newUserIdLPw(Object obj) {
1879        // Let's be stupidly inefficient for now...
1880        final int N = mUserIds.size();
1881        for (int i = 0; i < N; i++) {
1882            if (mUserIds.get(i) == null) {
1883                mUserIds.set(i, obj);
1884                return PackageManagerService.FIRST_APPLICATION_UID + i;
1885            }
1886        }
1887
1888        // None left?
1889        if (N >= PackageManagerService.MAX_APPLICATION_UIDS) {
1890            return -1;
1891        }
1892
1893        mUserIds.add(obj);
1894        return PackageManagerService.FIRST_APPLICATION_UID + N;
1895    }
1896
1897    public PackageSetting getDisabledSystemPkgLPr(String name) {
1898        PackageSetting ps = mDisabledSysPackages.get(name);
1899        return ps;
1900    }
1901
1902    boolean isEnabledLPr(ComponentInfo componentInfo, int flags) {
1903        if ((flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
1904            return true;
1905        }
1906        final PackageSetting packageSettings = mPackages.get(componentInfo.packageName);
1907        if (PackageManagerService.DEBUG_SETTINGS) {
1908            Log.v(PackageManagerService.TAG, "isEnabledLock - packageName = " + componentInfo.packageName
1909                       + " componentName = " + componentInfo.name);
1910            Log.v(PackageManagerService.TAG, "enabledComponents: "
1911                       + Arrays.toString(packageSettings.enabledComponents.toArray()));
1912            Log.v(PackageManagerService.TAG, "disabledComponents: "
1913                       + Arrays.toString(packageSettings.disabledComponents.toArray()));
1914        }
1915        if (packageSettings == null) {
1916            return false;
1917        }
1918        if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED
1919                || packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
1920                || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
1921                        && packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
1922            return false;
1923        }
1924        if (packageSettings.enabledComponents.contains(componentInfo.name)) {
1925            return true;
1926        }
1927        if (packageSettings.disabledComponents.contains(componentInfo.name)) {
1928            return false;
1929        }
1930        return componentInfo.enabled;
1931    }
1932
1933    String getInstallerPackageNameLPr(String packageName) {
1934        final PackageSetting pkg = mPackages.get(packageName);
1935        if (pkg == null) {
1936            throw new IllegalArgumentException("Unknown package: " + packageName);
1937        }
1938        return pkg.installerPackageName;
1939    }
1940
1941    int getApplicationEnabledSettingLPr(String packageName) {
1942        final PackageSetting pkg = mPackages.get(packageName);
1943        if (pkg == null) {
1944            throw new IllegalArgumentException("Unknown package: " + packageName);
1945        }
1946        return pkg.enabled;
1947    }
1948
1949    int getComponentEnabledSettingLPr(ComponentName componentName) {
1950        final String packageName = componentName.getPackageName();
1951        final PackageSetting pkg = mPackages.get(packageName);
1952        if (pkg == null) {
1953            throw new IllegalArgumentException("Unknown component: " + componentName);
1954        }
1955        final String classNameStr = componentName.getClassName();
1956        return pkg.getCurrentEnabledStateLPr(classNameStr);
1957    }
1958
1959    boolean setPackageStoppedStateLPw(String packageName, boolean stopped,
1960            boolean allowedByPermission, int uid) {
1961        final PackageSetting pkgSetting = mPackages.get(packageName);
1962        if (pkgSetting == null) {
1963            throw new IllegalArgumentException("Unknown package: " + packageName);
1964        }
1965        if (!allowedByPermission && (uid != pkgSetting.userId)) {
1966            throw new SecurityException(
1967                    "Permission Denial: attempt to change stopped state from pid="
1968                    + Binder.getCallingPid()
1969                    + ", uid=" + uid + ", package uid=" + pkgSetting.userId);
1970        }
1971        if (DEBUG_STOPPED) {
1972            if (stopped) {
1973                RuntimeException e = new RuntimeException("here");
1974                e.fillInStackTrace();
1975                Slog.i(TAG, "Stopping package " + packageName, e);
1976            }
1977        }
1978        if (pkgSetting.stopped != stopped) {
1979            pkgSetting.stopped = stopped;
1980            pkgSetting.pkg.mSetStopped = stopped;
1981            if (pkgSetting.notLaunched) {
1982                if (pkgSetting.installerPackageName != null) {
1983                    PackageManagerService.sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH,
1984                            pkgSetting.name, null,
1985                            pkgSetting.installerPackageName, null);
1986                }
1987                pkgSetting.notLaunched = false;
1988            }
1989            return true;
1990        }
1991        return false;
1992    }
1993
1994    void dumpPackagesLPr(PrintWriter pw, String packageName, DumpState dumpState) {
1995        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1996        final Date date = new Date();
1997        boolean printedSomething = false;
1998        for (final PackageSetting ps : mPackages.values()) {
1999            if (packageName != null && !packageName.equals(ps.realName)
2000                    && !packageName.equals(ps.name)) {
2001                continue;
2002            }
2003
2004            if (packageName != null) {
2005                dumpState.setSharedUser(ps.sharedUser);
2006            }
2007
2008            if (!printedSomething) {
2009                if (dumpState.onTitlePrinted())
2010                    pw.println(" ");
2011                pw.println("Packages:");
2012                printedSomething = true;
2013            }
2014            pw.print("  Package [");
2015                pw.print(ps.realName != null ? ps.realName : ps.name);
2016                pw.print("] (");
2017                pw.print(Integer.toHexString(System.identityHashCode(ps)));
2018                pw.println("):");
2019
2020            if (ps.realName != null) {
2021                pw.print("    compat name=");
2022                pw.println(ps.name);
2023            }
2024
2025            pw.print("    userId="); pw.print(ps.userId);
2026            pw.print(" gids="); pw.println(PackageManagerService.arrayToString(ps.gids));
2027            pw.print("    sharedUser="); pw.println(ps.sharedUser);
2028            pw.print("    pkg="); pw.println(ps.pkg);
2029            pw.print("    codePath="); pw.println(ps.codePathString);
2030            pw.print("    resourcePath="); pw.println(ps.resourcePathString);
2031            pw.print("    nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
2032            pw.print("    versionCode="); pw.println(ps.versionCode);
2033            if (ps.pkg != null) {
2034                pw.print("    versionName="); pw.println(ps.pkg.mVersionName);
2035                pw.print("    dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
2036                pw.print("    targetSdk="); pw.println(ps.pkg.applicationInfo.targetSdkVersion);
2037                if (ps.pkg.mOperationPending) {
2038                    pw.println("    mOperationPending=true");
2039                }
2040                pw.print("    supportsScreens=[");
2041                boolean first = true;
2042                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
2043                    if (!first)
2044                        pw.print(", ");
2045                    first = false;
2046                    pw.print("small");
2047                }
2048                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
2049                    if (!first)
2050                        pw.print(", ");
2051                    first = false;
2052                    pw.print("medium");
2053                }
2054                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
2055                    if (!first)
2056                        pw.print(", ");
2057                    first = false;
2058                    pw.print("large");
2059                }
2060                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
2061                    if (!first)
2062                        pw.print(", ");
2063                    first = false;
2064                    pw.print("xlarge");
2065                }
2066                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
2067                    if (!first)
2068                        pw.print(", ");
2069                    first = false;
2070                    pw.print("resizeable");
2071                }
2072                if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
2073                    if (!first)
2074                        pw.print(", ");
2075                    first = false;
2076                    pw.print("anyDensity");
2077                }
2078            }
2079            pw.println("]");
2080            pw.print("    timeStamp=");
2081                date.setTime(ps.timeStamp);
2082                pw.println(sdf.format(date));
2083            pw.print("    firstInstallTime=");
2084                date.setTime(ps.firstInstallTime);
2085                pw.println(sdf.format(date));
2086            pw.print("    lastUpdateTime=");
2087                date.setTime(ps.lastUpdateTime);
2088                pw.println(sdf.format(date));
2089            if (ps.installerPackageName != null) {
2090                pw.print("    installerPackageName="); pw.println(ps.installerPackageName);
2091            }
2092            pw.print("    signatures="); pw.println(ps.signatures);
2093            pw.print("    permissionsFixed="); pw.print(ps.permissionsFixed);
2094            pw.print(" haveGids="); pw.println(ps.haveGids);
2095            pw.print("    pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
2096            pw.print(" installStatus="); pw.print(ps.installStatus);
2097            pw.print(" stopped="); pw.print(ps.stopped);
2098            pw.print(" enabled="); pw.println(ps.enabled);
2099            if (ps.disabledComponents.size() > 0) {
2100                pw.println("    disabledComponents:");
2101                for (String s : ps.disabledComponents) {
2102                    pw.print("      "); pw.println(s);
2103                }
2104            }
2105            if (ps.enabledComponents.size() > 0) {
2106                pw.println("    enabledComponents:");
2107                for (String s : ps.enabledComponents) {
2108                    pw.print("      "); pw.println(s);
2109                }
2110            }
2111            if (ps.grantedPermissions.size() > 0) {
2112                pw.println("    grantedPermissions:");
2113                for (String s : ps.grantedPermissions) {
2114                    pw.print("      "); pw.println(s);
2115                }
2116            }
2117        }
2118
2119        printedSomething = false;
2120        if (mRenamedPackages.size() > 0) {
2121            for (final HashMap.Entry<String, String> e : mRenamedPackages.entrySet()) {
2122                if (packageName != null && !packageName.equals(e.getKey())
2123                        && !packageName.equals(e.getValue())) {
2124                    continue;
2125                }
2126                if (!printedSomething) {
2127                    if (dumpState.onTitlePrinted())
2128                        pw.println(" ");
2129                    pw.println("Renamed packages:");
2130                    printedSomething = true;
2131                }
2132                pw.print("  ");
2133                pw.print(e.getKey());
2134                pw.print(" -> ");
2135                pw.println(e.getValue());
2136            }
2137        }
2138
2139        printedSomething = false;
2140        if (mDisabledSysPackages.size() > 0) {
2141            for (final PackageSetting ps : mDisabledSysPackages.values()) {
2142                if (packageName != null && !packageName.equals(ps.realName)
2143                        && !packageName.equals(ps.name)) {
2144                    continue;
2145                }
2146                if (!printedSomething) {
2147                    if (dumpState.onTitlePrinted())
2148                        pw.println(" ");
2149                    pw.println("Hidden system packages:");
2150                    printedSomething = true;
2151                }
2152                pw.print("  Package [");
2153                pw.print(ps.realName != null ? ps.realName : ps.name);
2154                pw.print("] (");
2155                pw.print(Integer.toHexString(System.identityHashCode(ps)));
2156                pw.println("):");
2157                if (ps.realName != null) {
2158                    pw.print("    compat name=");
2159                    pw.println(ps.name);
2160                }
2161                pw.print("    userId=");
2162                pw.println(ps.userId);
2163                pw.print("    sharedUser=");
2164                pw.println(ps.sharedUser);
2165                pw.print("    codePath=");
2166                pw.println(ps.codePathString);
2167                pw.print("    resourcePath=");
2168                pw.println(ps.resourcePathString);
2169            }
2170        }
2171    }
2172
2173    void dumpPermissionsLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2174        boolean printedSomething = false;
2175        for (BasePermission p : mPermissions.values()) {
2176            if (packageName != null && !packageName.equals(p.sourcePackage)) {
2177                continue;
2178            }
2179            if (!printedSomething) {
2180                if (dumpState.onTitlePrinted())
2181                    pw.println(" ");
2182                pw.println("Permissions:");
2183                printedSomething = true;
2184            }
2185            pw.print("  Permission ["); pw.print(p.name); pw.print("] (");
2186                    pw.print(Integer.toHexString(System.identityHashCode(p)));
2187                    pw.println("):");
2188            pw.print("    sourcePackage="); pw.println(p.sourcePackage);
2189            pw.print("    uid="); pw.print(p.uid);
2190                    pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
2191                    pw.print(" type="); pw.print(p.type);
2192                    pw.print(" prot="); pw.println(p.protectionLevel);
2193            if (p.packageSetting != null) {
2194                pw.print("    packageSetting="); pw.println(p.packageSetting);
2195            }
2196            if (p.perm != null) {
2197                pw.print("    perm="); pw.println(p.perm);
2198            }
2199        }
2200    }
2201
2202    void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
2203        boolean printedSomething = false;
2204        for (SharedUserSetting su : mSharedUsers.values()) {
2205            if (packageName != null && su != dumpState.getSharedUser()) {
2206                continue;
2207            }
2208            if (!printedSomething) {
2209                if (dumpState.onTitlePrinted())
2210                    pw.println(" ");
2211                pw.println("Shared users:");
2212                printedSomething = true;
2213            }
2214            pw.print("  SharedUser [");
2215            pw.print(su.name);
2216            pw.print("] (");
2217            pw.print(Integer.toHexString(System.identityHashCode(su)));
2218                    pw.println("):");
2219            pw.print("    userId=");
2220            pw.print(su.userId);
2221            pw.print(" gids=");
2222            pw.println(PackageManagerService.arrayToString(su.gids));
2223            pw.println("    grantedPermissions:");
2224            for (String s : su.grantedPermissions) {
2225                pw.print("      ");
2226                pw.println(s);
2227            }
2228        }
2229    }
2230
2231    void dumpReadMessagesLPr(PrintWriter pw, DumpState dumpState) {
2232        pw.println("Settings parse messages:");
2233        pw.print(mReadMessages.toString());
2234    }
2235}