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