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