PackageManagerService.java revision 893e097157c68d94dbcb22e21cbc8d3b39965670
1/*
2 * Copyright (C) 2006 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.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
27import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
28import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
35import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
36import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
37import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
38import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
40import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
41import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
42import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
46import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
47import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
48import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
50import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
51import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
53import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
54import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
55import static android.content.pm.PackageManager.INSTALL_INTERNAL;
56import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
62import static android.content.pm.PackageManager.MATCH_ALL;
63import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
65import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
66import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
67import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
68import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
69import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
70import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
71import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
72import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
73import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
74import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
75import static android.content.pm.PackageManager.PERMISSION_DENIED;
76import static android.content.pm.PackageManager.PERMISSION_GRANTED;
77import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
78import static android.content.pm.PackageParser.isApkFile;
79import static android.os.Process.PACKAGE_INFO_GID;
80import static android.os.Process.SYSTEM_UID;
81import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
82import static android.system.OsConstants.O_CREAT;
83import static android.system.OsConstants.O_RDWR;
84
85import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
86import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
87import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
88import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
89import static com.android.internal.util.ArrayUtils.appendInt;
90import static com.android.server.pm.Installer.DEXOPT_PUBLIC;
91import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
92import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
93import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
94import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
95import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
96import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
97import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter;
98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
100import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
101
102import android.Manifest;
103import android.annotation.NonNull;
104import android.annotation.Nullable;
105import android.app.ActivityManager;
106import android.app.ActivityManagerNative;
107import android.app.IActivityManager;
108import android.app.admin.DevicePolicyManagerInternal;
109import android.app.admin.IDevicePolicyManager;
110import android.app.admin.SecurityLog;
111import android.app.backup.IBackupManager;
112import android.content.BroadcastReceiver;
113import android.content.ComponentName;
114import android.content.Context;
115import android.content.IIntentReceiver;
116import android.content.Intent;
117import android.content.IntentFilter;
118import android.content.IntentSender;
119import android.content.IntentSender.SendIntentException;
120import android.content.ServiceConnection;
121import android.content.pm.ActivityInfo;
122import android.content.pm.ApplicationInfo;
123import android.content.pm.AppsQueryHelper;
124import android.content.pm.ComponentInfo;
125import android.content.pm.EphemeralApplicationInfo;
126import android.content.pm.EphemeralResolveInfo;
127import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo;
128import android.content.pm.FeatureInfo;
129import android.content.pm.IOnPermissionsChangeListener;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageDeleteObserver;
132import android.content.pm.IPackageDeleteObserver2;
133import android.content.pm.IPackageInstallObserver2;
134import android.content.pm.IPackageInstaller;
135import android.content.pm.IPackageManager;
136import android.content.pm.IPackageMoveObserver;
137import android.content.pm.IPackageStatsObserver;
138import android.content.pm.InstrumentationInfo;
139import android.content.pm.IntentFilterVerificationInfo;
140import android.content.pm.KeySet;
141import android.content.pm.PackageCleanItem;
142import android.content.pm.PackageInfo;
143import android.content.pm.PackageInfoLite;
144import android.content.pm.PackageInstaller;
145import android.content.pm.PackageManager;
146import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
147import android.content.pm.PackageManagerInternal;
148import android.content.pm.PackageParser;
149import android.content.pm.PackageParser.ActivityIntentInfo;
150import android.content.pm.PackageParser.PackageLite;
151import android.content.pm.PackageParser.PackageParserException;
152import android.content.pm.PackageStats;
153import android.content.pm.PackageUserState;
154import android.content.pm.ParceledListSlice;
155import android.content.pm.PermissionGroupInfo;
156import android.content.pm.PermissionInfo;
157import android.content.pm.ProviderInfo;
158import android.content.pm.ResolveInfo;
159import android.content.pm.ServiceInfo;
160import android.content.pm.Signature;
161import android.content.pm.UserInfo;
162import android.content.pm.VerifierDeviceIdentity;
163import android.content.pm.VerifierInfo;
164import android.content.res.Resources;
165import android.graphics.Bitmap;
166import android.hardware.display.DisplayManager;
167import android.net.Uri;
168import android.os.Binder;
169import android.os.Build;
170import android.os.Bundle;
171import android.os.Debug;
172import android.os.Environment;
173import android.os.Environment.UserEnvironment;
174import android.os.FileUtils;
175import android.os.Handler;
176import android.os.IBinder;
177import android.os.Looper;
178import android.os.Message;
179import android.os.Parcel;
180import android.os.ParcelFileDescriptor;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.SELinux;
186import android.os.ServiceManager;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageEventListener;
195import android.os.storage.StorageManager;
196import android.os.storage.VolumeInfo;
197import android.os.storage.VolumeRecord;
198import android.security.KeyStore;
199import android.security.SystemKeyStore;
200import android.system.ErrnoException;
201import android.system.Os;
202import android.text.TextUtils;
203import android.text.format.DateUtils;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.ExceptionUtils;
210import android.util.Log;
211import android.util.LogPrinter;
212import android.util.MathUtils;
213import android.util.PrintStreamPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.SparseBooleanArray;
217import android.util.SparseIntArray;
218import android.util.Xml;
219import android.view.Display;
220
221import com.android.internal.R;
222import com.android.internal.annotations.GuardedBy;
223import com.android.internal.app.IMediaContainerService;
224import com.android.internal.app.ResolverActivity;
225import com.android.internal.content.NativeLibraryHelper;
226import com.android.internal.content.PackageHelper;
227import com.android.internal.os.IParcelFileDescriptorFactory;
228import com.android.internal.os.InstallerConnection.InstallerException;
229import com.android.internal.os.SomeArgs;
230import com.android.internal.os.Zygote;
231import com.android.internal.util.ArrayUtils;
232import com.android.internal.util.FastPrintWriter;
233import com.android.internal.util.FastXmlSerializer;
234import com.android.internal.util.IndentingPrintWriter;
235import com.android.internal.util.Preconditions;
236import com.android.internal.util.XmlUtils;
237import com.android.server.EventLogTags;
238import com.android.server.FgThread;
239import com.android.server.IntentResolver;
240import com.android.server.LocalServices;
241import com.android.server.ServiceThread;
242import com.android.server.SystemConfig;
243import com.android.server.Watchdog;
244import com.android.server.pm.PermissionsState.PermissionState;
245import com.android.server.pm.Settings.DatabaseVersion;
246import com.android.server.pm.Settings.VersionInfo;
247import com.android.server.storage.DeviceStorageMonitorInternal;
248
249import dalvik.system.DexFile;
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import org.xmlpull.v1.XmlPullParser;
256import org.xmlpull.v1.XmlPullParserException;
257import org.xmlpull.v1.XmlSerializer;
258
259import java.io.BufferedInputStream;
260import java.io.BufferedOutputStream;
261import java.io.BufferedReader;
262import java.io.ByteArrayInputStream;
263import java.io.ByteArrayOutputStream;
264import java.io.File;
265import java.io.FileDescriptor;
266import java.io.FileNotFoundException;
267import java.io.FileOutputStream;
268import java.io.FileReader;
269import java.io.FilenameFilter;
270import java.io.IOException;
271import java.io.InputStream;
272import java.io.PrintWriter;
273import java.nio.charset.StandardCharsets;
274import java.security.MessageDigest;
275import java.security.NoSuchAlgorithmException;
276import java.security.PublicKey;
277import java.security.cert.CertificateEncodingException;
278import java.security.cert.CertificateException;
279import java.text.SimpleDateFormat;
280import java.util.ArrayList;
281import java.util.Arrays;
282import java.util.Collection;
283import java.util.Collections;
284import java.util.Comparator;
285import java.util.Date;
286import java.util.HashSet;
287import java.util.Iterator;
288import java.util.List;
289import java.util.Map;
290import java.util.Objects;
291import java.util.Set;
292import java.util.concurrent.CountDownLatch;
293import java.util.concurrent.TimeUnit;
294import java.util.concurrent.atomic.AtomicBoolean;
295import java.util.concurrent.atomic.AtomicInteger;
296import java.util.concurrent.atomic.AtomicLong;
297
298/**
299 * Keep track of all those .apks everywhere.
300 *
301 * This is very central to the platform's security; please run the unit
302 * tests whenever making modifications here:
303 *
304runtest -c android.content.pm.PackageManagerTests frameworks-core
305 *
306 * {@hide}
307 */
308public class PackageManagerService extends IPackageManager.Stub {
309    static final String TAG = "PackageManager";
310    static final boolean DEBUG_SETTINGS = false;
311    static final boolean DEBUG_PREFERRED = false;
312    static final boolean DEBUG_UPGRADE = false;
313    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
314    private static final boolean DEBUG_BACKUP = false;
315    private static final boolean DEBUG_INSTALL = false;
316    private static final boolean DEBUG_REMOVE = false;
317    private static final boolean DEBUG_BROADCASTS = false;
318    private static final boolean DEBUG_SHOW_INFO = false;
319    private static final boolean DEBUG_PACKAGE_INFO = false;
320    private static final boolean DEBUG_INTENT_MATCHING = false;
321    private static final boolean DEBUG_PACKAGE_SCANNING = false;
322    private static final boolean DEBUG_VERIFY = false;
323
324    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
325    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
326    // user, but by default initialize to this.
327    static final boolean DEBUG_DEXOPT = false;
328
329    private static final boolean DEBUG_ABI_SELECTION = false;
330    private static final boolean DEBUG_EPHEMERAL = false;
331    private static final boolean DEBUG_TRIAGED_MISSING = false;
332    private static final boolean DEBUG_APP_DATA = false;
333
334    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
335
336    private static final boolean DISABLE_EPHEMERAL_APPS = true;
337
338    private static final int RADIO_UID = Process.PHONE_UID;
339    private static final int LOG_UID = Process.LOG_UID;
340    private static final int NFC_UID = Process.NFC_UID;
341    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
342    private static final int SHELL_UID = Process.SHELL_UID;
343
344    // Cap the size of permission trees that 3rd party apps can define
345    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
346
347    // Suffix used during package installation when copying/moving
348    // package apks to install directory.
349    private static final String INSTALL_PACKAGE_SUFFIX = "-";
350
351    static final int SCAN_NO_DEX = 1<<1;
352    static final int SCAN_FORCE_DEX = 1<<2;
353    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
354    static final int SCAN_NEW_INSTALL = 1<<4;
355    static final int SCAN_NO_PATHS = 1<<5;
356    static final int SCAN_UPDATE_TIME = 1<<6;
357    static final int SCAN_DEFER_DEX = 1<<7;
358    static final int SCAN_BOOTING = 1<<8;
359    static final int SCAN_TRUSTED_OVERLAY = 1<<9;
360    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
361    static final int SCAN_REPLACING = 1<<11;
362    static final int SCAN_REQUIRE_KNOWN = 1<<12;
363    static final int SCAN_MOVE = 1<<13;
364    static final int SCAN_INITIAL = 1<<14;
365    static final int SCAN_CHECK_ONLY = 1<<15;
366    static final int SCAN_DONT_KILL_APP = 1<<17;
367
368    static final int REMOVE_CHATTY = 1<<16;
369
370    private static final int[] EMPTY_INT_ARRAY = new int[0];
371
372    /**
373     * Timeout (in milliseconds) after which the watchdog should declare that
374     * our handler thread is wedged.  The usual default for such things is one
375     * minute but we sometimes do very lengthy I/O operations on this thread,
376     * such as installing multi-gigabyte applications, so ours needs to be longer.
377     */
378    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
379
380    /**
381     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
382     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
383     * settings entry if available, otherwise we use the hardcoded default.  If it's been
384     * more than this long since the last fstrim, we force one during the boot sequence.
385     *
386     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
387     * one gets run at the next available charging+idle time.  This final mandatory
388     * no-fstrim check kicks in only of the other scheduling criteria is never met.
389     */
390    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
391
392    /**
393     * Whether verification is enabled by default.
394     */
395    private static final boolean DEFAULT_VERIFY_ENABLE = true;
396
397    /**
398     * The default maximum time to wait for the verification agent to return in
399     * milliseconds.
400     */
401    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
402
403    /**
404     * The default response for package verification timeout.
405     *
406     * This can be either PackageManager.VERIFICATION_ALLOW or
407     * PackageManager.VERIFICATION_REJECT.
408     */
409    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
410
411    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
412
413    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
414            DEFAULT_CONTAINER_PACKAGE,
415            "com.android.defcontainer.DefaultContainerService");
416
417    private static final String KILL_APP_REASON_GIDS_CHANGED =
418            "permission grant or revoke changed gids";
419
420    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
421            "permissions revoked";
422
423    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
424
425    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
426
427    /** Permission grant: not grant the permission. */
428    private static final int GRANT_DENIED = 1;
429
430    /** Permission grant: grant the permission as an install permission. */
431    private static final int GRANT_INSTALL = 2;
432
433    /** Permission grant: grant the permission as a runtime one. */
434    private static final int GRANT_RUNTIME = 3;
435
436    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
437    private static final int GRANT_UPGRADE = 4;
438
439    /** Canonical intent used to identify what counts as a "web browser" app */
440    private static final Intent sBrowserIntent;
441    static {
442        sBrowserIntent = new Intent();
443        sBrowserIntent.setAction(Intent.ACTION_VIEW);
444        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
445        sBrowserIntent.setData(Uri.parse("http:"));
446    }
447
448    // Compilation reasons.
449    public static final int REASON_FIRST_BOOT = 0;
450    public static final int REASON_BOOT = 1;
451    public static final int REASON_INSTALL = 2;
452    public static final int REASON_BACKGROUND_DEXOPT = 3;
453    public static final int REASON_AB_OTA = 4;
454    public static final int REASON_NON_SYSTEM_LIBRARY = 5;
455    public static final int REASON_SHARED_APK = 6;
456    public static final int REASON_FORCED_DEXOPT = 7;
457
458    public static final int REASON_LAST = REASON_FORCED_DEXOPT;
459
460    final ServiceThread mHandlerThread;
461
462    final PackageHandler mHandler;
463
464    private final ProcessLoggingHandler mProcessLoggingHandler;
465
466    /**
467     * Messages for {@link #mHandler} that need to wait for system ready before
468     * being dispatched.
469     */
470    private ArrayList<Message> mPostSystemReadyMessages;
471
472    final int mSdkVersion = Build.VERSION.SDK_INT;
473
474    final Context mContext;
475    final boolean mFactoryTest;
476    final boolean mOnlyCore;
477    final DisplayMetrics mMetrics;
478    final int mDefParseFlags;
479    final String[] mSeparateProcesses;
480    final boolean mIsUpgrade;
481    final boolean mIsPreNUpgrade;
482
483    /** The location for ASEC container files on internal storage. */
484    final String mAsecInternalPath;
485
486    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
487    // LOCK HELD.  Can be called with mInstallLock held.
488    @GuardedBy("mInstallLock")
489    final Installer mInstaller;
490
491    /** Directory where installed third-party apps stored */
492    final File mAppInstallDir;
493    final File mEphemeralInstallDir;
494
495    /**
496     * Directory to which applications installed internally have their
497     * 32 bit native libraries copied.
498     */
499    private File mAppLib32InstallDir;
500
501    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
502    // apps.
503    final File mDrmAppPrivateInstallDir;
504
505    // ----------------------------------------------------------------
506
507    // Lock for state used when installing and doing other long running
508    // operations.  Methods that must be called with this lock held have
509    // the suffix "LI".
510    final Object mInstallLock = new Object();
511
512    // ----------------------------------------------------------------
513
514    // Keys are String (package name), values are Package.  This also serves
515    // as the lock for the global state.  Methods that must be called with
516    // this lock held have the prefix "LP".
517    @GuardedBy("mPackages")
518    final ArrayMap<String, PackageParser.Package> mPackages =
519            new ArrayMap<String, PackageParser.Package>();
520
521    final ArrayMap<String, Set<String>> mKnownCodebase =
522            new ArrayMap<String, Set<String>>();
523
524    // Tracks available target package names -> overlay package paths.
525    final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
526        new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
527
528    /**
529     * Tracks new system packages [received in an OTA] that we expect to
530     * find updated user-installed versions. Keys are package name, values
531     * are package location.
532     */
533    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
534
535    /**
536     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
537     */
538    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
539    /**
540     * Whether or not system app permissions should be promoted from install to runtime.
541     */
542    boolean mPromoteSystemApps;
543
544    final Settings mSettings;
545    boolean mRestoredSettings;
546
547    // System configuration read by SystemConfig.
548    final int[] mGlobalGids;
549    final SparseArray<ArraySet<String>> mSystemPermissions;
550    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
551
552    // If mac_permissions.xml was found for seinfo labeling.
553    boolean mFoundPolicyFile;
554
555    private final EphemeralApplicationRegistry mEphemeralApplicationRegistry;
556
557    public static final class SharedLibraryEntry {
558        public final String path;
559        public final String apk;
560
561        SharedLibraryEntry(String _path, String _apk) {
562            path = _path;
563            apk = _apk;
564        }
565    }
566
567    // Currently known shared libraries.
568    final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
569            new ArrayMap<String, SharedLibraryEntry>();
570
571    // All available activities, for your resolving pleasure.
572    final ActivityIntentResolver mActivities =
573            new ActivityIntentResolver();
574
575    // All available receivers, for your resolving pleasure.
576    final ActivityIntentResolver mReceivers =
577            new ActivityIntentResolver();
578
579    // All available services, for your resolving pleasure.
580    final ServiceIntentResolver mServices = new ServiceIntentResolver();
581
582    // All available providers, for your resolving pleasure.
583    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
584
585    // Mapping from provider base names (first directory in content URI codePath)
586    // to the provider information.
587    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
588            new ArrayMap<String, PackageParser.Provider>();
589
590    // Mapping from instrumentation class names to info about them.
591    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
592            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
593
594    // Mapping from permission names to info about them.
595    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
596            new ArrayMap<String, PackageParser.PermissionGroup>();
597
598    // Packages whose data we have transfered into another package, thus
599    // should no longer exist.
600    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
601
602    // Broadcast actions that are only available to the system.
603    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
604
605    /** List of packages waiting for verification. */
606    final SparseArray<PackageVerificationState> mPendingVerification
607            = new SparseArray<PackageVerificationState>();
608
609    /** Set of packages associated with each app op permission. */
610    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
611
612    final PackageInstallerService mInstallerService;
613
614    private final PackageDexOptimizer mPackageDexOptimizer;
615
616    private AtomicInteger mNextMoveId = new AtomicInteger();
617    private final MoveCallbacks mMoveCallbacks;
618
619    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
620
621    // Cache of users who need badging.
622    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
623
624    /** Token for keys in mPendingVerification. */
625    private int mPendingVerificationToken = 0;
626
627    volatile boolean mSystemReady;
628    volatile boolean mSafeMode;
629    volatile boolean mHasSystemUidErrors;
630
631    ApplicationInfo mAndroidApplication;
632    final ActivityInfo mResolveActivity = new ActivityInfo();
633    final ResolveInfo mResolveInfo = new ResolveInfo();
634    ComponentName mResolveComponentName;
635    PackageParser.Package mPlatformPackage;
636    ComponentName mCustomResolverComponentName;
637
638    boolean mResolverReplaced = false;
639
640    private final @Nullable ComponentName mIntentFilterVerifierComponent;
641    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
642
643    private int mIntentFilterVerificationToken = 0;
644
645    /** Component that knows whether or not an ephemeral application exists */
646    final ComponentName mEphemeralResolverComponent;
647    /** The service connection to the ephemeral resolver */
648    final EphemeralResolverConnection mEphemeralResolverConnection;
649
650    /** Component used to install ephemeral applications */
651    final ComponentName mEphemeralInstallerComponent;
652    final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo();
653    final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo();
654
655    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
656            = new SparseArray<IntentFilterVerificationState>();
657
658    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy =
659            new DefaultPermissionGrantPolicy(this);
660
661    // List of packages names to keep cached, even if they are uninstalled for all users
662    private List<String> mKeepUninstalledPackages;
663
664    private static class IFVerificationParams {
665        PackageParser.Package pkg;
666        boolean replacing;
667        int userId;
668        int verifierUid;
669
670        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
671                int _userId, int _verifierUid) {
672            pkg = _pkg;
673            replacing = _replacing;
674            userId = _userId;
675            replacing = _replacing;
676            verifierUid = _verifierUid;
677        }
678    }
679
680    private interface IntentFilterVerifier<T extends IntentFilter> {
681        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
682                                               T filter, String packageName);
683        void startVerifications(int userId);
684        void receiveVerificationResponse(int verificationId);
685    }
686
687    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
688        private Context mContext;
689        private ComponentName mIntentFilterVerifierComponent;
690        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
691
692        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
693            mContext = context;
694            mIntentFilterVerifierComponent = verifierComponent;
695        }
696
697        private String getDefaultScheme() {
698            return IntentFilter.SCHEME_HTTPS;
699        }
700
701        @Override
702        public void startVerifications(int userId) {
703            // Launch verifications requests
704            int count = mCurrentIntentFilterVerifications.size();
705            for (int n=0; n<count; n++) {
706                int verificationId = mCurrentIntentFilterVerifications.get(n);
707                final IntentFilterVerificationState ivs =
708                        mIntentFilterVerificationStates.get(verificationId);
709
710                String packageName = ivs.getPackageName();
711
712                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
713                final int filterCount = filters.size();
714                ArraySet<String> domainsSet = new ArraySet<>();
715                for (int m=0; m<filterCount; m++) {
716                    PackageParser.ActivityIntentInfo filter = filters.get(m);
717                    domainsSet.addAll(filter.getHostsList());
718                }
719                ArrayList<String> domainsList = new ArrayList<>(domainsSet);
720                synchronized (mPackages) {
721                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
722                            packageName, domainsList) != null) {
723                        scheduleWriteSettingsLocked();
724                    }
725                }
726                sendVerificationRequest(userId, verificationId, ivs);
727            }
728            mCurrentIntentFilterVerifications.clear();
729        }
730
731        private void sendVerificationRequest(int userId, int verificationId,
732                IntentFilterVerificationState ivs) {
733
734            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
735            verificationIntent.putExtra(
736                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
737                    verificationId);
738            verificationIntent.putExtra(
739                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
740                    getDefaultScheme());
741            verificationIntent.putExtra(
742                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
743                    ivs.getHostsString());
744            verificationIntent.putExtra(
745                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
746                    ivs.getPackageName());
747            verificationIntent.setComponent(mIntentFilterVerifierComponent);
748            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
749
750            UserHandle user = new UserHandle(userId);
751            mContext.sendBroadcastAsUser(verificationIntent, user);
752            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
753                    "Sending IntentFilter verification broadcast");
754        }
755
756        public void receiveVerificationResponse(int verificationId) {
757            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
758
759            final boolean verified = ivs.isVerified();
760
761            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
762            final int count = filters.size();
763            if (DEBUG_DOMAIN_VERIFICATION) {
764                Slog.i(TAG, "Received verification response " + verificationId
765                        + " for " + count + " filters, verified=" + verified);
766            }
767            for (int n=0; n<count; n++) {
768                PackageParser.ActivityIntentInfo filter = filters.get(n);
769                filter.setVerified(verified);
770
771                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
772                        + " verified with result:" + verified + " and hosts:"
773                        + ivs.getHostsString());
774            }
775
776            mIntentFilterVerificationStates.remove(verificationId);
777
778            final String packageName = ivs.getPackageName();
779            IntentFilterVerificationInfo ivi = null;
780
781            synchronized (mPackages) {
782                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
783            }
784            if (ivi == null) {
785                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
786                        + verificationId + " packageName:" + packageName);
787                return;
788            }
789            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
790                    "Updating IntentFilterVerificationInfo for package " + packageName
791                            +" verificationId:" + verificationId);
792
793            synchronized (mPackages) {
794                if (verified) {
795                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
796                } else {
797                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
798                }
799                scheduleWriteSettingsLocked();
800
801                final int userId = ivs.getUserId();
802                if (userId != UserHandle.USER_ALL) {
803                    final int userStatus =
804                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
805
806                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
807                    boolean needUpdate = false;
808
809                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
810                    // already been set by the User thru the Disambiguation dialog
811                    switch (userStatus) {
812                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
813                            if (verified) {
814                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
815                            } else {
816                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
817                            }
818                            needUpdate = true;
819                            break;
820
821                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
822                            if (verified) {
823                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
824                                needUpdate = true;
825                            }
826                            break;
827
828                        default:
829                            // Nothing to do
830                    }
831
832                    if (needUpdate) {
833                        mSettings.updateIntentFilterVerificationStatusLPw(
834                                packageName, updatedStatus, userId);
835                        scheduleWritePackageRestrictionsLocked(userId);
836                    }
837                }
838            }
839        }
840
841        @Override
842        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
843                    ActivityIntentInfo filter, String packageName) {
844            if (!hasValidDomains(filter)) {
845                return false;
846            }
847            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
848            if (ivs == null) {
849                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
850                        packageName);
851            }
852            if (DEBUG_DOMAIN_VERIFICATION) {
853                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
854            }
855            ivs.addFilter(filter);
856            return true;
857        }
858
859        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
860                int userId, int verificationId, String packageName) {
861            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
862                    verifierUid, userId, packageName);
863            ivs.setPendingState();
864            synchronized (mPackages) {
865                mIntentFilterVerificationStates.append(verificationId, ivs);
866                mCurrentIntentFilterVerifications.add(verificationId);
867            }
868            return ivs;
869        }
870    }
871
872    private static boolean hasValidDomains(ActivityIntentInfo filter) {
873        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
874                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
875                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
876    }
877
878    // Set of pending broadcasts for aggregating enable/disable of components.
879    static class PendingPackageBroadcasts {
880        // for each user id, a map of <package name -> components within that package>
881        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
882
883        public PendingPackageBroadcasts() {
884            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
885        }
886
887        public ArrayList<String> get(int userId, String packageName) {
888            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
889            return packages.get(packageName);
890        }
891
892        public void put(int userId, String packageName, ArrayList<String> components) {
893            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
894            packages.put(packageName, components);
895        }
896
897        public void remove(int userId, String packageName) {
898            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
899            if (packages != null) {
900                packages.remove(packageName);
901            }
902        }
903
904        public void remove(int userId) {
905            mUidMap.remove(userId);
906        }
907
908        public int userIdCount() {
909            return mUidMap.size();
910        }
911
912        public int userIdAt(int n) {
913            return mUidMap.keyAt(n);
914        }
915
916        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
917            return mUidMap.get(userId);
918        }
919
920        public int size() {
921            // total number of pending broadcast entries across all userIds
922            int num = 0;
923            for (int i = 0; i< mUidMap.size(); i++) {
924                num += mUidMap.valueAt(i).size();
925            }
926            return num;
927        }
928
929        public void clear() {
930            mUidMap.clear();
931        }
932
933        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
934            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
935            if (map == null) {
936                map = new ArrayMap<String, ArrayList<String>>();
937                mUidMap.put(userId, map);
938            }
939            return map;
940        }
941    }
942    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
943
944    // Service Connection to remote media container service to copy
945    // package uri's from external media onto secure containers
946    // or internal storage.
947    private IMediaContainerService mContainerService = null;
948
949    static final int SEND_PENDING_BROADCAST = 1;
950    static final int MCS_BOUND = 3;
951    static final int END_COPY = 4;
952    static final int INIT_COPY = 5;
953    static final int MCS_UNBIND = 6;
954    static final int START_CLEANING_PACKAGE = 7;
955    static final int FIND_INSTALL_LOC = 8;
956    static final int POST_INSTALL = 9;
957    static final int MCS_RECONNECT = 10;
958    static final int MCS_GIVE_UP = 11;
959    static final int UPDATED_MEDIA_STATUS = 12;
960    static final int WRITE_SETTINGS = 13;
961    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
962    static final int PACKAGE_VERIFIED = 15;
963    static final int CHECK_PENDING_VERIFICATION = 16;
964    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
965    static final int INTENT_FILTER_VERIFIED = 18;
966
967    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
968
969    // Delay time in millisecs
970    static final int BROADCAST_DELAY = 10 * 1000;
971
972    static UserManagerService sUserManager;
973
974    // Stores a list of users whose package restrictions file needs to be updated
975    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
976
977    final private DefaultContainerConnection mDefContainerConn =
978            new DefaultContainerConnection();
979    class DefaultContainerConnection implements ServiceConnection {
980        public void onServiceConnected(ComponentName name, IBinder service) {
981            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
982            IMediaContainerService imcs =
983                IMediaContainerService.Stub.asInterface(service);
984            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
985        }
986
987        public void onServiceDisconnected(ComponentName name) {
988            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
989        }
990    }
991
992    // Recordkeeping of restore-after-install operations that are currently in flight
993    // between the Package Manager and the Backup Manager
994    static class PostInstallData {
995        public InstallArgs args;
996        public PackageInstalledInfo res;
997
998        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
999            args = _a;
1000            res = _r;
1001        }
1002    }
1003
1004    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1005    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1006
1007    // XML tags for backup/restore of various bits of state
1008    private static final String TAG_PREFERRED_BACKUP = "pa";
1009    private static final String TAG_DEFAULT_APPS = "da";
1010    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1011
1012    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1013    private static final String TAG_ALL_GRANTS = "rt-grants";
1014    private static final String TAG_GRANT = "grant";
1015    private static final String ATTR_PACKAGE_NAME = "pkg";
1016
1017    private static final String TAG_PERMISSION = "perm";
1018    private static final String ATTR_PERMISSION_NAME = "name";
1019    private static final String ATTR_IS_GRANTED = "g";
1020    private static final String ATTR_USER_SET = "set";
1021    private static final String ATTR_USER_FIXED = "fixed";
1022    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1023
1024    // System/policy permission grants are not backed up
1025    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1026            FLAG_PERMISSION_POLICY_FIXED
1027            | FLAG_PERMISSION_SYSTEM_FIXED
1028            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1029
1030    // And we back up these user-adjusted states
1031    private static final int USER_RUNTIME_GRANT_MASK =
1032            FLAG_PERMISSION_USER_SET
1033            | FLAG_PERMISSION_USER_FIXED
1034            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1035
1036    final @Nullable String mRequiredVerifierPackage;
1037    final @Nullable String mRequiredInstallerPackage;
1038    final @Nullable String mSetupWizardPackage;
1039
1040    private final PackageUsage mPackageUsage = new PackageUsage();
1041
1042    private class PackageUsage {
1043        private static final int WRITE_INTERVAL
1044            = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
1045
1046        private final Object mFileLock = new Object();
1047        private final AtomicLong mLastWritten = new AtomicLong(0);
1048        private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
1049
1050        private boolean mIsHistoricalPackageUsageAvailable = true;
1051
1052        boolean isHistoricalPackageUsageAvailable() {
1053            return mIsHistoricalPackageUsageAvailable;
1054        }
1055
1056        void write(boolean force) {
1057            if (force) {
1058                writeInternal();
1059                return;
1060            }
1061            if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
1062                && !DEBUG_DEXOPT) {
1063                return;
1064            }
1065            if (mBackgroundWriteRunning.compareAndSet(false, true)) {
1066                new Thread("PackageUsage_DiskWriter") {
1067                    @Override
1068                    public void run() {
1069                        try {
1070                            writeInternal();
1071                        } finally {
1072                            mBackgroundWriteRunning.set(false);
1073                        }
1074                    }
1075                }.start();
1076            }
1077        }
1078
1079        private void writeInternal() {
1080            synchronized (mPackages) {
1081                synchronized (mFileLock) {
1082                    AtomicFile file = getFile();
1083                    FileOutputStream f = null;
1084                    try {
1085                        f = file.startWrite();
1086                        BufferedOutputStream out = new BufferedOutputStream(f);
1087                        FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
1088                        StringBuilder sb = new StringBuilder();
1089                        for (PackageParser.Package pkg : mPackages.values()) {
1090                            if (pkg.mLastPackageUsageTimeInMills == 0) {
1091                                continue;
1092                            }
1093                            sb.setLength(0);
1094                            sb.append(pkg.packageName);
1095                            sb.append(' ');
1096                            sb.append((long)pkg.mLastPackageUsageTimeInMills);
1097                            sb.append('\n');
1098                            out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
1099                        }
1100                        out.flush();
1101                        file.finishWrite(f);
1102                    } catch (IOException e) {
1103                        if (f != null) {
1104                            file.failWrite(f);
1105                        }
1106                        Log.e(TAG, "Failed to write package usage times", e);
1107                    }
1108                }
1109            }
1110            mLastWritten.set(SystemClock.elapsedRealtime());
1111        }
1112
1113        void readLP() {
1114            synchronized (mFileLock) {
1115                AtomicFile file = getFile();
1116                BufferedInputStream in = null;
1117                try {
1118                    in = new BufferedInputStream(file.openRead());
1119                    StringBuffer sb = new StringBuffer();
1120                    while (true) {
1121                        String packageName = readToken(in, sb, ' ');
1122                        if (packageName == null) {
1123                            break;
1124                        }
1125                        String timeInMillisString = readToken(in, sb, '\n');
1126                        if (timeInMillisString == null) {
1127                            throw new IOException("Failed to find last usage time for package "
1128                                                  + packageName);
1129                        }
1130                        PackageParser.Package pkg = mPackages.get(packageName);
1131                        if (pkg == null) {
1132                            continue;
1133                        }
1134                        long timeInMillis;
1135                        try {
1136                            timeInMillis = Long.parseLong(timeInMillisString);
1137                        } catch (NumberFormatException e) {
1138                            throw new IOException("Failed to parse " + timeInMillisString
1139                                                  + " as a long.", e);
1140                        }
1141                        pkg.mLastPackageUsageTimeInMills = timeInMillis;
1142                    }
1143                } catch (FileNotFoundException expected) {
1144                    mIsHistoricalPackageUsageAvailable = false;
1145                } catch (IOException e) {
1146                    Log.w(TAG, "Failed to read package usage times", e);
1147                } finally {
1148                    IoUtils.closeQuietly(in);
1149                }
1150            }
1151            mLastWritten.set(SystemClock.elapsedRealtime());
1152        }
1153
1154        private String readToken(InputStream in, StringBuffer sb, char endOfToken)
1155                throws IOException {
1156            sb.setLength(0);
1157            while (true) {
1158                int ch = in.read();
1159                if (ch == -1) {
1160                    if (sb.length() == 0) {
1161                        return null;
1162                    }
1163                    throw new IOException("Unexpected EOF");
1164                }
1165                if (ch == endOfToken) {
1166                    return sb.toString();
1167                }
1168                sb.append((char)ch);
1169            }
1170        }
1171
1172        private AtomicFile getFile() {
1173            File dataDir = Environment.getDataDirectory();
1174            File systemDir = new File(dataDir, "system");
1175            File fname = new File(systemDir, "package-usage.list");
1176            return new AtomicFile(fname);
1177        }
1178    }
1179
1180    class PackageHandler extends Handler {
1181        private boolean mBound = false;
1182        final ArrayList<HandlerParams> mPendingInstalls =
1183            new ArrayList<HandlerParams>();
1184
1185        private boolean connectToService() {
1186            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1187                    " DefaultContainerService");
1188            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1189            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1190            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1191                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1192                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1193                mBound = true;
1194                return true;
1195            }
1196            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1197            return false;
1198        }
1199
1200        private void disconnectService() {
1201            mContainerService = null;
1202            mBound = false;
1203            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1204            mContext.unbindService(mDefContainerConn);
1205            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1206        }
1207
1208        PackageHandler(Looper looper) {
1209            super(looper);
1210        }
1211
1212        public void handleMessage(Message msg) {
1213            try {
1214                doHandleMessage(msg);
1215            } finally {
1216                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1217            }
1218        }
1219
1220        void doHandleMessage(Message msg) {
1221            switch (msg.what) {
1222                case INIT_COPY: {
1223                    HandlerParams params = (HandlerParams) msg.obj;
1224                    int idx = mPendingInstalls.size();
1225                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1226                    // If a bind was already initiated we dont really
1227                    // need to do anything. The pending install
1228                    // will be processed later on.
1229                    if (!mBound) {
1230                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1231                                System.identityHashCode(mHandler));
1232                        // If this is the only one pending we might
1233                        // have to bind to the service again.
1234                        if (!connectToService()) {
1235                            Slog.e(TAG, "Failed to bind to media container service");
1236                            params.serviceError();
1237                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1238                                    System.identityHashCode(mHandler));
1239                            if (params.traceMethod != null) {
1240                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1241                                        params.traceCookie);
1242                            }
1243                            return;
1244                        } else {
1245                            // Once we bind to the service, the first
1246                            // pending request will be processed.
1247                            mPendingInstalls.add(idx, params);
1248                        }
1249                    } else {
1250                        mPendingInstalls.add(idx, params);
1251                        // Already bound to the service. Just make
1252                        // sure we trigger off processing the first request.
1253                        if (idx == 0) {
1254                            mHandler.sendEmptyMessage(MCS_BOUND);
1255                        }
1256                    }
1257                    break;
1258                }
1259                case MCS_BOUND: {
1260                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1261                    if (msg.obj != null) {
1262                        mContainerService = (IMediaContainerService) msg.obj;
1263                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1264                                System.identityHashCode(mHandler));
1265                    }
1266                    if (mContainerService == null) {
1267                        if (!mBound) {
1268                            // Something seriously wrong since we are not bound and we are not
1269                            // waiting for connection. Bail out.
1270                            Slog.e(TAG, "Cannot bind to media container service");
1271                            for (HandlerParams params : mPendingInstalls) {
1272                                // Indicate service bind error
1273                                params.serviceError();
1274                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1275                                        System.identityHashCode(params));
1276                                if (params.traceMethod != null) {
1277                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1278                                            params.traceMethod, params.traceCookie);
1279                                }
1280                                return;
1281                            }
1282                            mPendingInstalls.clear();
1283                        } else {
1284                            Slog.w(TAG, "Waiting to connect to media container service");
1285                        }
1286                    } else if (mPendingInstalls.size() > 0) {
1287                        HandlerParams params = mPendingInstalls.get(0);
1288                        if (params != null) {
1289                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1290                                    System.identityHashCode(params));
1291                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1292                            if (params.startCopy()) {
1293                                // We are done...  look for more work or to
1294                                // go idle.
1295                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1296                                        "Checking for more work or unbind...");
1297                                // Delete pending install
1298                                if (mPendingInstalls.size() > 0) {
1299                                    mPendingInstalls.remove(0);
1300                                }
1301                                if (mPendingInstalls.size() == 0) {
1302                                    if (mBound) {
1303                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1304                                                "Posting delayed MCS_UNBIND");
1305                                        removeMessages(MCS_UNBIND);
1306                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1307                                        // Unbind after a little delay, to avoid
1308                                        // continual thrashing.
1309                                        sendMessageDelayed(ubmsg, 10000);
1310                                    }
1311                                } else {
1312                                    // There are more pending requests in queue.
1313                                    // Just post MCS_BOUND message to trigger processing
1314                                    // of next pending install.
1315                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1316                                            "Posting MCS_BOUND for next work");
1317                                    mHandler.sendEmptyMessage(MCS_BOUND);
1318                                }
1319                            }
1320                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1321                        }
1322                    } else {
1323                        // Should never happen ideally.
1324                        Slog.w(TAG, "Empty queue");
1325                    }
1326                    break;
1327                }
1328                case MCS_RECONNECT: {
1329                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1330                    if (mPendingInstalls.size() > 0) {
1331                        if (mBound) {
1332                            disconnectService();
1333                        }
1334                        if (!connectToService()) {
1335                            Slog.e(TAG, "Failed to bind to media container service");
1336                            for (HandlerParams params : mPendingInstalls) {
1337                                // Indicate service bind error
1338                                params.serviceError();
1339                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1340                                        System.identityHashCode(params));
1341                            }
1342                            mPendingInstalls.clear();
1343                        }
1344                    }
1345                    break;
1346                }
1347                case MCS_UNBIND: {
1348                    // If there is no actual work left, then time to unbind.
1349                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1350
1351                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1352                        if (mBound) {
1353                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1354
1355                            disconnectService();
1356                        }
1357                    } else if (mPendingInstalls.size() > 0) {
1358                        // There are more pending requests in queue.
1359                        // Just post MCS_BOUND message to trigger processing
1360                        // of next pending install.
1361                        mHandler.sendEmptyMessage(MCS_BOUND);
1362                    }
1363
1364                    break;
1365                }
1366                case MCS_GIVE_UP: {
1367                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1368                    HandlerParams params = mPendingInstalls.remove(0);
1369                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1370                            System.identityHashCode(params));
1371                    break;
1372                }
1373                case SEND_PENDING_BROADCAST: {
1374                    String packages[];
1375                    ArrayList<String> components[];
1376                    int size = 0;
1377                    int uids[];
1378                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1379                    synchronized (mPackages) {
1380                        if (mPendingBroadcasts == null) {
1381                            return;
1382                        }
1383                        size = mPendingBroadcasts.size();
1384                        if (size <= 0) {
1385                            // Nothing to be done. Just return
1386                            return;
1387                        }
1388                        packages = new String[size];
1389                        components = new ArrayList[size];
1390                        uids = new int[size];
1391                        int i = 0;  // filling out the above arrays
1392
1393                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1394                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1395                            Iterator<Map.Entry<String, ArrayList<String>>> it
1396                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1397                                            .entrySet().iterator();
1398                            while (it.hasNext() && i < size) {
1399                                Map.Entry<String, ArrayList<String>> ent = it.next();
1400                                packages[i] = ent.getKey();
1401                                components[i] = ent.getValue();
1402                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1403                                uids[i] = (ps != null)
1404                                        ? UserHandle.getUid(packageUserId, ps.appId)
1405                                        : -1;
1406                                i++;
1407                            }
1408                        }
1409                        size = i;
1410                        mPendingBroadcasts.clear();
1411                    }
1412                    // Send broadcasts
1413                    for (int i = 0; i < size; i++) {
1414                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1415                    }
1416                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1417                    break;
1418                }
1419                case START_CLEANING_PACKAGE: {
1420                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1421                    final String packageName = (String)msg.obj;
1422                    final int userId = msg.arg1;
1423                    final boolean andCode = msg.arg2 != 0;
1424                    synchronized (mPackages) {
1425                        if (userId == UserHandle.USER_ALL) {
1426                            int[] users = sUserManager.getUserIds();
1427                            for (int user : users) {
1428                                mSettings.addPackageToCleanLPw(
1429                                        new PackageCleanItem(user, packageName, andCode));
1430                            }
1431                        } else {
1432                            mSettings.addPackageToCleanLPw(
1433                                    new PackageCleanItem(userId, packageName, andCode));
1434                        }
1435                    }
1436                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1437                    startCleaningPackages();
1438                } break;
1439                case POST_INSTALL: {
1440                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1441
1442                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1443                    mRunningInstalls.delete(msg.arg1);
1444
1445                    if (data != null) {
1446                        InstallArgs args = data.args;
1447                        PackageInstalledInfo parentRes = data.res;
1448
1449                        final boolean grantPermissions = (args.installFlags
1450                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1451                        final boolean killApp = (args.installFlags
1452                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1453                        final String[] grantedPermissions = args.installGrantPermissions;
1454
1455                        // Handle the parent package
1456                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1457                                grantedPermissions, args.observer);
1458
1459                        // Handle the child packages
1460                        final int childCount = (parentRes.addedChildPackages != null)
1461                                ? parentRes.addedChildPackages.size() : 0;
1462                        for (int i = 0; i < childCount; i++) {
1463                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1464                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1465                                    grantedPermissions, args.observer);
1466                        }
1467
1468                        // Log tracing if needed
1469                        if (args.traceMethod != null) {
1470                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1471                                    args.traceCookie);
1472                        }
1473                    } else {
1474                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1475                    }
1476
1477                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1478                } break;
1479                case UPDATED_MEDIA_STATUS: {
1480                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1481                    boolean reportStatus = msg.arg1 == 1;
1482                    boolean doGc = msg.arg2 == 1;
1483                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1484                    if (doGc) {
1485                        // Force a gc to clear up stale containers.
1486                        Runtime.getRuntime().gc();
1487                    }
1488                    if (msg.obj != null) {
1489                        @SuppressWarnings("unchecked")
1490                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1491                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1492                        // Unload containers
1493                        unloadAllContainers(args);
1494                    }
1495                    if (reportStatus) {
1496                        try {
1497                            if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
1498                            PackageHelper.getMountService().finishMediaUpdate();
1499                        } catch (RemoteException e) {
1500                            Log.e(TAG, "MountService not running?");
1501                        }
1502                    }
1503                } break;
1504                case WRITE_SETTINGS: {
1505                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1506                    synchronized (mPackages) {
1507                        removeMessages(WRITE_SETTINGS);
1508                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1509                        mSettings.writeLPr();
1510                        mDirtyUsers.clear();
1511                    }
1512                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1513                } break;
1514                case WRITE_PACKAGE_RESTRICTIONS: {
1515                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1516                    synchronized (mPackages) {
1517                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1518                        for (int userId : mDirtyUsers) {
1519                            mSettings.writePackageRestrictionsLPr(userId);
1520                        }
1521                        mDirtyUsers.clear();
1522                    }
1523                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1524                } break;
1525                case CHECK_PENDING_VERIFICATION: {
1526                    final int verificationId = msg.arg1;
1527                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1528
1529                    if ((state != null) && !state.timeoutExtended()) {
1530                        final InstallArgs args = state.getInstallArgs();
1531                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1532
1533                        Slog.i(TAG, "Verification timed out for " + originUri);
1534                        mPendingVerification.remove(verificationId);
1535
1536                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1537
1538                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1539                            Slog.i(TAG, "Continuing with installation of " + originUri);
1540                            state.setVerifierResponse(Binder.getCallingUid(),
1541                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1542                            broadcastPackageVerified(verificationId, originUri,
1543                                    PackageManager.VERIFICATION_ALLOW,
1544                                    state.getInstallArgs().getUser());
1545                            try {
1546                                ret = args.copyApk(mContainerService, true);
1547                            } catch (RemoteException e) {
1548                                Slog.e(TAG, "Could not contact the ContainerService");
1549                            }
1550                        } else {
1551                            broadcastPackageVerified(verificationId, originUri,
1552                                    PackageManager.VERIFICATION_REJECT,
1553                                    state.getInstallArgs().getUser());
1554                        }
1555
1556                        Trace.asyncTraceEnd(
1557                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1558
1559                        processPendingInstall(args, ret);
1560                        mHandler.sendEmptyMessage(MCS_UNBIND);
1561                    }
1562                    break;
1563                }
1564                case PACKAGE_VERIFIED: {
1565                    final int verificationId = msg.arg1;
1566
1567                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1568                    if (state == null) {
1569                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1570                        break;
1571                    }
1572
1573                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1574
1575                    state.setVerifierResponse(response.callerUid, response.code);
1576
1577                    if (state.isVerificationComplete()) {
1578                        mPendingVerification.remove(verificationId);
1579
1580                        final InstallArgs args = state.getInstallArgs();
1581                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1582
1583                        int ret;
1584                        if (state.isInstallAllowed()) {
1585                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1586                            broadcastPackageVerified(verificationId, originUri,
1587                                    response.code, state.getInstallArgs().getUser());
1588                            try {
1589                                ret = args.copyApk(mContainerService, true);
1590                            } catch (RemoteException e) {
1591                                Slog.e(TAG, "Could not contact the ContainerService");
1592                            }
1593                        } else {
1594                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1595                        }
1596
1597                        Trace.asyncTraceEnd(
1598                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1599
1600                        processPendingInstall(args, ret);
1601                        mHandler.sendEmptyMessage(MCS_UNBIND);
1602                    }
1603
1604                    break;
1605                }
1606                case START_INTENT_FILTER_VERIFICATIONS: {
1607                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1608                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1609                            params.replacing, params.pkg);
1610                    break;
1611                }
1612                case INTENT_FILTER_VERIFIED: {
1613                    final int verificationId = msg.arg1;
1614
1615                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1616                            verificationId);
1617                    if (state == null) {
1618                        Slog.w(TAG, "Invalid IntentFilter verification token "
1619                                + verificationId + " received");
1620                        break;
1621                    }
1622
1623                    final int userId = state.getUserId();
1624
1625                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1626                            "Processing IntentFilter verification with token:"
1627                            + verificationId + " and userId:" + userId);
1628
1629                    final IntentFilterVerificationResponse response =
1630                            (IntentFilterVerificationResponse) msg.obj;
1631
1632                    state.setVerifierResponse(response.callerUid, response.code);
1633
1634                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1635                            "IntentFilter verification with token:" + verificationId
1636                            + " and userId:" + userId
1637                            + " is settings verifier response with response code:"
1638                            + response.code);
1639
1640                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1641                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1642                                + response.getFailedDomainsString());
1643                    }
1644
1645                    if (state.isVerificationComplete()) {
1646                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1647                    } else {
1648                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1649                                "IntentFilter verification with token:" + verificationId
1650                                + " was not said to be complete");
1651                    }
1652
1653                    break;
1654                }
1655            }
1656        }
1657    }
1658
1659    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1660            boolean killApp, String[] grantedPermissions,
1661            IPackageInstallObserver2 installObserver) {
1662        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1663            // Send the removed broadcasts
1664            if (res.removedInfo != null) {
1665                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1666            }
1667
1668            // Now that we successfully installed the package, grant runtime
1669            // permissions if requested before broadcasting the install.
1670            if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
1671                    >= Build.VERSION_CODES.M) {
1672                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1673            }
1674
1675            final boolean update = res.removedInfo != null
1676                    && res.removedInfo.removedPackage != null;
1677
1678            // If this is the first time we have child packages for a disabled privileged
1679            // app that had no children, we grant requested runtime permissions to the new
1680            // children if the parent on the system image had them already granted.
1681            if (res.pkg.parentPackage != null) {
1682                synchronized (mPackages) {
1683                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1684                }
1685            }
1686
1687            synchronized (mPackages) {
1688                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
1689            }
1690
1691            final String packageName = res.pkg.applicationInfo.packageName;
1692            Bundle extras = new Bundle(1);
1693            extras.putInt(Intent.EXTRA_UID, res.uid);
1694
1695            // Determine the set of users who are adding this package for
1696            // the first time vs. those who are seeing an update.
1697            int[] firstUsers = EMPTY_INT_ARRAY;
1698            int[] updateUsers = EMPTY_INT_ARRAY;
1699            if (res.origUsers == null || res.origUsers.length == 0) {
1700                firstUsers = res.newUsers;
1701            } else {
1702                for (int newUser : res.newUsers) {
1703                    boolean isNew = true;
1704                    for (int origUser : res.origUsers) {
1705                        if (origUser == newUser) {
1706                            isNew = false;
1707                            break;
1708                        }
1709                    }
1710                    if (isNew) {
1711                        firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1712                    } else {
1713                        updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1714                    }
1715                }
1716            }
1717
1718            // Send installed broadcasts if the install/update is not ephemeral
1719            if (!isEphemeral(res.pkg)) {
1720                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1721
1722                // Send added for users that see the package for the first time
1723                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1724                        extras, 0 /*flags*/, null /*targetPackage*/,
1725                        null /*finishedReceiver*/, firstUsers);
1726
1727                // Send added for users that don't see the package for the first time
1728                if (update) {
1729                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1730                }
1731                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1732                        extras, 0 /*flags*/, null /*targetPackage*/,
1733                        null /*finishedReceiver*/, updateUsers);
1734
1735                // Send replaced for users that don't see the package for the first time
1736                if (update) {
1737                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1738                            packageName, extras, 0 /*flags*/,
1739                            null /*targetPackage*/, null /*finishedReceiver*/,
1740                            updateUsers);
1741                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1742                            null /*package*/, null /*extras*/, 0 /*flags*/,
1743                            packageName /*targetPackage*/,
1744                            null /*finishedReceiver*/, updateUsers);
1745                }
1746
1747                // Send broadcast package appeared if forward locked/external for all users
1748                // treat asec-hosted packages like removable media on upgrade
1749                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1750                    if (DEBUG_INSTALL) {
1751                        Slog.i(TAG, "upgrading pkg " + res.pkg
1752                                + " is ASEC-hosted -> AVAILABLE");
1753                    }
1754                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1755                    ArrayList<String> pkgList = new ArrayList<>(1);
1756                    pkgList.add(packageName);
1757                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1758                }
1759            }
1760
1761            // Work that needs to happen on first install within each user
1762            if (firstUsers != null && firstUsers.length > 0) {
1763                synchronized (mPackages) {
1764                    for (int userId : firstUsers) {
1765                        // If this app is a browser and it's newly-installed for some
1766                        // users, clear any default-browser state in those users. The
1767                        // app's nature doesn't depend on the user, so we can just check
1768                        // its browser nature in any user and generalize.
1769                        if (packageIsBrowser(packageName, userId)) {
1770                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1771                        }
1772
1773                        // We may also need to apply pending (restored) runtime
1774                        // permission grants within these users.
1775                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1776                    }
1777                }
1778            }
1779
1780            // Log current value of "unknown sources" setting
1781            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1782                    getUnknownSourcesSettings());
1783
1784            // Force a gc to clear up things
1785            Runtime.getRuntime().gc();
1786
1787            // Remove the replaced package's older resources safely now
1788            // We delete after a gc for applications  on sdcard.
1789            if (res.removedInfo != null && res.removedInfo.args != null) {
1790                synchronized (mInstallLock) {
1791                    res.removedInfo.args.doPostDeleteLI(true);
1792                }
1793            }
1794        }
1795
1796        // If someone is watching installs - notify them
1797        if (installObserver != null) {
1798            try {
1799                Bundle extras = extrasForInstallResult(res);
1800                installObserver.onPackageInstalled(res.name, res.returnCode,
1801                        res.returnMsg, extras);
1802            } catch (RemoteException e) {
1803                Slog.i(TAG, "Observer no longer exists.");
1804            }
1805        }
1806    }
1807
1808    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1809            PackageParser.Package pkg) {
1810        if (pkg.parentPackage == null) {
1811            return;
1812        }
1813        if (pkg.requestedPermissions == null) {
1814            return;
1815        }
1816        final PackageSetting disabledSysParentPs = mSettings
1817                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1818        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1819                || !disabledSysParentPs.isPrivileged()
1820                || (disabledSysParentPs.childPackageNames != null
1821                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
1822            return;
1823        }
1824        final int[] allUserIds = sUserManager.getUserIds();
1825        final int permCount = pkg.requestedPermissions.size();
1826        for (int i = 0; i < permCount; i++) {
1827            String permission = pkg.requestedPermissions.get(i);
1828            BasePermission bp = mSettings.mPermissions.get(permission);
1829            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1830                continue;
1831            }
1832            for (int userId : allUserIds) {
1833                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1834                        permission, userId)) {
1835                    grantRuntimePermission(pkg.packageName, permission, userId);
1836                }
1837            }
1838        }
1839    }
1840
1841    private StorageEventListener mStorageListener = new StorageEventListener() {
1842        @Override
1843        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1844            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1845                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1846                    final String volumeUuid = vol.getFsUuid();
1847
1848                    // Clean up any users or apps that were removed or recreated
1849                    // while this volume was missing
1850                    reconcileUsers(volumeUuid);
1851                    reconcileApps(volumeUuid);
1852
1853                    // Clean up any install sessions that expired or were
1854                    // cancelled while this volume was missing
1855                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
1856
1857                    loadPrivatePackages(vol);
1858
1859                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1860                    unloadPrivatePackages(vol);
1861                }
1862            }
1863
1864            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
1865                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1866                    updateExternalMediaStatus(true, false);
1867                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
1868                    updateExternalMediaStatus(false, false);
1869                }
1870            }
1871        }
1872
1873        @Override
1874        public void onVolumeForgotten(String fsUuid) {
1875            if (TextUtils.isEmpty(fsUuid)) {
1876                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
1877                return;
1878            }
1879
1880            // Remove any apps installed on the forgotten volume
1881            synchronized (mPackages) {
1882                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
1883                for (PackageSetting ps : packages) {
1884                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
1885                    deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(),
1886                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
1887                }
1888
1889                mSettings.onVolumeForgotten(fsUuid);
1890                mSettings.writeLPr();
1891            }
1892        }
1893    };
1894
1895    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1896            String[] grantedPermissions) {
1897        for (int userId : userIds) {
1898            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
1899        }
1900
1901        // We could have touched GID membership, so flush out packages.list
1902        synchronized (mPackages) {
1903            mSettings.writePackageListLPr();
1904        }
1905    }
1906
1907    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1908            String[] grantedPermissions) {
1909        SettingBase sb = (SettingBase) pkg.mExtras;
1910        if (sb == null) {
1911            return;
1912        }
1913
1914        PermissionsState permissionsState = sb.getPermissionsState();
1915
1916        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1917                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1918
1919        synchronized (mPackages) {
1920            for (String permission : pkg.requestedPermissions) {
1921                BasePermission bp = mSettings.mPermissions.get(permission);
1922                if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1923                        && (grantedPermissions == null
1924                               || ArrayUtils.contains(grantedPermissions, permission))) {
1925                    final int flags = permissionsState.getPermissionFlags(permission, userId);
1926                    // Installer cannot change immutable permissions.
1927                    if ((flags & immutableFlags) == 0) {
1928                        grantRuntimePermission(pkg.packageName, permission, userId);
1929                    }
1930                }
1931            }
1932        }
1933    }
1934
1935    Bundle extrasForInstallResult(PackageInstalledInfo res) {
1936        Bundle extras = null;
1937        switch (res.returnCode) {
1938            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
1939                extras = new Bundle();
1940                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
1941                        res.origPermission);
1942                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
1943                        res.origPackage);
1944                break;
1945            }
1946            case PackageManager.INSTALL_SUCCEEDED: {
1947                extras = new Bundle();
1948                extras.putBoolean(Intent.EXTRA_REPLACING,
1949                        res.removedInfo != null && res.removedInfo.removedPackage != null);
1950                break;
1951            }
1952        }
1953        return extras;
1954    }
1955
1956    void scheduleWriteSettingsLocked() {
1957        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1958            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1959        }
1960    }
1961
1962    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
1963        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
1964        scheduleWritePackageRestrictionsLocked(userId);
1965    }
1966
1967    void scheduleWritePackageRestrictionsLocked(int userId) {
1968        final int[] userIds = (userId == UserHandle.USER_ALL)
1969                ? sUserManager.getUserIds() : new int[]{userId};
1970        for (int nextUserId : userIds) {
1971            if (!sUserManager.exists(nextUserId)) return;
1972            mDirtyUsers.add(nextUserId);
1973            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1974                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1975            }
1976        }
1977    }
1978
1979    public static PackageManagerService main(Context context, Installer installer,
1980            boolean factoryTest, boolean onlyCore) {
1981        // Self-check for initial settings.
1982        PackageManagerServiceCompilerMapping.checkProperties();
1983
1984        PackageManagerService m = new PackageManagerService(context, installer,
1985                factoryTest, onlyCore);
1986        m.enableSystemUserPackages();
1987        ServiceManager.addService("package", m);
1988        return m;
1989    }
1990
1991    private void enableSystemUserPackages() {
1992        if (!UserManager.isSplitSystemUser()) {
1993            return;
1994        }
1995        // For system user, enable apps based on the following conditions:
1996        // - app is whitelisted or belong to one of these groups:
1997        //   -- system app which has no launcher icons
1998        //   -- system app which has INTERACT_ACROSS_USERS permission
1999        //   -- system IME app
2000        // - app is not in the blacklist
2001        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2002        Set<String> enableApps = new ArraySet<>();
2003        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2004                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2005                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2006        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2007        enableApps.addAll(wlApps);
2008        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2009                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2010        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2011        enableApps.removeAll(blApps);
2012        Log.i(TAG, "Applications installed for system user: " + enableApps);
2013        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2014                UserHandle.SYSTEM);
2015        final int allAppsSize = allAps.size();
2016        synchronized (mPackages) {
2017            for (int i = 0; i < allAppsSize; i++) {
2018                String pName = allAps.get(i);
2019                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2020                // Should not happen, but we shouldn't be failing if it does
2021                if (pkgSetting == null) {
2022                    continue;
2023                }
2024                boolean install = enableApps.contains(pName);
2025                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2026                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2027                            + " for system user");
2028                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2029                }
2030            }
2031        }
2032    }
2033
2034    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2035        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2036                Context.DISPLAY_SERVICE);
2037        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2038    }
2039
2040    public PackageManagerService(Context context, Installer installer,
2041            boolean factoryTest, boolean onlyCore) {
2042        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2043                SystemClock.uptimeMillis());
2044
2045        if (mSdkVersion <= 0) {
2046            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2047        }
2048
2049        mContext = context;
2050        mFactoryTest = factoryTest;
2051        mOnlyCore = onlyCore;
2052        mMetrics = new DisplayMetrics();
2053        mSettings = new Settings(mPackages);
2054        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2055                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2056        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2057                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2058        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2059                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2060        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2061                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2062        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2063                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2064        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2065                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2066
2067        String separateProcesses = SystemProperties.get("debug.separate_processes");
2068        if (separateProcesses != null && separateProcesses.length() > 0) {
2069            if ("*".equals(separateProcesses)) {
2070                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2071                mSeparateProcesses = null;
2072                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2073            } else {
2074                mDefParseFlags = 0;
2075                mSeparateProcesses = separateProcesses.split(",");
2076                Slog.w(TAG, "Running with debug.separate_processes: "
2077                        + separateProcesses);
2078            }
2079        } else {
2080            mDefParseFlags = 0;
2081            mSeparateProcesses = null;
2082        }
2083
2084        mInstaller = installer;
2085        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2086                "*dexopt*");
2087        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2088
2089        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2090                FgThread.get().getLooper());
2091
2092        getDefaultDisplayMetrics(context, mMetrics);
2093
2094        SystemConfig systemConfig = SystemConfig.getInstance();
2095        mGlobalGids = systemConfig.getGlobalGids();
2096        mSystemPermissions = systemConfig.getSystemPermissions();
2097        mAvailableFeatures = systemConfig.getAvailableFeatures();
2098
2099        synchronized (mInstallLock) {
2100        // writer
2101        synchronized (mPackages) {
2102            mHandlerThread = new ServiceThread(TAG,
2103                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2104            mHandlerThread.start();
2105            mHandler = new PackageHandler(mHandlerThread.getLooper());
2106            mProcessLoggingHandler = new ProcessLoggingHandler();
2107            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2108
2109            File dataDir = Environment.getDataDirectory();
2110            mAppInstallDir = new File(dataDir, "app");
2111            mAppLib32InstallDir = new File(dataDir, "app-lib");
2112            mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
2113            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2114            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2115
2116            sUserManager = new UserManagerService(context, this, mPackages);
2117
2118            // Propagate permission configuration in to package manager.
2119            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2120                    = systemConfig.getPermissions();
2121            for (int i=0; i<permConfig.size(); i++) {
2122                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2123                BasePermission bp = mSettings.mPermissions.get(perm.name);
2124                if (bp == null) {
2125                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2126                    mSettings.mPermissions.put(perm.name, bp);
2127                }
2128                if (perm.gids != null) {
2129                    bp.setGids(perm.gids, perm.perUser);
2130                }
2131            }
2132
2133            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2134            for (int i=0; i<libConfig.size(); i++) {
2135                mSharedLibraries.put(libConfig.keyAt(i),
2136                        new SharedLibraryEntry(libConfig.valueAt(i), null));
2137            }
2138
2139            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2140
2141            mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false));
2142
2143            String customResolverActivity = Resources.getSystem().getString(
2144                    R.string.config_customResolverActivity);
2145            if (TextUtils.isEmpty(customResolverActivity)) {
2146                customResolverActivity = null;
2147            } else {
2148                mCustomResolverComponentName = ComponentName.unflattenFromString(
2149                        customResolverActivity);
2150            }
2151
2152            long startTime = SystemClock.uptimeMillis();
2153
2154            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2155                    startTime);
2156
2157            // Set flag to monitor and not change apk file paths when
2158            // scanning install directories.
2159            final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL;
2160
2161            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2162            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2163
2164            if (bootClassPath == null) {
2165                Slog.w(TAG, "No BOOTCLASSPATH found!");
2166            }
2167
2168            if (systemServerClassPath == null) {
2169                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2170            }
2171
2172            final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
2173            final String[] dexCodeInstructionSets =
2174                    getDexCodeInstructionSets(
2175                            allInstructionSets.toArray(new String[allInstructionSets.size()]));
2176
2177            /**
2178             * Ensure all external libraries have had dexopt run on them.
2179             */
2180            if (mSharedLibraries.size() > 0) {
2181                // NOTE: For now, we're compiling these system "shared libraries"
2182                // (and framework jars) into all available architectures. It's possible
2183                // to compile them only when we come across an app that uses them (there's
2184                // already logic for that in scanPackageLI) but that adds some complexity.
2185                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
2186                    for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
2187                        final String lib = libEntry.path;
2188                        if (lib == null) {
2189                            continue;
2190                        }
2191
2192                        try {
2193                            // Shared libraries do not have profiles so we perform a full
2194                            // AOT compilation (if needed).
2195                            int dexoptNeeded = DexFile.getDexOptNeeded(
2196                                    lib, dexCodeInstructionSet,
2197                                    getCompilerFilterForReason(REASON_SHARED_APK),
2198                                    false /* newProfile */);
2199                            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
2200                                mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet,
2201                                        dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/,
2202                                        getCompilerFilterForReason(REASON_SHARED_APK),
2203                                        StorageManager.UUID_PRIVATE_INTERNAL);
2204                            }
2205                        } catch (FileNotFoundException e) {
2206                            Slog.w(TAG, "Library not found: " + lib);
2207                        } catch (IOException | InstallerException e) {
2208                            Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
2209                                    + e.getMessage());
2210                        }
2211                    }
2212                }
2213            }
2214
2215            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2216
2217            final VersionInfo ver = mSettings.getInternalVersion();
2218            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2219
2220            // when upgrading from pre-M, promote system app permissions from install to runtime
2221            mPromoteSystemApps =
2222                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2223
2224            // save off the names of pre-existing system packages prior to scanning; we don't
2225            // want to automatically grant runtime permissions for new system apps
2226            if (mPromoteSystemApps) {
2227                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2228                while (pkgSettingIter.hasNext()) {
2229                    PackageSetting ps = pkgSettingIter.next();
2230                    if (isSystemApp(ps)) {
2231                        mExistingSystemPackages.add(ps.name);
2232                    }
2233                }
2234            }
2235
2236            // When upgrading from pre-N, we need to handle package extraction like first boot,
2237            // as there is no profiling data available.
2238            mIsPreNUpgrade = !mSettings.isNWorkDone();
2239            mSettings.setNWorkDone();
2240
2241            // Collect vendor overlay packages.
2242            // (Do this before scanning any apps.)
2243            // For security and version matching reason, only consider
2244            // overlay packages if they reside in VENDOR_OVERLAY_DIR.
2245            File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
2246            scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
2247                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2248
2249            // Find base frameworks (resource packages without code).
2250            scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
2251                    | PackageParser.PARSE_IS_SYSTEM_DIR
2252                    | PackageParser.PARSE_IS_PRIVILEGED,
2253                    scanFlags | SCAN_NO_DEX, 0);
2254
2255            // Collected privileged system packages.
2256            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2257            scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
2258                    | PackageParser.PARSE_IS_SYSTEM_DIR
2259                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2260
2261            // Collect ordinary system packages.
2262            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2263            scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
2264                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2265
2266            // Collect all vendor packages.
2267            File vendorAppDir = new File("/vendor/app");
2268            try {
2269                vendorAppDir = vendorAppDir.getCanonicalFile();
2270            } catch (IOException e) {
2271                // failed to look up canonical path, continue with original one
2272            }
2273            scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
2274                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2275
2276            // Collect all OEM packages.
2277            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2278            scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
2279                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2280
2281            // Prune any system packages that no longer exist.
2282            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2283            if (!mOnlyCore) {
2284                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2285                while (psit.hasNext()) {
2286                    PackageSetting ps = psit.next();
2287
2288                    /*
2289                     * If this is not a system app, it can't be a
2290                     * disable system app.
2291                     */
2292                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2293                        continue;
2294                    }
2295
2296                    /*
2297                     * If the package is scanned, it's not erased.
2298                     */
2299                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2300                    if (scannedPkg != null) {
2301                        /*
2302                         * If the system app is both scanned and in the
2303                         * disabled packages list, then it must have been
2304                         * added via OTA. Remove it from the currently
2305                         * scanned package so the previously user-installed
2306                         * application can be scanned.
2307                         */
2308                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2309                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2310                                    + ps.name + "; removing system app.  Last known codePath="
2311                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2312                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2313                                    + scannedPkg.mVersionCode);
2314                            removePackageLI(scannedPkg, true);
2315                            mExpectingBetter.put(ps.name, ps.codePath);
2316                        }
2317
2318                        continue;
2319                    }
2320
2321                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2322                        psit.remove();
2323                        logCriticalInfo(Log.WARN, "System package " + ps.name
2324                                + " no longer exists; wiping its data");
2325                        removeDataDirsLI(null, ps.name);
2326                    } else {
2327                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2328                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2329                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2330                        }
2331                    }
2332                }
2333            }
2334
2335            //look for any incomplete package installations
2336            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2337            //clean up list
2338            for(int i = 0; i < deletePkgsList.size(); i++) {
2339                //clean up here
2340                cleanupInstallFailedPackage(deletePkgsList.get(i));
2341            }
2342            //delete tmp files
2343            deleteTempPackageFiles();
2344
2345            // Remove any shared userIDs that have no associated packages
2346            mSettings.pruneSharedUsersLPw();
2347
2348            if (!mOnlyCore) {
2349                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2350                        SystemClock.uptimeMillis());
2351                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2352
2353                scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
2354                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2355
2356                scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL,
2357                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2358
2359                /**
2360                 * Remove disable package settings for any updated system
2361                 * apps that were removed via an OTA. If they're not a
2362                 * previously-updated app, remove them completely.
2363                 * Otherwise, just revoke their system-level permissions.
2364                 */
2365                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2366                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2367                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2368
2369                    String msg;
2370                    if (deletedPkg == null) {
2371                        msg = "Updated system package " + deletedAppName
2372                                + " no longer exists; wiping its data";
2373                        removeDataDirsLI(null, deletedAppName);
2374                    } else {
2375                        msg = "Updated system app + " + deletedAppName
2376                                + " no longer present; removing system privileges for "
2377                                + deletedAppName;
2378
2379                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2380
2381                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2382                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2383                    }
2384                    logCriticalInfo(Log.WARN, msg);
2385                }
2386
2387                /**
2388                 * Make sure all system apps that we expected to appear on
2389                 * the userdata partition actually showed up. If they never
2390                 * appeared, crawl back and revive the system version.
2391                 */
2392                for (int i = 0; i < mExpectingBetter.size(); i++) {
2393                    final String packageName = mExpectingBetter.keyAt(i);
2394                    if (!mPackages.containsKey(packageName)) {
2395                        final File scanFile = mExpectingBetter.valueAt(i);
2396
2397                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2398                                + " but never showed up; reverting to system");
2399
2400                        final int reparseFlags;
2401                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2402                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2403                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2404                                    | PackageParser.PARSE_IS_PRIVILEGED;
2405                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2406                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2407                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2408                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2409                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2410                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2411                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2412                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2413                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2414                        } else {
2415                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2416                            continue;
2417                        }
2418
2419                        mSettings.enableSystemPackageLPw(packageName);
2420
2421                        try {
2422                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2423                        } catch (PackageManagerException e) {
2424                            Slog.e(TAG, "Failed to parse original system package: "
2425                                    + e.getMessage());
2426                        }
2427                    }
2428                }
2429            }
2430            mExpectingBetter.clear();
2431
2432            // Now that we know all of the shared libraries, update all clients to have
2433            // the correct library paths.
2434            updateAllSharedLibrariesLPw();
2435
2436            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2437                // NOTE: We ignore potential failures here during a system scan (like
2438                // the rest of the commands above) because there's precious little we
2439                // can do about it. A settings error is reported, though.
2440                adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
2441                        false /* boot complete */);
2442            }
2443
2444            // Now that we know all the packages we are keeping,
2445            // read and update their last usage times.
2446            mPackageUsage.readLP();
2447
2448            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2449                    SystemClock.uptimeMillis());
2450            Slog.i(TAG, "Time to scan packages: "
2451                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2452                    + " seconds");
2453
2454            // If the platform SDK has changed since the last time we booted,
2455            // we need to re-grant app permission to catch any new ones that
2456            // appear.  This is really a hack, and means that apps can in some
2457            // cases get permissions that the user didn't initially explicitly
2458            // allow...  it would be nice to have some better way to handle
2459            // this situation.
2460            int updateFlags = UPDATE_PERMISSIONS_ALL;
2461            if (ver.sdkVersion != mSdkVersion) {
2462                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2463                        + mSdkVersion + "; regranting permissions for internal storage");
2464                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2465            }
2466            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2467            ver.sdkVersion = mSdkVersion;
2468
2469            // If this is the first boot or an update from pre-M, and it is a normal
2470            // boot, then we need to initialize the default preferred apps across
2471            // all defined users.
2472            if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) {
2473                for (UserInfo user : sUserManager.getUsers(true)) {
2474                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2475                    applyFactoryDefaultBrowserLPw(user.id);
2476                    primeDomainVerificationsLPw(user.id);
2477                }
2478            }
2479
2480            // Prepare storage for system user really early during boot,
2481            // since core system apps like SettingsProvider and SystemUI
2482            // can't wait for user to start
2483            final int storageFlags;
2484            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2485                storageFlags = StorageManager.FLAG_STORAGE_DE;
2486            } else {
2487                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2488            }
2489            reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM,
2490                    storageFlags);
2491
2492            // If this is first boot after an OTA, and a normal boot, then
2493            // we need to clear code cache directories.
2494            if (mIsUpgrade && !onlyCore) {
2495                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2496                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2497                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2498                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2499                        deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
2500                    }
2501                }
2502                ver.fingerprint = Build.FINGERPRINT;
2503            }
2504
2505            checkDefaultBrowser();
2506
2507            // clear only after permissions and other defaults have been updated
2508            mExistingSystemPackages.clear();
2509            mPromoteSystemApps = false;
2510
2511            // All the changes are done during package scanning.
2512            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2513
2514            // can downgrade to reader
2515            mSettings.writeLPr();
2516
2517            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2518                    SystemClock.uptimeMillis());
2519
2520            if (!mOnlyCore) {
2521                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2522                mRequiredInstallerPackage = getRequiredInstallerLPr();
2523                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2524                mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2525                        mIntentFilterVerifierComponent);
2526            } else {
2527                mRequiredVerifierPackage = null;
2528                mRequiredInstallerPackage = null;
2529                mIntentFilterVerifierComponent = null;
2530                mIntentFilterVerifier = null;
2531            }
2532
2533            mInstallerService = new PackageInstallerService(context, this);
2534            mSetupWizardPackage = getSetupWizardPackageName();
2535
2536            final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr();
2537            final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr();
2538            // both the installer and resolver must be present to enable ephemeral
2539            if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) {
2540                if (DEBUG_EPHEMERAL) {
2541                    Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent
2542                            + " installer:" + ephemeralInstallerComponent);
2543                }
2544                mEphemeralResolverComponent = ephemeralResolverComponent;
2545                mEphemeralInstallerComponent = ephemeralInstallerComponent;
2546                setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent);
2547                mEphemeralResolverConnection =
2548                        new EphemeralResolverConnection(mContext, mEphemeralResolverComponent);
2549            } else {
2550                if (DEBUG_EPHEMERAL) {
2551                    final String missingComponent =
2552                            (ephemeralResolverComponent == null)
2553                            ? (ephemeralInstallerComponent == null)
2554                                    ? "resolver and installer"
2555                                    : "resolver"
2556                            : "installer";
2557                    Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent);
2558                }
2559                mEphemeralResolverComponent = null;
2560                mEphemeralInstallerComponent = null;
2561                mEphemeralResolverConnection = null;
2562            }
2563
2564            mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this);
2565        } // synchronized (mPackages)
2566        } // synchronized (mInstallLock)
2567
2568        // Now after opening every single application zip, make sure they
2569        // are all flushed.  Not really needed, but keeps things nice and
2570        // tidy.
2571        Runtime.getRuntime().gc();
2572
2573        // The initial scanning above does many calls into installd while
2574        // holding the mPackages lock, but we're mostly interested in yelling
2575        // once we have a booted system.
2576        mInstaller.setWarnIfHeld(mPackages);
2577
2578        // Expose private service for system components to use.
2579        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2580    }
2581
2582    @Override
2583    public boolean isFirstBoot() {
2584        return !mRestoredSettings;
2585    }
2586
2587    @Override
2588    public boolean isOnlyCoreApps() {
2589        return mOnlyCore;
2590    }
2591
2592    @Override
2593    public boolean isUpgrade() {
2594        return mIsUpgrade;
2595    }
2596
2597    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2598        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2599
2600        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2601                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2602                UserHandle.USER_SYSTEM);
2603        if (matches.size() == 1) {
2604            return matches.get(0).getComponentInfo().packageName;
2605        } else {
2606            Log.e(TAG, "There should probably be exactly one verifier; found " + matches);
2607            return null;
2608        }
2609    }
2610
2611    private @NonNull String getRequiredInstallerLPr() {
2612        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
2613        intent.addCategory(Intent.CATEGORY_DEFAULT);
2614        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2615
2616        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2617                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2618                UserHandle.USER_SYSTEM);
2619        if (matches.size() == 1) {
2620            return matches.get(0).getComponentInfo().packageName;
2621        } else {
2622            throw new RuntimeException("There must be exactly one installer; found " + matches);
2623        }
2624    }
2625
2626    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
2627        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
2628
2629        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2630                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2631                UserHandle.USER_SYSTEM);
2632        ResolveInfo best = null;
2633        final int N = matches.size();
2634        for (int i = 0; i < N; i++) {
2635            final ResolveInfo cur = matches.get(i);
2636            final String packageName = cur.getComponentInfo().packageName;
2637            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
2638                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
2639                continue;
2640            }
2641
2642            if (best == null || cur.priority > best.priority) {
2643                best = cur;
2644            }
2645        }
2646
2647        if (best != null) {
2648            return best.getComponentInfo().getComponentName();
2649        } else {
2650            throw new RuntimeException("There must be at least one intent filter verifier");
2651        }
2652    }
2653
2654    private @Nullable ComponentName getEphemeralResolverLPr() {
2655        final String[] packageArray =
2656                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
2657        if (packageArray.length == 0) {
2658            if (DEBUG_EPHEMERAL) {
2659                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
2660            }
2661            return null;
2662        }
2663
2664        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
2665        final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
2666                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2667                UserHandle.USER_SYSTEM);
2668
2669        final int N = resolvers.size();
2670        if (N == 0) {
2671            if (DEBUG_EPHEMERAL) {
2672                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
2673            }
2674            return null;
2675        }
2676
2677        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
2678        for (int i = 0; i < N; i++) {
2679            final ResolveInfo info = resolvers.get(i);
2680
2681            if (info.serviceInfo == null) {
2682                continue;
2683            }
2684
2685            final String packageName = info.serviceInfo.packageName;
2686            if (!possiblePackages.contains(packageName)) {
2687                if (DEBUG_EPHEMERAL) {
2688                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
2689                            + " pkg: " + packageName + ", info:" + info);
2690                }
2691                continue;
2692            }
2693
2694            if (DEBUG_EPHEMERAL) {
2695                Slog.v(TAG, "Ephemeral resolver found;"
2696                        + " pkg: " + packageName + ", info:" + info);
2697            }
2698            return new ComponentName(packageName, info.serviceInfo.name);
2699        }
2700        if (DEBUG_EPHEMERAL) {
2701            Slog.v(TAG, "Ephemeral resolver NOT found");
2702        }
2703        return null;
2704    }
2705
2706    private @Nullable ComponentName getEphemeralInstallerLPr() {
2707        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
2708        intent.addCategory(Intent.CATEGORY_DEFAULT);
2709        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
2710
2711        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
2712                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2713                UserHandle.USER_SYSTEM);
2714        if (matches.size() == 0) {
2715            return null;
2716        } else if (matches.size() == 1) {
2717            return matches.get(0).getComponentInfo().getComponentName();
2718        } else {
2719            throw new RuntimeException(
2720                    "There must be at most one ephemeral installer; found " + matches);
2721        }
2722    }
2723
2724    private void primeDomainVerificationsLPw(int userId) {
2725        if (DEBUG_DOMAIN_VERIFICATION) {
2726            Slog.d(TAG, "Priming domain verifications in user " + userId);
2727        }
2728
2729        SystemConfig systemConfig = SystemConfig.getInstance();
2730        ArraySet<String> packages = systemConfig.getLinkedApps();
2731        ArraySet<String> domains = new ArraySet<String>();
2732
2733        for (String packageName : packages) {
2734            PackageParser.Package pkg = mPackages.get(packageName);
2735            if (pkg != null) {
2736                if (!pkg.isSystemApp()) {
2737                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
2738                    continue;
2739                }
2740
2741                domains.clear();
2742                for (PackageParser.Activity a : pkg.activities) {
2743                    for (ActivityIntentInfo filter : a.intents) {
2744                        if (hasValidDomains(filter)) {
2745                            domains.addAll(filter.getHostsList());
2746                        }
2747                    }
2748                }
2749
2750                if (domains.size() > 0) {
2751                    if (DEBUG_DOMAIN_VERIFICATION) {
2752                        Slog.v(TAG, "      + " + packageName);
2753                    }
2754                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
2755                    // state w.r.t. the formal app-linkage "no verification attempted" state;
2756                    // and then 'always' in the per-user state actually used for intent resolution.
2757                    final IntentFilterVerificationInfo ivi;
2758                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName,
2759                            new ArrayList<String>(domains));
2760                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
2761                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
2762                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
2763                } else {
2764                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
2765                            + "' does not handle web links");
2766                }
2767            } else {
2768                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
2769            }
2770        }
2771
2772        scheduleWritePackageRestrictionsLocked(userId);
2773        scheduleWriteSettingsLocked();
2774    }
2775
2776    private void applyFactoryDefaultBrowserLPw(int userId) {
2777        // The default browser app's package name is stored in a string resource,
2778        // with a product-specific overlay used for vendor customization.
2779        String browserPkg = mContext.getResources().getString(
2780                com.android.internal.R.string.default_browser);
2781        if (!TextUtils.isEmpty(browserPkg)) {
2782            // non-empty string => required to be a known package
2783            PackageSetting ps = mSettings.mPackages.get(browserPkg);
2784            if (ps == null) {
2785                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
2786                browserPkg = null;
2787            } else {
2788                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2789            }
2790        }
2791
2792        // Nothing valid explicitly set? Make the factory-installed browser the explicit
2793        // default.  If there's more than one, just leave everything alone.
2794        if (browserPkg == null) {
2795            calculateDefaultBrowserLPw(userId);
2796        }
2797    }
2798
2799    private void calculateDefaultBrowserLPw(int userId) {
2800        List<String> allBrowsers = resolveAllBrowserApps(userId);
2801        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
2802        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
2803    }
2804
2805    private List<String> resolveAllBrowserApps(int userId) {
2806        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
2807        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
2808                PackageManager.MATCH_ALL, userId);
2809
2810        final int count = list.size();
2811        List<String> result = new ArrayList<String>(count);
2812        for (int i=0; i<count; i++) {
2813            ResolveInfo info = list.get(i);
2814            if (info.activityInfo == null
2815                    || !info.handleAllWebDataURI
2816                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
2817                    || result.contains(info.activityInfo.packageName)) {
2818                continue;
2819            }
2820            result.add(info.activityInfo.packageName);
2821        }
2822
2823        return result;
2824    }
2825
2826    private boolean packageIsBrowser(String packageName, int userId) {
2827        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
2828                PackageManager.MATCH_ALL, userId);
2829        final int N = list.size();
2830        for (int i = 0; i < N; i++) {
2831            ResolveInfo info = list.get(i);
2832            if (packageName.equals(info.activityInfo.packageName)) {
2833                return true;
2834            }
2835        }
2836        return false;
2837    }
2838
2839    private void checkDefaultBrowser() {
2840        final int myUserId = UserHandle.myUserId();
2841        final String packageName = getDefaultBrowserPackageName(myUserId);
2842        if (packageName != null) {
2843            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
2844            if (info == null) {
2845                Slog.w(TAG, "Default browser no longer installed: " + packageName);
2846                synchronized (mPackages) {
2847                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
2848                }
2849            }
2850        }
2851    }
2852
2853    @Override
2854    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2855            throws RemoteException {
2856        try {
2857            return super.onTransact(code, data, reply, flags);
2858        } catch (RuntimeException e) {
2859            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
2860                Slog.wtf(TAG, "Package Manager Crash", e);
2861            }
2862            throw e;
2863        }
2864    }
2865
2866    void cleanupInstallFailedPackage(PackageSetting ps) {
2867        logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
2868
2869        removeDataDirsLI(ps.volumeUuid, ps.name);
2870        if (ps.codePath != null) {
2871            removeCodePathLI(ps.codePath);
2872        }
2873        if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
2874            if (ps.resourcePath.isDirectory()) {
2875                FileUtils.deleteContents(ps.resourcePath);
2876            }
2877            ps.resourcePath.delete();
2878        }
2879        mSettings.removePackageLPw(ps.name);
2880    }
2881
2882    static int[] appendInts(int[] cur, int[] add) {
2883        if (add == null) return cur;
2884        if (cur == null) return add;
2885        final int N = add.length;
2886        for (int i=0; i<N; i++) {
2887            cur = appendInt(cur, add[i]);
2888        }
2889        return cur;
2890    }
2891
2892    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
2893        if (!sUserManager.exists(userId)) return null;
2894        if (ps == null) {
2895            return null;
2896        }
2897        final PackageParser.Package p = ps.pkg;
2898        if (p == null) {
2899            return null;
2900        }
2901
2902        final PermissionsState permissionsState = ps.getPermissionsState();
2903
2904        final int[] gids = permissionsState.computeGids(userId);
2905        final Set<String> permissions = permissionsState.getPermissions(userId);
2906        final PackageUserState state = ps.readUserState(userId);
2907
2908        return PackageParser.generatePackageInfo(p, gids, flags,
2909                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
2910    }
2911
2912    @Override
2913    public void checkPackageStartable(String packageName, int userId) {
2914        final boolean userKeyUnlocked = isUserKeyUnlocked(userId);
2915
2916        synchronized (mPackages) {
2917            final PackageSetting ps = mSettings.mPackages.get(packageName);
2918            if (ps == null) {
2919                throw new SecurityException("Package " + packageName + " was not found!");
2920            }
2921
2922            if (!ps.getInstalled(userId)) {
2923                throw new SecurityException(
2924                        "Package " + packageName + " was not installed for user " + userId + "!");
2925            }
2926
2927            if (mSafeMode && !ps.isSystem()) {
2928                throw new SecurityException("Package " + packageName + " not a system app!");
2929            }
2930
2931            if (ps.frozen) {
2932                throw new SecurityException("Package " + packageName + " is currently frozen!");
2933            }
2934
2935            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
2936                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
2937                throw new SecurityException("Package " + packageName + " is not encryption aware!");
2938            }
2939        }
2940    }
2941
2942    @Override
2943    public boolean isPackageAvailable(String packageName, int userId) {
2944        if (!sUserManager.exists(userId)) return false;
2945        enforceCrossUserPermission(Binder.getCallingUid(), userId,
2946                false /* requireFullPermission */, false /* checkShell */, "is package available");
2947        synchronized (mPackages) {
2948            PackageParser.Package p = mPackages.get(packageName);
2949            if (p != null) {
2950                final PackageSetting ps = (PackageSetting) p.mExtras;
2951                if (ps != null) {
2952                    final PackageUserState state = ps.readUserState(userId);
2953                    if (state != null) {
2954                        return PackageParser.isAvailable(state);
2955                    }
2956                }
2957            }
2958        }
2959        return false;
2960    }
2961
2962    @Override
2963    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
2964        if (!sUserManager.exists(userId)) return null;
2965        flags = updateFlagsForPackage(flags, userId, packageName);
2966        enforceCrossUserPermission(Binder.getCallingUid(), userId,
2967                false /* requireFullPermission */, false /* checkShell */, "get package info");
2968        // reader
2969        synchronized (mPackages) {
2970            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
2971            PackageParser.Package p = null;
2972            if (matchFactoryOnly) {
2973                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
2974                if (ps != null) {
2975                    return generatePackageInfo(ps, flags, userId);
2976                }
2977            }
2978            if (p == null) {
2979                p = mPackages.get(packageName);
2980                if (matchFactoryOnly && !isSystemApp(p)) {
2981                    return null;
2982                }
2983            }
2984            if (DEBUG_PACKAGE_INFO)
2985                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
2986            if (p != null) {
2987                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
2988            }
2989            if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
2990                final PackageSetting ps = mSettings.mPackages.get(packageName);
2991                return generatePackageInfo(ps, flags, userId);
2992            }
2993        }
2994        return null;
2995    }
2996
2997    @Override
2998    public String[] currentToCanonicalPackageNames(String[] names) {
2999        String[] out = new String[names.length];
3000        // reader
3001        synchronized (mPackages) {
3002            for (int i=names.length-1; i>=0; i--) {
3003                PackageSetting ps = mSettings.mPackages.get(names[i]);
3004                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3005            }
3006        }
3007        return out;
3008    }
3009
3010    @Override
3011    public String[] canonicalToCurrentPackageNames(String[] names) {
3012        String[] out = new String[names.length];
3013        // reader
3014        synchronized (mPackages) {
3015            for (int i=names.length-1; i>=0; i--) {
3016                String cur = mSettings.mRenamedPackages.get(names[i]);
3017                out[i] = cur != null ? cur : names[i];
3018            }
3019        }
3020        return out;
3021    }
3022
3023    @Override
3024    public int getPackageUid(String packageName, int flags, int userId) {
3025        if (!sUserManager.exists(userId)) return -1;
3026        flags = updateFlagsForPackage(flags, userId, packageName);
3027        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3028                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3029
3030        // reader
3031        synchronized (mPackages) {
3032            final PackageParser.Package p = mPackages.get(packageName);
3033            if (p != null && p.isMatch(flags)) {
3034                return UserHandle.getUid(userId, p.applicationInfo.uid);
3035            }
3036            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3037                final PackageSetting ps = mSettings.mPackages.get(packageName);
3038                if (ps != null && ps.isMatch(flags)) {
3039                    return UserHandle.getUid(userId, ps.appId);
3040                }
3041            }
3042        }
3043
3044        return -1;
3045    }
3046
3047    @Override
3048    public int[] getPackageGids(String packageName, int flags, int userId) {
3049        if (!sUserManager.exists(userId)) return null;
3050        flags = updateFlagsForPackage(flags, userId, packageName);
3051        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3052                false /* requireFullPermission */, false /* checkShell */,
3053                "getPackageGids");
3054
3055        // reader
3056        synchronized (mPackages) {
3057            final PackageParser.Package p = mPackages.get(packageName);
3058            if (p != null && p.isMatch(flags)) {
3059                PackageSetting ps = (PackageSetting) p.mExtras;
3060                return ps.getPermissionsState().computeGids(userId);
3061            }
3062            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3063                final PackageSetting ps = mSettings.mPackages.get(packageName);
3064                if (ps != null && ps.isMatch(flags)) {
3065                    return ps.getPermissionsState().computeGids(userId);
3066                }
3067            }
3068        }
3069
3070        return null;
3071    }
3072
3073    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3074        if (bp.perm != null) {
3075            return PackageParser.generatePermissionInfo(bp.perm, flags);
3076        }
3077        PermissionInfo pi = new PermissionInfo();
3078        pi.name = bp.name;
3079        pi.packageName = bp.sourcePackage;
3080        pi.nonLocalizedLabel = bp.name;
3081        pi.protectionLevel = bp.protectionLevel;
3082        return pi;
3083    }
3084
3085    @Override
3086    public PermissionInfo getPermissionInfo(String name, int flags) {
3087        // reader
3088        synchronized (mPackages) {
3089            final BasePermission p = mSettings.mPermissions.get(name);
3090            if (p != null) {
3091                return generatePermissionInfo(p, flags);
3092            }
3093            return null;
3094        }
3095    }
3096
3097    @Override
3098    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3099            int flags) {
3100        // reader
3101        synchronized (mPackages) {
3102            if (group != null && !mPermissionGroups.containsKey(group)) {
3103                // This is thrown as NameNotFoundException
3104                return null;
3105            }
3106
3107            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3108            for (BasePermission p : mSettings.mPermissions.values()) {
3109                if (group == null) {
3110                    if (p.perm == null || p.perm.info.group == null) {
3111                        out.add(generatePermissionInfo(p, flags));
3112                    }
3113                } else {
3114                    if (p.perm != null && group.equals(p.perm.info.group)) {
3115                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3116                    }
3117                }
3118            }
3119            return new ParceledListSlice<>(out);
3120        }
3121    }
3122
3123    @Override
3124    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3125        // reader
3126        synchronized (mPackages) {
3127            return PackageParser.generatePermissionGroupInfo(
3128                    mPermissionGroups.get(name), flags);
3129        }
3130    }
3131
3132    @Override
3133    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3134        // reader
3135        synchronized (mPackages) {
3136            final int N = mPermissionGroups.size();
3137            ArrayList<PermissionGroupInfo> out
3138                    = new ArrayList<PermissionGroupInfo>(N);
3139            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3140                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3141            }
3142            return new ParceledListSlice<>(out);
3143        }
3144    }
3145
3146    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3147            int userId) {
3148        if (!sUserManager.exists(userId)) return null;
3149        PackageSetting ps = mSettings.mPackages.get(packageName);
3150        if (ps != null) {
3151            if (ps.pkg == null) {
3152                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3153                if (pInfo != null) {
3154                    return pInfo.applicationInfo;
3155                }
3156                return null;
3157            }
3158            return PackageParser.generateApplicationInfo(ps.pkg, flags,
3159                    ps.readUserState(userId), userId);
3160        }
3161        return null;
3162    }
3163
3164    @Override
3165    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3166        if (!sUserManager.exists(userId)) return null;
3167        flags = updateFlagsForApplication(flags, userId, packageName);
3168        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3169                false /* requireFullPermission */, false /* checkShell */, "get application info");
3170        // writer
3171        synchronized (mPackages) {
3172            PackageParser.Package p = mPackages.get(packageName);
3173            if (DEBUG_PACKAGE_INFO) Log.v(
3174                    TAG, "getApplicationInfo " + packageName
3175                    + ": " + p);
3176            if (p != null) {
3177                PackageSetting ps = mSettings.mPackages.get(packageName);
3178                if (ps == null) return null;
3179                // Note: isEnabledLP() does not apply here - always return info
3180                return PackageParser.generateApplicationInfo(
3181                        p, flags, ps.readUserState(userId), userId);
3182            }
3183            if ("android".equals(packageName)||"system".equals(packageName)) {
3184                return mAndroidApplication;
3185            }
3186            if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
3187                return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
3188            }
3189        }
3190        return null;
3191    }
3192
3193    @Override
3194    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3195            final IPackageDataObserver observer) {
3196        mContext.enforceCallingOrSelfPermission(
3197                android.Manifest.permission.CLEAR_APP_CACHE, null);
3198        // Queue up an async operation since clearing cache may take a little while.
3199        mHandler.post(new Runnable() {
3200            public void run() {
3201                mHandler.removeCallbacks(this);
3202                boolean success = true;
3203                synchronized (mInstallLock) {
3204                    try {
3205                        mInstaller.freeCache(volumeUuid, freeStorageSize);
3206                    } catch (InstallerException e) {
3207                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3208                        success = false;
3209                    }
3210                }
3211                if (observer != null) {
3212                    try {
3213                        observer.onRemoveCompleted(null, success);
3214                    } catch (RemoteException e) {
3215                        Slog.w(TAG, "RemoveException when invoking call back");
3216                    }
3217                }
3218            }
3219        });
3220    }
3221
3222    @Override
3223    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3224            final IntentSender pi) {
3225        mContext.enforceCallingOrSelfPermission(
3226                android.Manifest.permission.CLEAR_APP_CACHE, null);
3227        // Queue up an async operation since clearing cache may take a little while.
3228        mHandler.post(new Runnable() {
3229            public void run() {
3230                mHandler.removeCallbacks(this);
3231                boolean success = true;
3232                synchronized (mInstallLock) {
3233                    try {
3234                        mInstaller.freeCache(volumeUuid, freeStorageSize);
3235                    } catch (InstallerException e) {
3236                        Slog.w(TAG, "Couldn't clear application caches: " + e);
3237                        success = false;
3238                    }
3239                }
3240                if(pi != null) {
3241                    try {
3242                        // Callback via pending intent
3243                        int code = success ? 1 : 0;
3244                        pi.sendIntent(null, code, null,
3245                                null, null);
3246                    } catch (SendIntentException e1) {
3247                        Slog.i(TAG, "Failed to send pending intent");
3248                    }
3249                }
3250            }
3251        });
3252    }
3253
3254    void freeStorage(String volumeUuid, long freeStorageSize) throws IOException {
3255        synchronized (mInstallLock) {
3256            try {
3257                mInstaller.freeCache(volumeUuid, freeStorageSize);
3258            } catch (InstallerException e) {
3259                throw new IOException("Failed to free enough space", e);
3260            }
3261        }
3262    }
3263
3264    /**
3265     * Return if the user key is currently unlocked.
3266     */
3267    private boolean isUserKeyUnlocked(int userId) {
3268        if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3269            final IMountService mount = IMountService.Stub
3270                    .asInterface(ServiceManager.getService("mount"));
3271            if (mount == null) {
3272                Slog.w(TAG, "Early during boot, assuming locked");
3273                return false;
3274            }
3275            final long token = Binder.clearCallingIdentity();
3276            try {
3277                return mount.isUserKeyUnlocked(userId);
3278            } catch (RemoteException e) {
3279                throw e.rethrowAsRuntimeException();
3280            } finally {
3281                Binder.restoreCallingIdentity(token);
3282            }
3283        } else {
3284            return true;
3285        }
3286    }
3287
3288    /**
3289     * Update given flags based on encryption status of current user.
3290     */
3291    private int updateFlags(int flags, int userId) {
3292        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3293                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3294            // Caller expressed an explicit opinion about what encryption
3295            // aware/unaware components they want to see, so fall through and
3296            // give them what they want
3297        } else {
3298            // Caller expressed no opinion, so match based on user state
3299            if (isUserKeyUnlocked(userId)) {
3300                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3301            } else {
3302                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3303            }
3304        }
3305        return flags;
3306    }
3307
3308    /**
3309     * Update given flags when being used to request {@link PackageInfo}.
3310     */
3311    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3312        boolean triaged = true;
3313        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3314                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3315            // Caller is asking for component details, so they'd better be
3316            // asking for specific encryption matching behavior, or be triaged
3317            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3318                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
3319                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3320                triaged = false;
3321            }
3322        }
3323        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3324                | PackageManager.MATCH_SYSTEM_ONLY
3325                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3326            triaged = false;
3327        }
3328        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3329            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3330                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3331        }
3332        return updateFlags(flags, userId);
3333    }
3334
3335    /**
3336     * Update given flags when being used to request {@link ApplicationInfo}.
3337     */
3338    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
3339        return updateFlagsForPackage(flags, userId, cookie);
3340    }
3341
3342    /**
3343     * Update given flags when being used to request {@link ComponentInfo}.
3344     */
3345    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
3346        if (cookie instanceof Intent) {
3347            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
3348                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
3349            }
3350        }
3351
3352        boolean triaged = true;
3353        // Caller is asking for component details, so they'd better be
3354        // asking for specific encryption matching behavior, or be triaged
3355        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3356                | PackageManager.MATCH_DIRECT_BOOT_AWARE
3357                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3358            triaged = false;
3359        }
3360        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
3361            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
3362                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
3363        }
3364
3365        return updateFlags(flags, userId);
3366    }
3367
3368    /**
3369     * Update given flags when being used to request {@link ResolveInfo}.
3370     */
3371    int updateFlagsForResolve(int flags, int userId, Object cookie) {
3372        // Safe mode means we shouldn't match any third-party components
3373        if (mSafeMode) {
3374            flags |= PackageManager.MATCH_SYSTEM_ONLY;
3375        }
3376
3377        return updateFlagsForComponent(flags, userId, cookie);
3378    }
3379
3380    @Override
3381    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
3382        if (!sUserManager.exists(userId)) return null;
3383        flags = updateFlagsForComponent(flags, userId, component);
3384        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3385                false /* requireFullPermission */, false /* checkShell */, "get activity info");
3386        synchronized (mPackages) {
3387            PackageParser.Activity a = mActivities.mActivities.get(component);
3388
3389            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
3390            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3391                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3392                if (ps == null) return null;
3393                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3394                        userId);
3395            }
3396            if (mResolveComponentName.equals(component)) {
3397                return PackageParser.generateActivityInfo(mResolveActivity, flags,
3398                        new PackageUserState(), userId);
3399            }
3400        }
3401        return null;
3402    }
3403
3404    @Override
3405    public boolean activitySupportsIntent(ComponentName component, Intent intent,
3406            String resolvedType) {
3407        synchronized (mPackages) {
3408            if (component.equals(mResolveComponentName)) {
3409                // The resolver supports EVERYTHING!
3410                return true;
3411            }
3412            PackageParser.Activity a = mActivities.mActivities.get(component);
3413            if (a == null) {
3414                return false;
3415            }
3416            for (int i=0; i<a.intents.size(); i++) {
3417                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
3418                        intent.getData(), intent.getCategories(), TAG) >= 0) {
3419                    return true;
3420                }
3421            }
3422            return false;
3423        }
3424    }
3425
3426    @Override
3427    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
3428        if (!sUserManager.exists(userId)) return null;
3429        flags = updateFlagsForComponent(flags, userId, component);
3430        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3431                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
3432        synchronized (mPackages) {
3433            PackageParser.Activity a = mReceivers.mActivities.get(component);
3434            if (DEBUG_PACKAGE_INFO) Log.v(
3435                TAG, "getReceiverInfo " + component + ": " + a);
3436            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
3437                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3438                if (ps == null) return null;
3439                return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
3440                        userId);
3441            }
3442        }
3443        return null;
3444    }
3445
3446    @Override
3447    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
3448        if (!sUserManager.exists(userId)) return null;
3449        flags = updateFlagsForComponent(flags, userId, component);
3450        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3451                false /* requireFullPermission */, false /* checkShell */, "get service info");
3452        synchronized (mPackages) {
3453            PackageParser.Service s = mServices.mServices.get(component);
3454            if (DEBUG_PACKAGE_INFO) Log.v(
3455                TAG, "getServiceInfo " + component + ": " + s);
3456            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
3457                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3458                if (ps == null) return null;
3459                return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
3460                        userId);
3461            }
3462        }
3463        return null;
3464    }
3465
3466    @Override
3467    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
3468        if (!sUserManager.exists(userId)) return null;
3469        flags = updateFlagsForComponent(flags, userId, component);
3470        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3471                false /* requireFullPermission */, false /* checkShell */, "get provider info");
3472        synchronized (mPackages) {
3473            PackageParser.Provider p = mProviders.mProviders.get(component);
3474            if (DEBUG_PACKAGE_INFO) Log.v(
3475                TAG, "getProviderInfo " + component + ": " + p);
3476            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
3477                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
3478                if (ps == null) return null;
3479                return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
3480                        userId);
3481            }
3482        }
3483        return null;
3484    }
3485
3486    @Override
3487    public String[] getSystemSharedLibraryNames() {
3488        Set<String> libSet;
3489        synchronized (mPackages) {
3490            libSet = mSharedLibraries.keySet();
3491            int size = libSet.size();
3492            if (size > 0) {
3493                String[] libs = new String[size];
3494                libSet.toArray(libs);
3495                return libs;
3496            }
3497        }
3498        return null;
3499    }
3500
3501    @Override
3502    public @Nullable String getServicesSystemSharedLibraryPackageName() {
3503        synchronized (mPackages) {
3504            SharedLibraryEntry libraryEntry = mSharedLibraries.get(
3505                    PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
3506            if (libraryEntry != null) {
3507                return libraryEntry.apk;
3508            }
3509        }
3510        return null;
3511    }
3512
3513    @Override
3514    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
3515        synchronized (mPackages) {
3516            final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
3517
3518            final FeatureInfo fi = new FeatureInfo();
3519            fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
3520                    FeatureInfo.GL_ES_VERSION_UNDEFINED);
3521            res.add(fi);
3522
3523            return new ParceledListSlice<>(res);
3524        }
3525    }
3526
3527    @Override
3528    public boolean hasSystemFeature(String name, int version) {
3529        synchronized (mPackages) {
3530            final FeatureInfo feat = mAvailableFeatures.get(name);
3531            if (feat == null) {
3532                return false;
3533            } else {
3534                return feat.version >= version;
3535            }
3536        }
3537    }
3538
3539    @Override
3540    public int checkPermission(String permName, String pkgName, int userId) {
3541        if (!sUserManager.exists(userId)) {
3542            return PackageManager.PERMISSION_DENIED;
3543        }
3544
3545        synchronized (mPackages) {
3546            final PackageParser.Package p = mPackages.get(pkgName);
3547            if (p != null && p.mExtras != null) {
3548                final PackageSetting ps = (PackageSetting) p.mExtras;
3549                final PermissionsState permissionsState = ps.getPermissionsState();
3550                if (permissionsState.hasPermission(permName, userId)) {
3551                    return PackageManager.PERMISSION_GRANTED;
3552                }
3553                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3554                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3555                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3556                    return PackageManager.PERMISSION_GRANTED;
3557                }
3558            }
3559        }
3560
3561        return PackageManager.PERMISSION_DENIED;
3562    }
3563
3564    @Override
3565    public int checkUidPermission(String permName, int uid) {
3566        final int userId = UserHandle.getUserId(uid);
3567
3568        if (!sUserManager.exists(userId)) {
3569            return PackageManager.PERMISSION_DENIED;
3570        }
3571
3572        synchronized (mPackages) {
3573            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
3574            if (obj != null) {
3575                final SettingBase ps = (SettingBase) obj;
3576                final PermissionsState permissionsState = ps.getPermissionsState();
3577                if (permissionsState.hasPermission(permName, userId)) {
3578                    return PackageManager.PERMISSION_GRANTED;
3579                }
3580                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
3581                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
3582                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
3583                    return PackageManager.PERMISSION_GRANTED;
3584                }
3585            } else {
3586                ArraySet<String> perms = mSystemPermissions.get(uid);
3587                if (perms != null) {
3588                    if (perms.contains(permName)) {
3589                        return PackageManager.PERMISSION_GRANTED;
3590                    }
3591                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
3592                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
3593                        return PackageManager.PERMISSION_GRANTED;
3594                    }
3595                }
3596            }
3597        }
3598
3599        return PackageManager.PERMISSION_DENIED;
3600    }
3601
3602    @Override
3603    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
3604        if (UserHandle.getCallingUserId() != userId) {
3605            mContext.enforceCallingPermission(
3606                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
3607                    "isPermissionRevokedByPolicy for user " + userId);
3608        }
3609
3610        if (checkPermission(permission, packageName, userId)
3611                == PackageManager.PERMISSION_GRANTED) {
3612            return false;
3613        }
3614
3615        final long identity = Binder.clearCallingIdentity();
3616        try {
3617            final int flags = getPermissionFlags(permission, packageName, userId);
3618            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
3619        } finally {
3620            Binder.restoreCallingIdentity(identity);
3621        }
3622    }
3623
3624    @Override
3625    public String getPermissionControllerPackageName() {
3626        synchronized (mPackages) {
3627            return mRequiredInstallerPackage;
3628        }
3629    }
3630
3631    /**
3632     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
3633     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
3634     * @param checkShell whether to prevent shell from access if there's a debugging restriction
3635     * @param message the message to log on security exception
3636     */
3637    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
3638            boolean checkShell, String message) {
3639        if (userId < 0) {
3640            throw new IllegalArgumentException("Invalid userId " + userId);
3641        }
3642        if (checkShell) {
3643            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
3644        }
3645        if (userId == UserHandle.getUserId(callingUid)) return;
3646        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3647            if (requireFullPermission) {
3648                mContext.enforceCallingOrSelfPermission(
3649                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3650            } else {
3651                try {
3652                    mContext.enforceCallingOrSelfPermission(
3653                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
3654                } catch (SecurityException se) {
3655                    mContext.enforceCallingOrSelfPermission(
3656                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
3657                }
3658            }
3659        }
3660    }
3661
3662    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
3663        if (callingUid == Process.SHELL_UID) {
3664            if (userHandle >= 0
3665                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
3666                throw new SecurityException("Shell does not have permission to access user "
3667                        + userHandle);
3668            } else if (userHandle < 0) {
3669                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
3670                        + Debug.getCallers(3));
3671            }
3672        }
3673    }
3674
3675    private BasePermission findPermissionTreeLP(String permName) {
3676        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
3677            if (permName.startsWith(bp.name) &&
3678                    permName.length() > bp.name.length() &&
3679                    permName.charAt(bp.name.length()) == '.') {
3680                return bp;
3681            }
3682        }
3683        return null;
3684    }
3685
3686    private BasePermission checkPermissionTreeLP(String permName) {
3687        if (permName != null) {
3688            BasePermission bp = findPermissionTreeLP(permName);
3689            if (bp != null) {
3690                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
3691                    return bp;
3692                }
3693                throw new SecurityException("Calling uid "
3694                        + Binder.getCallingUid()
3695                        + " is not allowed to add to permission tree "
3696                        + bp.name + " owned by uid " + bp.uid);
3697            }
3698        }
3699        throw new SecurityException("No permission tree found for " + permName);
3700    }
3701
3702    static boolean compareStrings(CharSequence s1, CharSequence s2) {
3703        if (s1 == null) {
3704            return s2 == null;
3705        }
3706        if (s2 == null) {
3707            return false;
3708        }
3709        if (s1.getClass() != s2.getClass()) {
3710            return false;
3711        }
3712        return s1.equals(s2);
3713    }
3714
3715    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
3716        if (pi1.icon != pi2.icon) return false;
3717        if (pi1.logo != pi2.logo) return false;
3718        if (pi1.protectionLevel != pi2.protectionLevel) return false;
3719        if (!compareStrings(pi1.name, pi2.name)) return false;
3720        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
3721        // We'll take care of setting this one.
3722        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
3723        // These are not currently stored in settings.
3724        //if (!compareStrings(pi1.group, pi2.group)) return false;
3725        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
3726        //if (pi1.labelRes != pi2.labelRes) return false;
3727        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
3728        return true;
3729    }
3730
3731    int permissionInfoFootprint(PermissionInfo info) {
3732        int size = info.name.length();
3733        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
3734        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
3735        return size;
3736    }
3737
3738    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
3739        int size = 0;
3740        for (BasePermission perm : mSettings.mPermissions.values()) {
3741            if (perm.uid == tree.uid) {
3742                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
3743            }
3744        }
3745        return size;
3746    }
3747
3748    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
3749        // We calculate the max size of permissions defined by this uid and throw
3750        // if that plus the size of 'info' would exceed our stated maximum.
3751        if (tree.uid != Process.SYSTEM_UID) {
3752            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
3753            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
3754                throw new SecurityException("Permission tree size cap exceeded");
3755            }
3756        }
3757    }
3758
3759    boolean addPermissionLocked(PermissionInfo info, boolean async) {
3760        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
3761            throw new SecurityException("Label must be specified in permission");
3762        }
3763        BasePermission tree = checkPermissionTreeLP(info.name);
3764        BasePermission bp = mSettings.mPermissions.get(info.name);
3765        boolean added = bp == null;
3766        boolean changed = true;
3767        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
3768        if (added) {
3769            enforcePermissionCapLocked(info, tree);
3770            bp = new BasePermission(info.name, tree.sourcePackage,
3771                    BasePermission.TYPE_DYNAMIC);
3772        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
3773            throw new SecurityException(
3774                    "Not allowed to modify non-dynamic permission "
3775                    + info.name);
3776        } else {
3777            if (bp.protectionLevel == fixedLevel
3778                    && bp.perm.owner.equals(tree.perm.owner)
3779                    && bp.uid == tree.uid
3780                    && comparePermissionInfos(bp.perm.info, info)) {
3781                changed = false;
3782            }
3783        }
3784        bp.protectionLevel = fixedLevel;
3785        info = new PermissionInfo(info);
3786        info.protectionLevel = fixedLevel;
3787        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
3788        bp.perm.info.packageName = tree.perm.info.packageName;
3789        bp.uid = tree.uid;
3790        if (added) {
3791            mSettings.mPermissions.put(info.name, bp);
3792        }
3793        if (changed) {
3794            if (!async) {
3795                mSettings.writeLPr();
3796            } else {
3797                scheduleWriteSettingsLocked();
3798            }
3799        }
3800        return added;
3801    }
3802
3803    @Override
3804    public boolean addPermission(PermissionInfo info) {
3805        synchronized (mPackages) {
3806            return addPermissionLocked(info, false);
3807        }
3808    }
3809
3810    @Override
3811    public boolean addPermissionAsync(PermissionInfo info) {
3812        synchronized (mPackages) {
3813            return addPermissionLocked(info, true);
3814        }
3815    }
3816
3817    @Override
3818    public void removePermission(String name) {
3819        synchronized (mPackages) {
3820            checkPermissionTreeLP(name);
3821            BasePermission bp = mSettings.mPermissions.get(name);
3822            if (bp != null) {
3823                if (bp.type != BasePermission.TYPE_DYNAMIC) {
3824                    throw new SecurityException(
3825                            "Not allowed to modify non-dynamic permission "
3826                            + name);
3827                }
3828                mSettings.mPermissions.remove(name);
3829                mSettings.writeLPr();
3830            }
3831        }
3832    }
3833
3834    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
3835            BasePermission bp) {
3836        int index = pkg.requestedPermissions.indexOf(bp.name);
3837        if (index == -1) {
3838            throw new SecurityException("Package " + pkg.packageName
3839                    + " has not requested permission " + bp.name);
3840        }
3841        if (!bp.isRuntime() && !bp.isDevelopment()) {
3842            throw new SecurityException("Permission " + bp.name
3843                    + " is not a changeable permission type");
3844        }
3845    }
3846
3847    @Override
3848    public void grantRuntimePermission(String packageName, String name, final int userId) {
3849        if (!sUserManager.exists(userId)) {
3850            Log.e(TAG, "No such user:" + userId);
3851            return;
3852        }
3853
3854        mContext.enforceCallingOrSelfPermission(
3855                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
3856                "grantRuntimePermission");
3857
3858        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3859                true /* requireFullPermission */, true /* checkShell */,
3860                "grantRuntimePermission");
3861
3862        final int uid;
3863        final SettingBase sb;
3864
3865        synchronized (mPackages) {
3866            final PackageParser.Package pkg = mPackages.get(packageName);
3867            if (pkg == null) {
3868                throw new IllegalArgumentException("Unknown package: " + packageName);
3869            }
3870
3871            final BasePermission bp = mSettings.mPermissions.get(name);
3872            if (bp == null) {
3873                throw new IllegalArgumentException("Unknown permission: " + name);
3874            }
3875
3876            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3877
3878            // If a permission review is required for legacy apps we represent
3879            // their permissions as always granted runtime ones since we need
3880            // to keep the review required permission flag per user while an
3881            // install permission's state is shared across all users.
3882            if (Build.PERMISSIONS_REVIEW_REQUIRED
3883                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3884                    && bp.isRuntime()) {
3885                return;
3886            }
3887
3888            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
3889            sb = (SettingBase) pkg.mExtras;
3890            if (sb == null) {
3891                throw new IllegalArgumentException("Unknown package: " + packageName);
3892            }
3893
3894            final PermissionsState permissionsState = sb.getPermissionsState();
3895
3896            final int flags = permissionsState.getPermissionFlags(name, userId);
3897            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
3898                throw new SecurityException("Cannot grant system fixed permission "
3899                        + name + " for package " + packageName);
3900            }
3901
3902            if (bp.isDevelopment()) {
3903                // Development permissions must be handled specially, since they are not
3904                // normal runtime permissions.  For now they apply to all users.
3905                if (permissionsState.grantInstallPermission(bp) !=
3906                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
3907                    scheduleWriteSettingsLocked();
3908                }
3909                return;
3910            }
3911
3912            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3913                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
3914                return;
3915            }
3916
3917            final int result = permissionsState.grantRuntimePermission(bp, userId);
3918            switch (result) {
3919                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
3920                    return;
3921                }
3922
3923                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
3924                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
3925                    mHandler.post(new Runnable() {
3926                        @Override
3927                        public void run() {
3928                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
3929                        }
3930                    });
3931                }
3932                break;
3933            }
3934
3935            mOnPermissionChangeListeners.onPermissionsChanged(uid);
3936
3937            // Not critical if that is lost - app has to request again.
3938            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
3939        }
3940
3941        // Only need to do this if user is initialized. Otherwise it's a new user
3942        // and there are no processes running as the user yet and there's no need
3943        // to make an expensive call to remount processes for the changed permissions.
3944        if (READ_EXTERNAL_STORAGE.equals(name)
3945                || WRITE_EXTERNAL_STORAGE.equals(name)) {
3946            final long token = Binder.clearCallingIdentity();
3947            try {
3948                if (sUserManager.isInitialized(userId)) {
3949                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3950                            MountServiceInternal.class);
3951                    mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName);
3952                }
3953            } finally {
3954                Binder.restoreCallingIdentity(token);
3955            }
3956        }
3957    }
3958
3959    @Override
3960    public void revokeRuntimePermission(String packageName, String name, int userId) {
3961        if (!sUserManager.exists(userId)) {
3962            Log.e(TAG, "No such user:" + userId);
3963            return;
3964        }
3965
3966        mContext.enforceCallingOrSelfPermission(
3967                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
3968                "revokeRuntimePermission");
3969
3970        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3971                true /* requireFullPermission */, true /* checkShell */,
3972                "revokeRuntimePermission");
3973
3974        final int appId;
3975
3976        synchronized (mPackages) {
3977            final PackageParser.Package pkg = mPackages.get(packageName);
3978            if (pkg == null) {
3979                throw new IllegalArgumentException("Unknown package: " + packageName);
3980            }
3981
3982            final BasePermission bp = mSettings.mPermissions.get(name);
3983            if (bp == null) {
3984                throw new IllegalArgumentException("Unknown permission: " + name);
3985            }
3986
3987            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
3988
3989            // If a permission review is required for legacy apps we represent
3990            // their permissions as always granted runtime ones since we need
3991            // to keep the review required permission flag per user while an
3992            // install permission's state is shared across all users.
3993            if (Build.PERMISSIONS_REVIEW_REQUIRED
3994                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
3995                    && bp.isRuntime()) {
3996                return;
3997            }
3998
3999            SettingBase sb = (SettingBase) pkg.mExtras;
4000            if (sb == null) {
4001                throw new IllegalArgumentException("Unknown package: " + packageName);
4002            }
4003
4004            final PermissionsState permissionsState = sb.getPermissionsState();
4005
4006            final int flags = permissionsState.getPermissionFlags(name, userId);
4007            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4008                throw new SecurityException("Cannot revoke system fixed permission "
4009                        + name + " for package " + packageName);
4010            }
4011
4012            if (bp.isDevelopment()) {
4013                // Development permissions must be handled specially, since they are not
4014                // normal runtime permissions.  For now they apply to all users.
4015                if (permissionsState.revokeInstallPermission(bp) !=
4016                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4017                    scheduleWriteSettingsLocked();
4018                }
4019                return;
4020            }
4021
4022            if (permissionsState.revokeRuntimePermission(bp, userId) ==
4023                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
4024                return;
4025            }
4026
4027            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4028
4029            // Critical, after this call app should never have the permission.
4030            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
4031
4032            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4033        }
4034
4035        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
4036    }
4037
4038    @Override
4039    public void resetRuntimePermissions() {
4040        mContext.enforceCallingOrSelfPermission(
4041                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4042                "revokeRuntimePermission");
4043
4044        int callingUid = Binder.getCallingUid();
4045        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4046            mContext.enforceCallingOrSelfPermission(
4047                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4048                    "resetRuntimePermissions");
4049        }
4050
4051        synchronized (mPackages) {
4052            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
4053            for (int userId : UserManagerService.getInstance().getUserIds()) {
4054                final int packageCount = mPackages.size();
4055                for (int i = 0; i < packageCount; i++) {
4056                    PackageParser.Package pkg = mPackages.valueAt(i);
4057                    if (!(pkg.mExtras instanceof PackageSetting)) {
4058                        continue;
4059                    }
4060                    PackageSetting ps = (PackageSetting) pkg.mExtras;
4061                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
4062                }
4063            }
4064        }
4065    }
4066
4067    @Override
4068    public int getPermissionFlags(String name, String packageName, int userId) {
4069        if (!sUserManager.exists(userId)) {
4070            return 0;
4071        }
4072
4073        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
4074
4075        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4076                true /* requireFullPermission */, false /* checkShell */,
4077                "getPermissionFlags");
4078
4079        synchronized (mPackages) {
4080            final PackageParser.Package pkg = mPackages.get(packageName);
4081            if (pkg == null) {
4082                throw new IllegalArgumentException("Unknown package: " + packageName);
4083            }
4084
4085            final BasePermission bp = mSettings.mPermissions.get(name);
4086            if (bp == null) {
4087                throw new IllegalArgumentException("Unknown permission: " + name);
4088            }
4089
4090            SettingBase sb = (SettingBase) pkg.mExtras;
4091            if (sb == null) {
4092                throw new IllegalArgumentException("Unknown package: " + packageName);
4093            }
4094
4095            PermissionsState permissionsState = sb.getPermissionsState();
4096            return permissionsState.getPermissionFlags(name, userId);
4097        }
4098    }
4099
4100    @Override
4101    public void updatePermissionFlags(String name, String packageName, int flagMask,
4102            int flagValues, int userId) {
4103        if (!sUserManager.exists(userId)) {
4104            return;
4105        }
4106
4107        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
4108
4109        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4110                true /* requireFullPermission */, true /* checkShell */,
4111                "updatePermissionFlags");
4112
4113        // Only the system can change these flags and nothing else.
4114        if (getCallingUid() != Process.SYSTEM_UID) {
4115            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4116            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4117            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4118            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
4119            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
4120        }
4121
4122        synchronized (mPackages) {
4123            final PackageParser.Package pkg = mPackages.get(packageName);
4124            if (pkg == null) {
4125                throw new IllegalArgumentException("Unknown package: " + packageName);
4126            }
4127
4128            final BasePermission bp = mSettings.mPermissions.get(name);
4129            if (bp == null) {
4130                throw new IllegalArgumentException("Unknown permission: " + name);
4131            }
4132
4133            SettingBase sb = (SettingBase) pkg.mExtras;
4134            if (sb == null) {
4135                throw new IllegalArgumentException("Unknown package: " + packageName);
4136            }
4137
4138            PermissionsState permissionsState = sb.getPermissionsState();
4139
4140            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
4141
4142            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
4143                // Install and runtime permissions are stored in different places,
4144                // so figure out what permission changed and persist the change.
4145                if (permissionsState.getInstallPermissionState(name) != null) {
4146                    scheduleWriteSettingsLocked();
4147                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
4148                        || hadState) {
4149                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4150                }
4151            }
4152        }
4153    }
4154
4155    /**
4156     * Update the permission flags for all packages and runtime permissions of a user in order
4157     * to allow device or profile owner to remove POLICY_FIXED.
4158     */
4159    @Override
4160    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
4161        if (!sUserManager.exists(userId)) {
4162            return;
4163        }
4164
4165        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
4166
4167        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4168                true /* requireFullPermission */, true /* checkShell */,
4169                "updatePermissionFlagsForAllApps");
4170
4171        // Only the system can change system fixed flags.
4172        if (getCallingUid() != Process.SYSTEM_UID) {
4173            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4174            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
4175        }
4176
4177        synchronized (mPackages) {
4178            boolean changed = false;
4179            final int packageCount = mPackages.size();
4180            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
4181                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
4182                SettingBase sb = (SettingBase) pkg.mExtras;
4183                if (sb == null) {
4184                    continue;
4185                }
4186                PermissionsState permissionsState = sb.getPermissionsState();
4187                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
4188                        userId, flagMask, flagValues);
4189            }
4190            if (changed) {
4191                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4192            }
4193        }
4194    }
4195
4196    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4197        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4198                != PackageManager.PERMISSION_GRANTED
4199            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4200                != PackageManager.PERMISSION_GRANTED) {
4201            throw new SecurityException(message + " requires "
4202                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4203                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4204        }
4205    }
4206
4207    @Override
4208    public boolean shouldShowRequestPermissionRationale(String permissionName,
4209            String packageName, int userId) {
4210        if (UserHandle.getCallingUserId() != userId) {
4211            mContext.enforceCallingPermission(
4212                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4213                    "canShowRequestPermissionRationale for user " + userId);
4214        }
4215
4216        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
4217        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
4218            return false;
4219        }
4220
4221        if (checkPermission(permissionName, packageName, userId)
4222                == PackageManager.PERMISSION_GRANTED) {
4223            return false;
4224        }
4225
4226        final int flags;
4227
4228        final long identity = Binder.clearCallingIdentity();
4229        try {
4230            flags = getPermissionFlags(permissionName,
4231                    packageName, userId);
4232        } finally {
4233            Binder.restoreCallingIdentity(identity);
4234        }
4235
4236        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
4237                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
4238                | PackageManager.FLAG_PERMISSION_USER_FIXED;
4239
4240        if ((flags & fixedFlags) != 0) {
4241            return false;
4242        }
4243
4244        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
4245    }
4246
4247    @Override
4248    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4249        mContext.enforceCallingOrSelfPermission(
4250                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
4251                "addOnPermissionsChangeListener");
4252
4253        synchronized (mPackages) {
4254            mOnPermissionChangeListeners.addListenerLocked(listener);
4255        }
4256    }
4257
4258    @Override
4259    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
4260        synchronized (mPackages) {
4261            mOnPermissionChangeListeners.removeListenerLocked(listener);
4262        }
4263    }
4264
4265    @Override
4266    public boolean isProtectedBroadcast(String actionName) {
4267        synchronized (mPackages) {
4268            if (mProtectedBroadcasts.contains(actionName)) {
4269                return true;
4270            } else if (actionName != null) {
4271                // TODO: remove these terrible hacks
4272                if (actionName.startsWith("android.net.netmon.lingerExpired")
4273                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
4274                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
4275                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
4276                    return true;
4277                }
4278            }
4279        }
4280        return false;
4281    }
4282
4283    @Override
4284    public int checkSignatures(String pkg1, String pkg2) {
4285        synchronized (mPackages) {
4286            final PackageParser.Package p1 = mPackages.get(pkg1);
4287            final PackageParser.Package p2 = mPackages.get(pkg2);
4288            if (p1 == null || p1.mExtras == null
4289                    || p2 == null || p2.mExtras == null) {
4290                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4291            }
4292            return compareSignatures(p1.mSignatures, p2.mSignatures);
4293        }
4294    }
4295
4296    @Override
4297    public int checkUidSignatures(int uid1, int uid2) {
4298        // Map to base uids.
4299        uid1 = UserHandle.getAppId(uid1);
4300        uid2 = UserHandle.getAppId(uid2);
4301        // reader
4302        synchronized (mPackages) {
4303            Signature[] s1;
4304            Signature[] s2;
4305            Object obj = mSettings.getUserIdLPr(uid1);
4306            if (obj != null) {
4307                if (obj instanceof SharedUserSetting) {
4308                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
4309                } else if (obj instanceof PackageSetting) {
4310                    s1 = ((PackageSetting)obj).signatures.mSignatures;
4311                } else {
4312                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4313                }
4314            } else {
4315                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4316            }
4317            obj = mSettings.getUserIdLPr(uid2);
4318            if (obj != null) {
4319                if (obj instanceof SharedUserSetting) {
4320                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
4321                } else if (obj instanceof PackageSetting) {
4322                    s2 = ((PackageSetting)obj).signatures.mSignatures;
4323                } else {
4324                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4325                }
4326            } else {
4327                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
4328            }
4329            return compareSignatures(s1, s2);
4330        }
4331    }
4332
4333    private void killUid(int appId, int userId, String reason) {
4334        final long identity = Binder.clearCallingIdentity();
4335        try {
4336            IActivityManager am = ActivityManagerNative.getDefault();
4337            if (am != null) {
4338                try {
4339                    am.killUid(appId, userId, reason);
4340                } catch (RemoteException e) {
4341                    /* ignore - same process */
4342                }
4343            }
4344        } finally {
4345            Binder.restoreCallingIdentity(identity);
4346        }
4347    }
4348
4349    /**
4350     * Compares two sets of signatures. Returns:
4351     * <br />
4352     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
4353     * <br />
4354     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
4355     * <br />
4356     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
4357     * <br />
4358     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
4359     * <br />
4360     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
4361     */
4362    static int compareSignatures(Signature[] s1, Signature[] s2) {
4363        if (s1 == null) {
4364            return s2 == null
4365                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
4366                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
4367        }
4368
4369        if (s2 == null) {
4370            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
4371        }
4372
4373        if (s1.length != s2.length) {
4374            return PackageManager.SIGNATURE_NO_MATCH;
4375        }
4376
4377        // Since both signature sets are of size 1, we can compare without HashSets.
4378        if (s1.length == 1) {
4379            return s1[0].equals(s2[0]) ?
4380                    PackageManager.SIGNATURE_MATCH :
4381                    PackageManager.SIGNATURE_NO_MATCH;
4382        }
4383
4384        ArraySet<Signature> set1 = new ArraySet<Signature>();
4385        for (Signature sig : s1) {
4386            set1.add(sig);
4387        }
4388        ArraySet<Signature> set2 = new ArraySet<Signature>();
4389        for (Signature sig : s2) {
4390            set2.add(sig);
4391        }
4392        // Make sure s2 contains all signatures in s1.
4393        if (set1.equals(set2)) {
4394            return PackageManager.SIGNATURE_MATCH;
4395        }
4396        return PackageManager.SIGNATURE_NO_MATCH;
4397    }
4398
4399    /**
4400     * If the database version for this type of package (internal storage or
4401     * external storage) is less than the version where package signatures
4402     * were updated, return true.
4403     */
4404    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4405        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4406        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
4407    }
4408
4409    /**
4410     * Used for backward compatibility to make sure any packages with
4411     * certificate chains get upgraded to the new style. {@code existingSigs}
4412     * will be in the old format (since they were stored on disk from before the
4413     * system upgrade) and {@code scannedSigs} will be in the newer format.
4414     */
4415    private int compareSignaturesCompat(PackageSignatures existingSigs,
4416            PackageParser.Package scannedPkg) {
4417        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
4418            return PackageManager.SIGNATURE_NO_MATCH;
4419        }
4420
4421        ArraySet<Signature> existingSet = new ArraySet<Signature>();
4422        for (Signature sig : existingSigs.mSignatures) {
4423            existingSet.add(sig);
4424        }
4425        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
4426        for (Signature sig : scannedPkg.mSignatures) {
4427            try {
4428                Signature[] chainSignatures = sig.getChainSignatures();
4429                for (Signature chainSig : chainSignatures) {
4430                    scannedCompatSet.add(chainSig);
4431                }
4432            } catch (CertificateEncodingException e) {
4433                scannedCompatSet.add(sig);
4434            }
4435        }
4436        /*
4437         * Make sure the expanded scanned set contains all signatures in the
4438         * existing one.
4439         */
4440        if (scannedCompatSet.equals(existingSet)) {
4441            // Migrate the old signatures to the new scheme.
4442            existingSigs.assignSignatures(scannedPkg.mSignatures);
4443            // The new KeySets will be re-added later in the scanning process.
4444            synchronized (mPackages) {
4445                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
4446            }
4447            return PackageManager.SIGNATURE_MATCH;
4448        }
4449        return PackageManager.SIGNATURE_NO_MATCH;
4450    }
4451
4452    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
4453        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
4454        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
4455    }
4456
4457    private int compareSignaturesRecover(PackageSignatures existingSigs,
4458            PackageParser.Package scannedPkg) {
4459        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
4460            return PackageManager.SIGNATURE_NO_MATCH;
4461        }
4462
4463        String msg = null;
4464        try {
4465            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
4466                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
4467                        + scannedPkg.packageName);
4468                return PackageManager.SIGNATURE_MATCH;
4469            }
4470        } catch (CertificateException e) {
4471            msg = e.getMessage();
4472        }
4473
4474        logCriticalInfo(Log.INFO,
4475                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
4476        return PackageManager.SIGNATURE_NO_MATCH;
4477    }
4478
4479    @Override
4480    public List<String> getAllPackages() {
4481        synchronized (mPackages) {
4482            return new ArrayList<String>(mPackages.keySet());
4483        }
4484    }
4485
4486    @Override
4487    public String[] getPackagesForUid(int uid) {
4488        uid = UserHandle.getAppId(uid);
4489        // reader
4490        synchronized (mPackages) {
4491            Object obj = mSettings.getUserIdLPr(uid);
4492            if (obj instanceof SharedUserSetting) {
4493                final SharedUserSetting sus = (SharedUserSetting) obj;
4494                final int N = sus.packages.size();
4495                final String[] res = new String[N];
4496                final Iterator<PackageSetting> it = sus.packages.iterator();
4497                int i = 0;
4498                while (it.hasNext()) {
4499                    res[i++] = it.next().name;
4500                }
4501                return res;
4502            } else if (obj instanceof PackageSetting) {
4503                final PackageSetting ps = (PackageSetting) obj;
4504                return new String[] { ps.name };
4505            }
4506        }
4507        return null;
4508    }
4509
4510    @Override
4511    public String getNameForUid(int uid) {
4512        // reader
4513        synchronized (mPackages) {
4514            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4515            if (obj instanceof SharedUserSetting) {
4516                final SharedUserSetting sus = (SharedUserSetting) obj;
4517                return sus.name + ":" + sus.userId;
4518            } else if (obj instanceof PackageSetting) {
4519                final PackageSetting ps = (PackageSetting) obj;
4520                return ps.name;
4521            }
4522        }
4523        return null;
4524    }
4525
4526    @Override
4527    public int getUidForSharedUser(String sharedUserName) {
4528        if(sharedUserName == null) {
4529            return -1;
4530        }
4531        // reader
4532        synchronized (mPackages) {
4533            final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
4534            if (suid == null) {
4535                return -1;
4536            }
4537            return suid.userId;
4538        }
4539    }
4540
4541    @Override
4542    public int getFlagsForUid(int uid) {
4543        synchronized (mPackages) {
4544            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4545            if (obj instanceof SharedUserSetting) {
4546                final SharedUserSetting sus = (SharedUserSetting) obj;
4547                return sus.pkgFlags;
4548            } else if (obj instanceof PackageSetting) {
4549                final PackageSetting ps = (PackageSetting) obj;
4550                return ps.pkgFlags;
4551            }
4552        }
4553        return 0;
4554    }
4555
4556    @Override
4557    public int getPrivateFlagsForUid(int uid) {
4558        synchronized (mPackages) {
4559            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4560            if (obj instanceof SharedUserSetting) {
4561                final SharedUserSetting sus = (SharedUserSetting) obj;
4562                return sus.pkgPrivateFlags;
4563            } else if (obj instanceof PackageSetting) {
4564                final PackageSetting ps = (PackageSetting) obj;
4565                return ps.pkgPrivateFlags;
4566            }
4567        }
4568        return 0;
4569    }
4570
4571    @Override
4572    public boolean isUidPrivileged(int uid) {
4573        uid = UserHandle.getAppId(uid);
4574        // reader
4575        synchronized (mPackages) {
4576            Object obj = mSettings.getUserIdLPr(uid);
4577            if (obj instanceof SharedUserSetting) {
4578                final SharedUserSetting sus = (SharedUserSetting) obj;
4579                final Iterator<PackageSetting> it = sus.packages.iterator();
4580                while (it.hasNext()) {
4581                    if (it.next().isPrivileged()) {
4582                        return true;
4583                    }
4584                }
4585            } else if (obj instanceof PackageSetting) {
4586                final PackageSetting ps = (PackageSetting) obj;
4587                return ps.isPrivileged();
4588            }
4589        }
4590        return false;
4591    }
4592
4593    @Override
4594    public String[] getAppOpPermissionPackages(String permissionName) {
4595        synchronized (mPackages) {
4596            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
4597            if (pkgs == null) {
4598                return null;
4599            }
4600            return pkgs.toArray(new String[pkgs.size()]);
4601        }
4602    }
4603
4604    @Override
4605    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
4606            int flags, int userId) {
4607        if (!sUserManager.exists(userId)) return null;
4608        flags = updateFlagsForResolve(flags, userId, intent);
4609        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4610                false /* requireFullPermission */, false /* checkShell */, "resolve intent");
4611        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4612                userId);
4613        final ResolveInfo bestChoice =
4614                chooseBestActivity(intent, resolvedType, flags, query, userId);
4615
4616        if (isEphemeralAllowed(intent, query, userId)) {
4617            final EphemeralResolveInfo ai =
4618                    getEphemeralResolveInfo(intent, resolvedType, userId);
4619            if (ai != null) {
4620                if (DEBUG_EPHEMERAL) {
4621                    Slog.v(TAG, "Returning an EphemeralResolveInfo");
4622                }
4623                bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
4624                bestChoice.ephemeralResolveInfo = ai;
4625            }
4626        }
4627        return bestChoice;
4628    }
4629
4630    @Override
4631    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
4632            IntentFilter filter, int match, ComponentName activity) {
4633        final int userId = UserHandle.getCallingUserId();
4634        if (DEBUG_PREFERRED) {
4635            Log.v(TAG, "setLastChosenActivity intent=" + intent
4636                + " resolvedType=" + resolvedType
4637                + " flags=" + flags
4638                + " filter=" + filter
4639                + " match=" + match
4640                + " activity=" + activity);
4641            filter.dump(new PrintStreamPrinter(System.out), "    ");
4642        }
4643        intent.setComponent(null);
4644        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4645                userId);
4646        // Find any earlier preferred or last chosen entries and nuke them
4647        findPreferredActivity(intent, resolvedType,
4648                flags, query, 0, false, true, false, userId);
4649        // Add the new activity as the last chosen for this filter
4650        addPreferredActivityInternal(filter, match, null, activity, false, userId,
4651                "Setting last chosen");
4652    }
4653
4654    @Override
4655    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
4656        final int userId = UserHandle.getCallingUserId();
4657        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
4658        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
4659                userId);
4660        return findPreferredActivity(intent, resolvedType, flags, query, 0,
4661                false, false, false, userId);
4662    }
4663
4664
4665    private boolean isEphemeralAllowed(
4666            Intent intent, List<ResolveInfo> resolvedActivites, int userId) {
4667        // Short circuit and return early if possible.
4668        if (DISABLE_EPHEMERAL_APPS) {
4669            return false;
4670        }
4671        final int callingUser = UserHandle.getCallingUserId();
4672        if (callingUser != UserHandle.USER_SYSTEM) {
4673            return false;
4674        }
4675        if (mEphemeralResolverConnection == null) {
4676            return false;
4677        }
4678        if (intent.getComponent() != null) {
4679            return false;
4680        }
4681        if (intent.getPackage() != null) {
4682            return false;
4683        }
4684        final boolean isWebUri = hasWebURI(intent);
4685        if (!isWebUri) {
4686            return false;
4687        }
4688        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
4689        synchronized (mPackages) {
4690            final int count = resolvedActivites.size();
4691            for (int n = 0; n < count; n++) {
4692                ResolveInfo info = resolvedActivites.get(n);
4693                String packageName = info.activityInfo.packageName;
4694                PackageSetting ps = mSettings.mPackages.get(packageName);
4695                if (ps != null) {
4696                    // Try to get the status from User settings first
4697                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
4698                    int status = (int) (packedStatus >> 32);
4699                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
4700                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
4701                        if (DEBUG_EPHEMERAL) {
4702                            Slog.v(TAG, "DENY ephemeral apps;"
4703                                + " pkg: " + packageName + ", status: " + status);
4704                        }
4705                        return false;
4706                    }
4707                }
4708            }
4709        }
4710        // We've exhausted all ways to deny ephemeral application; let the system look for them.
4711        return true;
4712    }
4713
4714    private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType,
4715            int userId) {
4716        MessageDigest digest = null;
4717        try {
4718            digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM);
4719        } catch (NoSuchAlgorithmException e) {
4720            // If we can't create a digest, ignore ephemeral apps.
4721            return null;
4722        }
4723
4724        final byte[] hostBytes = intent.getData().getHost().getBytes();
4725        final byte[] digestBytes = digest.digest(hostBytes);
4726        int shaPrefix =
4727                digestBytes[0] << 24
4728                | digestBytes[1] << 16
4729                | digestBytes[2] << 8
4730                | digestBytes[3] << 0;
4731        final List<EphemeralResolveInfo> ephemeralResolveInfoList =
4732                mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix);
4733        if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) {
4734            // No hash prefix match; there are no ephemeral apps for this domain.
4735            return null;
4736        }
4737        for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) {
4738            EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i);
4739            if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) {
4740                continue;
4741            }
4742            final List<IntentFilter> filters = ephemeralApplication.getFilters();
4743            // No filters; this should never happen.
4744            if (filters.isEmpty()) {
4745                continue;
4746            }
4747            // We have a domain match; resolve the filters to see if anything matches.
4748            final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver();
4749            for (int j = filters.size() - 1; j >= 0; --j) {
4750                final EphemeralResolveIntentInfo intentInfo =
4751                        new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication);
4752                ephemeralResolver.addFilter(intentInfo);
4753            }
4754            List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent(
4755                    intent, resolvedType, false /*defaultOnly*/, userId);
4756            if (!matchedResolveInfoList.isEmpty()) {
4757                return matchedResolveInfoList.get(0);
4758            }
4759        }
4760        // Hash or filter mis-match; no ephemeral apps for this domain.
4761        return null;
4762    }
4763
4764    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
4765            int flags, List<ResolveInfo> query, int userId) {
4766        if (query != null) {
4767            final int N = query.size();
4768            if (N == 1) {
4769                return query.get(0);
4770            } else if (N > 1) {
4771                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4772                // If there is more than one activity with the same priority,
4773                // then let the user decide between them.
4774                ResolveInfo r0 = query.get(0);
4775                ResolveInfo r1 = query.get(1);
4776                if (DEBUG_INTENT_MATCHING || debug) {
4777                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
4778                            + r1.activityInfo.name + "=" + r1.priority);
4779                }
4780                // If the first activity has a higher priority, or a different
4781                // default, then it is always desirable to pick it.
4782                if (r0.priority != r1.priority
4783                        || r0.preferredOrder != r1.preferredOrder
4784                        || r0.isDefault != r1.isDefault) {
4785                    return query.get(0);
4786                }
4787                // If we have saved a preference for a preferred activity for
4788                // this Intent, use that.
4789                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
4790                        flags, query, r0.priority, true, false, debug, userId);
4791                if (ri != null) {
4792                    return ri;
4793                }
4794                ri = new ResolveInfo(mResolveInfo);
4795                ri.activityInfo = new ActivityInfo(ri.activityInfo);
4796                ri.activityInfo.applicationInfo = new ApplicationInfo(
4797                        ri.activityInfo.applicationInfo);
4798                if (userId != 0) {
4799                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
4800                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
4801                }
4802                // Make sure that the resolver is displayable in car mode
4803                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
4804                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
4805                return ri;
4806            }
4807        }
4808        return null;
4809    }
4810
4811    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
4812            int flags, List<ResolveInfo> query, boolean debug, int userId) {
4813        final int N = query.size();
4814        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
4815                .get(userId);
4816        // Get the list of persistent preferred activities that handle the intent
4817        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
4818        List<PersistentPreferredActivity> pprefs = ppir != null
4819                ? ppir.queryIntent(intent, resolvedType,
4820                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4821                : null;
4822        if (pprefs != null && pprefs.size() > 0) {
4823            final int M = pprefs.size();
4824            for (int i=0; i<M; i++) {
4825                final PersistentPreferredActivity ppa = pprefs.get(i);
4826                if (DEBUG_PREFERRED || debug) {
4827                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
4828                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
4829                            + "\n  component=" + ppa.mComponent);
4830                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4831                }
4832                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
4833                        flags | MATCH_DISABLED_COMPONENTS, userId);
4834                if (DEBUG_PREFERRED || debug) {
4835                    Slog.v(TAG, "Found persistent preferred activity:");
4836                    if (ai != null) {
4837                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4838                    } else {
4839                        Slog.v(TAG, "  null");
4840                    }
4841                }
4842                if (ai == null) {
4843                    // This previously registered persistent preferred activity
4844                    // component is no longer known. Ignore it and do NOT remove it.
4845                    continue;
4846                }
4847                for (int j=0; j<N; j++) {
4848                    final ResolveInfo ri = query.get(j);
4849                    if (!ri.activityInfo.applicationInfo.packageName
4850                            .equals(ai.applicationInfo.packageName)) {
4851                        continue;
4852                    }
4853                    if (!ri.activityInfo.name.equals(ai.name)) {
4854                        continue;
4855                    }
4856                    //  Found a persistent preference that can handle the intent.
4857                    if (DEBUG_PREFERRED || debug) {
4858                        Slog.v(TAG, "Returning persistent preferred activity: " +
4859                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
4860                    }
4861                    return ri;
4862                }
4863            }
4864        }
4865        return null;
4866    }
4867
4868    // TODO: handle preferred activities missing while user has amnesia
4869    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
4870            List<ResolveInfo> query, int priority, boolean always,
4871            boolean removeMatches, boolean debug, int userId) {
4872        if (!sUserManager.exists(userId)) return null;
4873        flags = updateFlagsForResolve(flags, userId, intent);
4874        // writer
4875        synchronized (mPackages) {
4876            if (intent.getSelector() != null) {
4877                intent = intent.getSelector();
4878            }
4879            if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4880
4881            // Try to find a matching persistent preferred activity.
4882            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
4883                    debug, userId);
4884
4885            // If a persistent preferred activity matched, use it.
4886            if (pri != null) {
4887                return pri;
4888            }
4889
4890            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
4891            // Get the list of preferred activities that handle the intent
4892            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
4893            List<PreferredActivity> prefs = pir != null
4894                    ? pir.queryIntent(intent, resolvedType,
4895                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
4896                    : null;
4897            if (prefs != null && prefs.size() > 0) {
4898                boolean changed = false;
4899                try {
4900                    // First figure out how good the original match set is.
4901                    // We will only allow preferred activities that came
4902                    // from the same match quality.
4903                    int match = 0;
4904
4905                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
4906
4907                    final int N = query.size();
4908                    for (int j=0; j<N; j++) {
4909                        final ResolveInfo ri = query.get(j);
4910                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
4911                                + ": 0x" + Integer.toHexString(match));
4912                        if (ri.match > match) {
4913                            match = ri.match;
4914                        }
4915                    }
4916
4917                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
4918                            + Integer.toHexString(match));
4919
4920                    match &= IntentFilter.MATCH_CATEGORY_MASK;
4921                    final int M = prefs.size();
4922                    for (int i=0; i<M; i++) {
4923                        final PreferredActivity pa = prefs.get(i);
4924                        if (DEBUG_PREFERRED || debug) {
4925                            Slog.v(TAG, "Checking PreferredActivity ds="
4926                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
4927                                    + "\n  component=" + pa.mPref.mComponent);
4928                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4929                        }
4930                        if (pa.mPref.mMatch != match) {
4931                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
4932                                    + Integer.toHexString(pa.mPref.mMatch));
4933                            continue;
4934                        }
4935                        // If it's not an "always" type preferred activity and that's what we're
4936                        // looking for, skip it.
4937                        if (always && !pa.mPref.mAlways) {
4938                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
4939                            continue;
4940                        }
4941                        final ActivityInfo ai = getActivityInfo(
4942                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
4943                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
4944                                userId);
4945                        if (DEBUG_PREFERRED || debug) {
4946                            Slog.v(TAG, "Found preferred activity:");
4947                            if (ai != null) {
4948                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
4949                            } else {
4950                                Slog.v(TAG, "  null");
4951                            }
4952                        }
4953                        if (ai == null) {
4954                            // This previously registered preferred activity
4955                            // component is no longer known.  Most likely an update
4956                            // to the app was installed and in the new version this
4957                            // component no longer exists.  Clean it up by removing
4958                            // it from the preferred activities list, and skip it.
4959                            Slog.w(TAG, "Removing dangling preferred activity: "
4960                                    + pa.mPref.mComponent);
4961                            pir.removeFilter(pa);
4962                            changed = true;
4963                            continue;
4964                        }
4965                        for (int j=0; j<N; j++) {
4966                            final ResolveInfo ri = query.get(j);
4967                            if (!ri.activityInfo.applicationInfo.packageName
4968                                    .equals(ai.applicationInfo.packageName)) {
4969                                continue;
4970                            }
4971                            if (!ri.activityInfo.name.equals(ai.name)) {
4972                                continue;
4973                            }
4974
4975                            if (removeMatches) {
4976                                pir.removeFilter(pa);
4977                                changed = true;
4978                                if (DEBUG_PREFERRED) {
4979                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
4980                                }
4981                                break;
4982                            }
4983
4984                            // Okay we found a previously set preferred or last chosen app.
4985                            // If the result set is different from when this
4986                            // was created, we need to clear it and re-ask the
4987                            // user their preference, if we're looking for an "always" type entry.
4988                            if (always && !pa.mPref.sameSet(query)) {
4989                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
4990                                        + intent + " type " + resolvedType);
4991                                if (DEBUG_PREFERRED) {
4992                                    Slog.v(TAG, "Removing preferred activity since set changed "
4993                                            + pa.mPref.mComponent);
4994                                }
4995                                pir.removeFilter(pa);
4996                                // Re-add the filter as a "last chosen" entry (!always)
4997                                PreferredActivity lastChosen = new PreferredActivity(
4998                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
4999                                pir.addFilter(lastChosen);
5000                                changed = true;
5001                                return null;
5002                            }
5003
5004                            // Yay! Either the set matched or we're looking for the last chosen
5005                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
5006                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5007                            return ri;
5008                        }
5009                    }
5010                } finally {
5011                    if (changed) {
5012                        if (DEBUG_PREFERRED) {
5013                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
5014                        }
5015                        scheduleWritePackageRestrictionsLocked(userId);
5016                    }
5017                }
5018            }
5019        }
5020        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
5021        return null;
5022    }
5023
5024    /*
5025     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
5026     */
5027    @Override
5028    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
5029            int targetUserId) {
5030        mContext.enforceCallingOrSelfPermission(
5031                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
5032        List<CrossProfileIntentFilter> matches =
5033                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
5034        if (matches != null) {
5035            int size = matches.size();
5036            for (int i = 0; i < size; i++) {
5037                if (matches.get(i).getTargetUserId() == targetUserId) return true;
5038            }
5039        }
5040        if (hasWebURI(intent)) {
5041            // cross-profile app linking works only towards the parent.
5042            final UserInfo parent = getProfileParent(sourceUserId);
5043            synchronized(mPackages) {
5044                int flags = updateFlagsForResolve(0, parent.id, intent);
5045                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
5046                        intent, resolvedType, flags, sourceUserId, parent.id);
5047                return xpDomainInfo != null;
5048            }
5049        }
5050        return false;
5051    }
5052
5053    private UserInfo getProfileParent(int userId) {
5054        final long identity = Binder.clearCallingIdentity();
5055        try {
5056            return sUserManager.getProfileParent(userId);
5057        } finally {
5058            Binder.restoreCallingIdentity(identity);
5059        }
5060    }
5061
5062    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
5063            String resolvedType, int userId) {
5064        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
5065        if (resolver != null) {
5066            return resolver.queryIntent(intent, resolvedType, false, userId);
5067        }
5068        return null;
5069    }
5070
5071    @Override
5072    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
5073            String resolvedType, int flags, int userId) {
5074        return new ParceledListSlice<>(
5075                queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
5076    }
5077
5078    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
5079            String resolvedType, int flags, int userId) {
5080        if (!sUserManager.exists(userId)) return Collections.emptyList();
5081        flags = updateFlagsForResolve(flags, userId, intent);
5082        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5083                false /* requireFullPermission */, false /* checkShell */,
5084                "query intent activities");
5085        ComponentName comp = intent.getComponent();
5086        if (comp == null) {
5087            if (intent.getSelector() != null) {
5088                intent = intent.getSelector();
5089                comp = intent.getComponent();
5090            }
5091        }
5092
5093        if (comp != null) {
5094            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5095            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
5096            if (ai != null) {
5097                final ResolveInfo ri = new ResolveInfo();
5098                ri.activityInfo = ai;
5099                list.add(ri);
5100            }
5101            return list;
5102        }
5103
5104        // reader
5105        synchronized (mPackages) {
5106            final String pkgName = intent.getPackage();
5107            if (pkgName == null) {
5108                List<CrossProfileIntentFilter> matchingFilters =
5109                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
5110                // Check for results that need to skip the current profile.
5111                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
5112                        resolvedType, flags, userId);
5113                if (xpResolveInfo != null) {
5114                    List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
5115                    result.add(xpResolveInfo);
5116                    return filterIfNotSystemUser(result, userId);
5117                }
5118
5119                // Check for results in the current profile.
5120                List<ResolveInfo> result = mActivities.queryIntent(
5121                        intent, resolvedType, flags, userId);
5122                result = filterIfNotSystemUser(result, userId);
5123
5124                // Check for cross profile results.
5125                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
5126                xpResolveInfo = queryCrossProfileIntents(
5127                        matchingFilters, intent, resolvedType, flags, userId,
5128                        hasNonNegativePriorityResult);
5129                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
5130                    boolean isVisibleToUser = filterIfNotSystemUser(
5131                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
5132                    if (isVisibleToUser) {
5133                        result.add(xpResolveInfo);
5134                        Collections.sort(result, mResolvePrioritySorter);
5135                    }
5136                }
5137                if (hasWebURI(intent)) {
5138                    CrossProfileDomainInfo xpDomainInfo = null;
5139                    final UserInfo parent = getProfileParent(userId);
5140                    if (parent != null) {
5141                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
5142                                flags, userId, parent.id);
5143                    }
5144                    if (xpDomainInfo != null) {
5145                        if (xpResolveInfo != null) {
5146                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
5147                            // in the result.
5148                            result.remove(xpResolveInfo);
5149                        }
5150                        if (result.size() == 0) {
5151                            result.add(xpDomainInfo.resolveInfo);
5152                            return result;
5153                        }
5154                    } else if (result.size() <= 1) {
5155                        return result;
5156                    }
5157                    result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result,
5158                            xpDomainInfo, userId);
5159                    Collections.sort(result, mResolvePrioritySorter);
5160                }
5161                return result;
5162            }
5163            final PackageParser.Package pkg = mPackages.get(pkgName);
5164            if (pkg != null) {
5165                return filterIfNotSystemUser(
5166                        mActivities.queryIntentForPackage(
5167                                intent, resolvedType, flags, pkg.activities, userId),
5168                        userId);
5169            }
5170            return new ArrayList<ResolveInfo>();
5171        }
5172    }
5173
5174    private static class CrossProfileDomainInfo {
5175        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
5176        ResolveInfo resolveInfo;
5177        /* Best domain verification status of the activities found in the other profile */
5178        int bestDomainVerificationStatus;
5179    }
5180
5181    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
5182            String resolvedType, int flags, int sourceUserId, int parentUserId) {
5183        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
5184                sourceUserId)) {
5185            return null;
5186        }
5187        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5188                resolvedType, flags, parentUserId);
5189
5190        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
5191            return null;
5192        }
5193        CrossProfileDomainInfo result = null;
5194        int size = resultTargetUser.size();
5195        for (int i = 0; i < size; i++) {
5196            ResolveInfo riTargetUser = resultTargetUser.get(i);
5197            // Intent filter verification is only for filters that specify a host. So don't return
5198            // those that handle all web uris.
5199            if (riTargetUser.handleAllWebDataURI) {
5200                continue;
5201            }
5202            String packageName = riTargetUser.activityInfo.packageName;
5203            PackageSetting ps = mSettings.mPackages.get(packageName);
5204            if (ps == null) {
5205                continue;
5206            }
5207            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
5208            int status = (int)(verificationState >> 32);
5209            if (result == null) {
5210                result = new CrossProfileDomainInfo();
5211                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
5212                        sourceUserId, parentUserId);
5213                result.bestDomainVerificationStatus = status;
5214            } else {
5215                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
5216                        result.bestDomainVerificationStatus);
5217            }
5218        }
5219        // Don't consider matches with status NEVER across profiles.
5220        if (result != null && result.bestDomainVerificationStatus
5221                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5222            return null;
5223        }
5224        return result;
5225    }
5226
5227    /**
5228     * Verification statuses are ordered from the worse to the best, except for
5229     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
5230     */
5231    private int bestDomainVerificationStatus(int status1, int status2) {
5232        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5233            return status2;
5234        }
5235        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5236            return status1;
5237        }
5238        return (int) MathUtils.max(status1, status2);
5239    }
5240
5241    private boolean isUserEnabled(int userId) {
5242        long callingId = Binder.clearCallingIdentity();
5243        try {
5244            UserInfo userInfo = sUserManager.getUserInfo(userId);
5245            return userInfo != null && userInfo.isEnabled();
5246        } finally {
5247            Binder.restoreCallingIdentity(callingId);
5248        }
5249    }
5250
5251    /**
5252     * Filter out activities with systemUserOnly flag set, when current user is not System.
5253     *
5254     * @return filtered list
5255     */
5256    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
5257        if (userId == UserHandle.USER_SYSTEM) {
5258            return resolveInfos;
5259        }
5260        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
5261            ResolveInfo info = resolveInfos.get(i);
5262            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
5263                resolveInfos.remove(i);
5264            }
5265        }
5266        return resolveInfos;
5267    }
5268
5269    /**
5270     * @param resolveInfos list of resolve infos in descending priority order
5271     * @return if the list contains a resolve info with non-negative priority
5272     */
5273    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
5274        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
5275    }
5276
5277    private static boolean hasWebURI(Intent intent) {
5278        if (intent.getData() == null) {
5279            return false;
5280        }
5281        final String scheme = intent.getScheme();
5282        if (TextUtils.isEmpty(scheme)) {
5283            return false;
5284        }
5285        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
5286    }
5287
5288    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
5289            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
5290            int userId) {
5291        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
5292
5293        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5294            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
5295                    candidates.size());
5296        }
5297
5298        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
5299        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
5300        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
5301        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
5302        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
5303        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
5304
5305        synchronized (mPackages) {
5306            final int count = candidates.size();
5307            // First, try to use linked apps. Partition the candidates into four lists:
5308            // one for the final results, one for the "do not use ever", one for "undefined status"
5309            // and finally one for "browser app type".
5310            for (int n=0; n<count; n++) {
5311                ResolveInfo info = candidates.get(n);
5312                String packageName = info.activityInfo.packageName;
5313                PackageSetting ps = mSettings.mPackages.get(packageName);
5314                if (ps != null) {
5315                    // Add to the special match all list (Browser use case)
5316                    if (info.handleAllWebDataURI) {
5317                        matchAllList.add(info);
5318                        continue;
5319                    }
5320                    // Try to get the status from User settings first
5321                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5322                    int status = (int)(packedStatus >> 32);
5323                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
5324                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
5325                        if (DEBUG_DOMAIN_VERIFICATION) {
5326                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
5327                                    + " : linkgen=" + linkGeneration);
5328                        }
5329                        // Use link-enabled generation as preferredOrder, i.e.
5330                        // prefer newly-enabled over earlier-enabled.
5331                        info.preferredOrder = linkGeneration;
5332                        alwaysList.add(info);
5333                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
5334                        if (DEBUG_DOMAIN_VERIFICATION) {
5335                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
5336                        }
5337                        neverList.add(info);
5338                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5339                        if (DEBUG_DOMAIN_VERIFICATION) {
5340                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
5341                        }
5342                        alwaysAskList.add(info);
5343                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
5344                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
5345                        if (DEBUG_DOMAIN_VERIFICATION) {
5346                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
5347                        }
5348                        undefinedList.add(info);
5349                    }
5350                }
5351            }
5352
5353            // We'll want to include browser possibilities in a few cases
5354            boolean includeBrowser = false;
5355
5356            // First try to add the "always" resolution(s) for the current user, if any
5357            if (alwaysList.size() > 0) {
5358                result.addAll(alwaysList);
5359            } else {
5360                // Add all undefined apps as we want them to appear in the disambiguation dialog.
5361                result.addAll(undefinedList);
5362                // Maybe add one for the other profile.
5363                if (xpDomainInfo != null && (
5364                        xpDomainInfo.bestDomainVerificationStatus
5365                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
5366                    result.add(xpDomainInfo.resolveInfo);
5367                }
5368                includeBrowser = true;
5369            }
5370
5371            // The presence of any 'always ask' alternatives means we'll also offer browsers.
5372            // If there were 'always' entries their preferred order has been set, so we also
5373            // back that off to make the alternatives equivalent
5374            if (alwaysAskList.size() > 0) {
5375                for (ResolveInfo i : result) {
5376                    i.preferredOrder = 0;
5377                }
5378                result.addAll(alwaysAskList);
5379                includeBrowser = true;
5380            }
5381
5382            if (includeBrowser) {
5383                // Also add browsers (all of them or only the default one)
5384                if (DEBUG_DOMAIN_VERIFICATION) {
5385                    Slog.v(TAG, "   ...including browsers in candidate set");
5386                }
5387                if ((matchFlags & MATCH_ALL) != 0) {
5388                    result.addAll(matchAllList);
5389                } else {
5390                    // Browser/generic handling case.  If there's a default browser, go straight
5391                    // to that (but only if there is no other higher-priority match).
5392                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
5393                    int maxMatchPrio = 0;
5394                    ResolveInfo defaultBrowserMatch = null;
5395                    final int numCandidates = matchAllList.size();
5396                    for (int n = 0; n < numCandidates; n++) {
5397                        ResolveInfo info = matchAllList.get(n);
5398                        // track the highest overall match priority...
5399                        if (info.priority > maxMatchPrio) {
5400                            maxMatchPrio = info.priority;
5401                        }
5402                        // ...and the highest-priority default browser match
5403                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
5404                            if (defaultBrowserMatch == null
5405                                    || (defaultBrowserMatch.priority < info.priority)) {
5406                                if (debug) {
5407                                    Slog.v(TAG, "Considering default browser match " + info);
5408                                }
5409                                defaultBrowserMatch = info;
5410                            }
5411                        }
5412                    }
5413                    if (defaultBrowserMatch != null
5414                            && defaultBrowserMatch.priority >= maxMatchPrio
5415                            && !TextUtils.isEmpty(defaultBrowserPackageName))
5416                    {
5417                        if (debug) {
5418                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
5419                        }
5420                        result.add(defaultBrowserMatch);
5421                    } else {
5422                        result.addAll(matchAllList);
5423                    }
5424                }
5425
5426                // If there is nothing selected, add all candidates and remove the ones that the user
5427                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
5428                if (result.size() == 0) {
5429                    result.addAll(candidates);
5430                    result.removeAll(neverList);
5431                }
5432            }
5433        }
5434        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
5435            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
5436                    result.size());
5437            for (ResolveInfo info : result) {
5438                Slog.v(TAG, "  + " + info.activityInfo);
5439            }
5440        }
5441        return result;
5442    }
5443
5444    // Returns a packed value as a long:
5445    //
5446    // high 'int'-sized word: link status: undefined/ask/never/always.
5447    // low 'int'-sized word: relative priority among 'always' results.
5448    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
5449        long result = ps.getDomainVerificationStatusForUser(userId);
5450        // if none available, get the master status
5451        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
5452            if (ps.getIntentFilterVerificationInfo() != null) {
5453                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
5454            }
5455        }
5456        return result;
5457    }
5458
5459    private ResolveInfo querySkipCurrentProfileIntents(
5460            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5461            int flags, int sourceUserId) {
5462        if (matchingFilters != null) {
5463            int size = matchingFilters.size();
5464            for (int i = 0; i < size; i ++) {
5465                CrossProfileIntentFilter filter = matchingFilters.get(i);
5466                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
5467                    // Checking if there are activities in the target user that can handle the
5468                    // intent.
5469                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5470                            resolvedType, flags, sourceUserId);
5471                    if (resolveInfo != null) {
5472                        return resolveInfo;
5473                    }
5474                }
5475            }
5476        }
5477        return null;
5478    }
5479
5480    // Return matching ResolveInfo in target user if any.
5481    private ResolveInfo queryCrossProfileIntents(
5482            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
5483            int flags, int sourceUserId, boolean matchInCurrentProfile) {
5484        if (matchingFilters != null) {
5485            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
5486            // match the same intent. For performance reasons, it is better not to
5487            // run queryIntent twice for the same userId
5488            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
5489            int size = matchingFilters.size();
5490            for (int i = 0; i < size; i++) {
5491                CrossProfileIntentFilter filter = matchingFilters.get(i);
5492                int targetUserId = filter.getTargetUserId();
5493                boolean skipCurrentProfile =
5494                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
5495                boolean skipCurrentProfileIfNoMatchFound =
5496                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
5497                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
5498                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
5499                    // Checking if there are activities in the target user that can handle the
5500                    // intent.
5501                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
5502                            resolvedType, flags, sourceUserId);
5503                    if (resolveInfo != null) return resolveInfo;
5504                    alreadyTriedUserIds.put(targetUserId, true);
5505                }
5506            }
5507        }
5508        return null;
5509    }
5510
5511    /**
5512     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
5513     * will forward the intent to the filter's target user.
5514     * Otherwise, returns null.
5515     */
5516    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
5517            String resolvedType, int flags, int sourceUserId) {
5518        int targetUserId = filter.getTargetUserId();
5519        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
5520                resolvedType, flags, targetUserId);
5521        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
5522            // If all the matches in the target profile are suspended, return null.
5523            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
5524                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
5525                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
5526                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
5527                            targetUserId);
5528                }
5529            }
5530        }
5531        return null;
5532    }
5533
5534    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
5535            int sourceUserId, int targetUserId) {
5536        ResolveInfo forwardingResolveInfo = new ResolveInfo();
5537        long ident = Binder.clearCallingIdentity();
5538        boolean targetIsProfile;
5539        try {
5540            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
5541        } finally {
5542            Binder.restoreCallingIdentity(ident);
5543        }
5544        String className;
5545        if (targetIsProfile) {
5546            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
5547        } else {
5548            className = FORWARD_INTENT_TO_PARENT;
5549        }
5550        ComponentName forwardingActivityComponentName = new ComponentName(
5551                mAndroidApplication.packageName, className);
5552        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
5553                sourceUserId);
5554        if (!targetIsProfile) {
5555            forwardingActivityInfo.showUserIcon = targetUserId;
5556            forwardingResolveInfo.noResourceId = true;
5557        }
5558        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
5559        forwardingResolveInfo.priority = 0;
5560        forwardingResolveInfo.preferredOrder = 0;
5561        forwardingResolveInfo.match = 0;
5562        forwardingResolveInfo.isDefault = true;
5563        forwardingResolveInfo.filter = filter;
5564        forwardingResolveInfo.targetUserId = targetUserId;
5565        return forwardingResolveInfo;
5566    }
5567
5568    @Override
5569    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
5570            Intent[] specifics, String[] specificTypes, Intent intent,
5571            String resolvedType, int flags, int userId) {
5572        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
5573                specificTypes, intent, resolvedType, flags, userId));
5574    }
5575
5576    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
5577            Intent[] specifics, String[] specificTypes, Intent intent,
5578            String resolvedType, int flags, int userId) {
5579        if (!sUserManager.exists(userId)) return Collections.emptyList();
5580        flags = updateFlagsForResolve(flags, userId, intent);
5581        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5582                false /* requireFullPermission */, false /* checkShell */,
5583                "query intent activity options");
5584        final String resultsAction = intent.getAction();
5585
5586        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
5587                | PackageManager.GET_RESOLVED_FILTER, userId);
5588
5589        if (DEBUG_INTENT_MATCHING) {
5590            Log.v(TAG, "Query " + intent + ": " + results);
5591        }
5592
5593        int specificsPos = 0;
5594        int N;
5595
5596        // todo: note that the algorithm used here is O(N^2).  This
5597        // isn't a problem in our current environment, but if we start running
5598        // into situations where we have more than 5 or 10 matches then this
5599        // should probably be changed to something smarter...
5600
5601        // First we go through and resolve each of the specific items
5602        // that were supplied, taking care of removing any corresponding
5603        // duplicate items in the generic resolve list.
5604        if (specifics != null) {
5605            for (int i=0; i<specifics.length; i++) {
5606                final Intent sintent = specifics[i];
5607                if (sintent == null) {
5608                    continue;
5609                }
5610
5611                if (DEBUG_INTENT_MATCHING) {
5612                    Log.v(TAG, "Specific #" + i + ": " + sintent);
5613                }
5614
5615                String action = sintent.getAction();
5616                if (resultsAction != null && resultsAction.equals(action)) {
5617                    // If this action was explicitly requested, then don't
5618                    // remove things that have it.
5619                    action = null;
5620                }
5621
5622                ResolveInfo ri = null;
5623                ActivityInfo ai = null;
5624
5625                ComponentName comp = sintent.getComponent();
5626                if (comp == null) {
5627                    ri = resolveIntent(
5628                        sintent,
5629                        specificTypes != null ? specificTypes[i] : null,
5630                            flags, userId);
5631                    if (ri == null) {
5632                        continue;
5633                    }
5634                    if (ri == mResolveInfo) {
5635                        // ACK!  Must do something better with this.
5636                    }
5637                    ai = ri.activityInfo;
5638                    comp = new ComponentName(ai.applicationInfo.packageName,
5639                            ai.name);
5640                } else {
5641                    ai = getActivityInfo(comp, flags, userId);
5642                    if (ai == null) {
5643                        continue;
5644                    }
5645                }
5646
5647                // Look for any generic query activities that are duplicates
5648                // of this specific one, and remove them from the results.
5649                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
5650                N = results.size();
5651                int j;
5652                for (j=specificsPos; j<N; j++) {
5653                    ResolveInfo sri = results.get(j);
5654                    if ((sri.activityInfo.name.equals(comp.getClassName())
5655                            && sri.activityInfo.applicationInfo.packageName.equals(
5656                                    comp.getPackageName()))
5657                        || (action != null && sri.filter.matchAction(action))) {
5658                        results.remove(j);
5659                        if (DEBUG_INTENT_MATCHING) Log.v(
5660                            TAG, "Removing duplicate item from " + j
5661                            + " due to specific " + specificsPos);
5662                        if (ri == null) {
5663                            ri = sri;
5664                        }
5665                        j--;
5666                        N--;
5667                    }
5668                }
5669
5670                // Add this specific item to its proper place.
5671                if (ri == null) {
5672                    ri = new ResolveInfo();
5673                    ri.activityInfo = ai;
5674                }
5675                results.add(specificsPos, ri);
5676                ri.specificIndex = i;
5677                specificsPos++;
5678            }
5679        }
5680
5681        // Now we go through the remaining generic results and remove any
5682        // duplicate actions that are found here.
5683        N = results.size();
5684        for (int i=specificsPos; i<N-1; i++) {
5685            final ResolveInfo rii = results.get(i);
5686            if (rii.filter == null) {
5687                continue;
5688            }
5689
5690            // Iterate over all of the actions of this result's intent
5691            // filter...  typically this should be just one.
5692            final Iterator<String> it = rii.filter.actionsIterator();
5693            if (it == null) {
5694                continue;
5695            }
5696            while (it.hasNext()) {
5697                final String action = it.next();
5698                if (resultsAction != null && resultsAction.equals(action)) {
5699                    // If this action was explicitly requested, then don't
5700                    // remove things that have it.
5701                    continue;
5702                }
5703                for (int j=i+1; j<N; j++) {
5704                    final ResolveInfo rij = results.get(j);
5705                    if (rij.filter != null && rij.filter.hasAction(action)) {
5706                        results.remove(j);
5707                        if (DEBUG_INTENT_MATCHING) Log.v(
5708                            TAG, "Removing duplicate item from " + j
5709                            + " due to action " + action + " at " + i);
5710                        j--;
5711                        N--;
5712                    }
5713                }
5714            }
5715
5716            // If the caller didn't request filter information, drop it now
5717            // so we don't have to marshall/unmarshall it.
5718            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5719                rii.filter = null;
5720            }
5721        }
5722
5723        // Filter out the caller activity if so requested.
5724        if (caller != null) {
5725            N = results.size();
5726            for (int i=0; i<N; i++) {
5727                ActivityInfo ainfo = results.get(i).activityInfo;
5728                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
5729                        && caller.getClassName().equals(ainfo.name)) {
5730                    results.remove(i);
5731                    break;
5732                }
5733            }
5734        }
5735
5736        // If the caller didn't request filter information,
5737        // drop them now so we don't have to
5738        // marshall/unmarshall it.
5739        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
5740            N = results.size();
5741            for (int i=0; i<N; i++) {
5742                results.get(i).filter = null;
5743            }
5744        }
5745
5746        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
5747        return results;
5748    }
5749
5750    @Override
5751    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
5752            String resolvedType, int flags, int userId) {
5753        return new ParceledListSlice<>(
5754                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
5755    }
5756
5757    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
5758            String resolvedType, int flags, int userId) {
5759        if (!sUserManager.exists(userId)) return Collections.emptyList();
5760        flags = updateFlagsForResolve(flags, userId, intent);
5761        ComponentName comp = intent.getComponent();
5762        if (comp == null) {
5763            if (intent.getSelector() != null) {
5764                intent = intent.getSelector();
5765                comp = intent.getComponent();
5766            }
5767        }
5768        if (comp != null) {
5769            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5770            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
5771            if (ai != null) {
5772                ResolveInfo ri = new ResolveInfo();
5773                ri.activityInfo = ai;
5774                list.add(ri);
5775            }
5776            return list;
5777        }
5778
5779        // reader
5780        synchronized (mPackages) {
5781            String pkgName = intent.getPackage();
5782            if (pkgName == null) {
5783                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
5784            }
5785            final PackageParser.Package pkg = mPackages.get(pkgName);
5786            if (pkg != null) {
5787                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
5788                        userId);
5789            }
5790            return Collections.emptyList();
5791        }
5792    }
5793
5794    @Override
5795    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
5796        if (!sUserManager.exists(userId)) return null;
5797        flags = updateFlagsForResolve(flags, userId, intent);
5798        List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
5799        if (query != null) {
5800            if (query.size() >= 1) {
5801                // If there is more than one service with the same priority,
5802                // just arbitrarily pick the first one.
5803                return query.get(0);
5804            }
5805        }
5806        return null;
5807    }
5808
5809    @Override
5810    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
5811            String resolvedType, int flags, int userId) {
5812        return new ParceledListSlice<>(
5813                queryIntentServicesInternal(intent, resolvedType, flags, userId));
5814    }
5815
5816    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
5817            String resolvedType, int flags, int userId) {
5818        if (!sUserManager.exists(userId)) return Collections.emptyList();
5819        flags = updateFlagsForResolve(flags, userId, intent);
5820        ComponentName comp = intent.getComponent();
5821        if (comp == null) {
5822            if (intent.getSelector() != null) {
5823                intent = intent.getSelector();
5824                comp = intent.getComponent();
5825            }
5826        }
5827        if (comp != null) {
5828            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5829            final ServiceInfo si = getServiceInfo(comp, flags, userId);
5830            if (si != null) {
5831                final ResolveInfo ri = new ResolveInfo();
5832                ri.serviceInfo = si;
5833                list.add(ri);
5834            }
5835            return list;
5836        }
5837
5838        // reader
5839        synchronized (mPackages) {
5840            String pkgName = intent.getPackage();
5841            if (pkgName == null) {
5842                return mServices.queryIntent(intent, resolvedType, flags, userId);
5843            }
5844            final PackageParser.Package pkg = mPackages.get(pkgName);
5845            if (pkg != null) {
5846                return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
5847                        userId);
5848            }
5849            return Collections.emptyList();
5850        }
5851    }
5852
5853    @Override
5854    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
5855            String resolvedType, int flags, int userId) {
5856        return new ParceledListSlice<>(
5857                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
5858    }
5859
5860    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
5861            Intent intent, String resolvedType, int flags, int userId) {
5862        if (!sUserManager.exists(userId)) return Collections.emptyList();
5863        flags = updateFlagsForResolve(flags, userId, intent);
5864        ComponentName comp = intent.getComponent();
5865        if (comp == null) {
5866            if (intent.getSelector() != null) {
5867                intent = intent.getSelector();
5868                comp = intent.getComponent();
5869            }
5870        }
5871        if (comp != null) {
5872            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
5873            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
5874            if (pi != null) {
5875                final ResolveInfo ri = new ResolveInfo();
5876                ri.providerInfo = pi;
5877                list.add(ri);
5878            }
5879            return list;
5880        }
5881
5882        // reader
5883        synchronized (mPackages) {
5884            String pkgName = intent.getPackage();
5885            if (pkgName == null) {
5886                return mProviders.queryIntent(intent, resolvedType, flags, userId);
5887            }
5888            final PackageParser.Package pkg = mPackages.get(pkgName);
5889            if (pkg != null) {
5890                return mProviders.queryIntentForPackage(
5891                        intent, resolvedType, flags, pkg.providers, userId);
5892            }
5893            return Collections.emptyList();
5894        }
5895    }
5896
5897    @Override
5898    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
5899        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5900        flags = updateFlagsForPackage(flags, userId, null);
5901        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5902        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5903                true /* requireFullPermission */, false /* checkShell */,
5904                "get installed packages");
5905
5906        // writer
5907        synchronized (mPackages) {
5908            ArrayList<PackageInfo> list;
5909            if (listUninstalled) {
5910                list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
5911                for (PackageSetting ps : mSettings.mPackages.values()) {
5912                    final PackageInfo pi;
5913                    if (ps.pkg != null) {
5914                        pi = generatePackageInfo(ps, flags, userId);
5915                    } else {
5916                        pi = generatePackageInfo(ps, flags, userId);
5917                    }
5918                    if (pi != null) {
5919                        list.add(pi);
5920                    }
5921                }
5922            } else {
5923                list = new ArrayList<PackageInfo>(mPackages.size());
5924                for (PackageParser.Package p : mPackages.values()) {
5925                    final PackageInfo pi =
5926                            generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
5927                    if (pi != null) {
5928                        list.add(pi);
5929                    }
5930                }
5931            }
5932
5933            return new ParceledListSlice<PackageInfo>(list);
5934        }
5935    }
5936
5937    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
5938            String[] permissions, boolean[] tmp, int flags, int userId) {
5939        int numMatch = 0;
5940        final PermissionsState permissionsState = ps.getPermissionsState();
5941        for (int i=0; i<permissions.length; i++) {
5942            final String permission = permissions[i];
5943            if (permissionsState.hasPermission(permission, userId)) {
5944                tmp[i] = true;
5945                numMatch++;
5946            } else {
5947                tmp[i] = false;
5948            }
5949        }
5950        if (numMatch == 0) {
5951            return;
5952        }
5953        final PackageInfo pi;
5954        if (ps.pkg != null) {
5955            pi = generatePackageInfo(ps, flags, userId);
5956        } else {
5957            pi = generatePackageInfo(ps, flags, userId);
5958        }
5959        // The above might return null in cases of uninstalled apps or install-state
5960        // skew across users/profiles.
5961        if (pi != null) {
5962            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
5963                if (numMatch == permissions.length) {
5964                    pi.requestedPermissions = permissions;
5965                } else {
5966                    pi.requestedPermissions = new String[numMatch];
5967                    numMatch = 0;
5968                    for (int i=0; i<permissions.length; i++) {
5969                        if (tmp[i]) {
5970                            pi.requestedPermissions[numMatch] = permissions[i];
5971                            numMatch++;
5972                        }
5973                    }
5974                }
5975            }
5976            list.add(pi);
5977        }
5978    }
5979
5980    @Override
5981    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
5982            String[] permissions, int flags, int userId) {
5983        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
5984        flags = updateFlagsForPackage(flags, userId, permissions);
5985        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
5986
5987        // writer
5988        synchronized (mPackages) {
5989            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
5990            boolean[] tmpBools = new boolean[permissions.length];
5991            if (listUninstalled) {
5992                for (PackageSetting ps : mSettings.mPackages.values()) {
5993                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
5994                }
5995            } else {
5996                for (PackageParser.Package pkg : mPackages.values()) {
5997                    PackageSetting ps = (PackageSetting)pkg.mExtras;
5998                    if (ps != null) {
5999                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
6000                                userId);
6001                    }
6002                }
6003            }
6004
6005            return new ParceledListSlice<PackageInfo>(list);
6006        }
6007    }
6008
6009    @Override
6010    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
6011        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6012        flags = updateFlagsForApplication(flags, userId, null);
6013        final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
6014
6015        // writer
6016        synchronized (mPackages) {
6017            ArrayList<ApplicationInfo> list;
6018            if (listUninstalled) {
6019                list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
6020                for (PackageSetting ps : mSettings.mPackages.values()) {
6021                    ApplicationInfo ai;
6022                    if (ps.pkg != null) {
6023                        ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
6024                                ps.readUserState(userId), userId);
6025                    } else {
6026                        ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
6027                    }
6028                    if (ai != null) {
6029                        list.add(ai);
6030                    }
6031                }
6032            } else {
6033                list = new ArrayList<ApplicationInfo>(mPackages.size());
6034                for (PackageParser.Package p : mPackages.values()) {
6035                    if (p.mExtras != null) {
6036                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6037                                ((PackageSetting)p.mExtras).readUserState(userId), userId);
6038                        if (ai != null) {
6039                            list.add(ai);
6040                        }
6041                    }
6042                }
6043            }
6044
6045            return new ParceledListSlice<ApplicationInfo>(list);
6046        }
6047    }
6048
6049    @Override
6050    public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) {
6051        if (DISABLE_EPHEMERAL_APPS) {
6052            return null;
6053        }
6054
6055        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6056                "getEphemeralApplications");
6057        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6058                true /* requireFullPermission */, false /* checkShell */,
6059                "getEphemeralApplications");
6060        synchronized (mPackages) {
6061            List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry
6062                    .getEphemeralApplicationsLPw(userId);
6063            if (ephemeralApps != null) {
6064                return new ParceledListSlice<>(ephemeralApps);
6065            }
6066        }
6067        return null;
6068    }
6069
6070    @Override
6071    public boolean isEphemeralApplication(String packageName, int userId) {
6072        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6073                true /* requireFullPermission */, false /* checkShell */,
6074                "isEphemeral");
6075        if (DISABLE_EPHEMERAL_APPS) {
6076            return false;
6077        }
6078
6079        if (!isCallerSameApp(packageName)) {
6080            return false;
6081        }
6082        synchronized (mPackages) {
6083            PackageParser.Package pkg = mPackages.get(packageName);
6084            if (pkg != null) {
6085                return pkg.applicationInfo.isEphemeralApp();
6086            }
6087        }
6088        return false;
6089    }
6090
6091    @Override
6092    public byte[] getEphemeralApplicationCookie(String packageName, int userId) {
6093        if (DISABLE_EPHEMERAL_APPS) {
6094            return null;
6095        }
6096
6097        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6098                true /* requireFullPermission */, false /* checkShell */,
6099                "getCookie");
6100        if (!isCallerSameApp(packageName)) {
6101            return null;
6102        }
6103        synchronized (mPackages) {
6104            return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw(
6105                    packageName, userId);
6106        }
6107    }
6108
6109    @Override
6110    public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) {
6111        if (DISABLE_EPHEMERAL_APPS) {
6112            return true;
6113        }
6114
6115        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6116                true /* requireFullPermission */, true /* checkShell */,
6117                "setCookie");
6118        if (!isCallerSameApp(packageName)) {
6119            return false;
6120        }
6121        synchronized (mPackages) {
6122            return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw(
6123                    packageName, cookie, userId);
6124        }
6125    }
6126
6127    @Override
6128    public Bitmap getEphemeralApplicationIcon(String packageName, int userId) {
6129        if (DISABLE_EPHEMERAL_APPS) {
6130            return null;
6131        }
6132
6133        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS,
6134                "getEphemeralApplicationIcon");
6135        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6136                true /* requireFullPermission */, false /* checkShell */,
6137                "getEphemeralApplicationIcon");
6138        synchronized (mPackages) {
6139            return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw(
6140                    packageName, userId);
6141        }
6142    }
6143
6144    private boolean isCallerSameApp(String packageName) {
6145        PackageParser.Package pkg = mPackages.get(packageName);
6146        return pkg != null
6147                && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
6148    }
6149
6150    @Override
6151    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
6152        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
6153    }
6154
6155    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
6156        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
6157
6158        // reader
6159        synchronized (mPackages) {
6160            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
6161            final int userId = UserHandle.getCallingUserId();
6162            while (i.hasNext()) {
6163                final PackageParser.Package p = i.next();
6164                if (p.applicationInfo == null) continue;
6165
6166                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
6167                        && !p.applicationInfo.isDirectBootAware();
6168                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
6169                        && p.applicationInfo.isDirectBootAware();
6170
6171                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
6172                        && (!mSafeMode || isSystemApp(p))
6173                        && (matchesUnaware || matchesAware)) {
6174                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
6175                    if (ps != null) {
6176                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
6177                                ps.readUserState(userId), userId);
6178                        if (ai != null) {
6179                            finalList.add(ai);
6180                        }
6181                    }
6182                }
6183            }
6184        }
6185
6186        return finalList;
6187    }
6188
6189    @Override
6190    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
6191        if (!sUserManager.exists(userId)) return null;
6192        flags = updateFlagsForComponent(flags, userId, name);
6193        // reader
6194        synchronized (mPackages) {
6195            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
6196            PackageSetting ps = provider != null
6197                    ? mSettings.mPackages.get(provider.owner.packageName)
6198                    : null;
6199            return ps != null
6200                    && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)
6201                    ? PackageParser.generateProviderInfo(provider, flags,
6202                            ps.readUserState(userId), userId)
6203                    : null;
6204        }
6205    }
6206
6207    /**
6208     * @deprecated
6209     */
6210    @Deprecated
6211    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
6212        // reader
6213        synchronized (mPackages) {
6214            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
6215                    .entrySet().iterator();
6216            final int userId = UserHandle.getCallingUserId();
6217            while (i.hasNext()) {
6218                Map.Entry<String, PackageParser.Provider> entry = i.next();
6219                PackageParser.Provider p = entry.getValue();
6220                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6221
6222                if (ps != null && p.syncable
6223                        && (!mSafeMode || (p.info.applicationInfo.flags
6224                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
6225                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
6226                            ps.readUserState(userId), userId);
6227                    if (info != null) {
6228                        outNames.add(entry.getKey());
6229                        outInfo.add(info);
6230                    }
6231                }
6232            }
6233        }
6234    }
6235
6236    @Override
6237    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
6238            int uid, int flags) {
6239        final int userId = processName != null ? UserHandle.getUserId(uid)
6240                : UserHandle.getCallingUserId();
6241        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
6242        flags = updateFlagsForComponent(flags, userId, processName);
6243
6244        ArrayList<ProviderInfo> finalList = null;
6245        // reader
6246        synchronized (mPackages) {
6247            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
6248            while (i.hasNext()) {
6249                final PackageParser.Provider p = i.next();
6250                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
6251                if (ps != null && p.info.authority != null
6252                        && (processName == null
6253                                || (p.info.processName.equals(processName)
6254                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
6255                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
6256                    if (finalList == null) {
6257                        finalList = new ArrayList<ProviderInfo>(3);
6258                    }
6259                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
6260                            ps.readUserState(userId), userId);
6261                    if (info != null) {
6262                        finalList.add(info);
6263                    }
6264                }
6265            }
6266        }
6267
6268        if (finalList != null) {
6269            Collections.sort(finalList, mProviderInitOrderSorter);
6270            return new ParceledListSlice<ProviderInfo>(finalList);
6271        }
6272
6273        return ParceledListSlice.emptyList();
6274    }
6275
6276    @Override
6277    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
6278        // reader
6279        synchronized (mPackages) {
6280            final PackageParser.Instrumentation i = mInstrumentation.get(name);
6281            return PackageParser.generateInstrumentationInfo(i, flags);
6282        }
6283    }
6284
6285    @Override
6286    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
6287            String targetPackage, int flags) {
6288        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
6289    }
6290
6291    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
6292            int flags) {
6293        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
6294
6295        // reader
6296        synchronized (mPackages) {
6297            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
6298            while (i.hasNext()) {
6299                final PackageParser.Instrumentation p = i.next();
6300                if (targetPackage == null
6301                        || targetPackage.equals(p.info.targetPackage)) {
6302                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
6303                            flags);
6304                    if (ii != null) {
6305                        finalList.add(ii);
6306                    }
6307                }
6308            }
6309        }
6310
6311        return finalList;
6312    }
6313
6314    private void createIdmapsForPackageLI(PackageParser.Package pkg) {
6315        ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
6316        if (overlays == null) {
6317            Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
6318            return;
6319        }
6320        for (PackageParser.Package opkg : overlays.values()) {
6321            // Not much to do if idmap fails: we already logged the error
6322            // and we certainly don't want to abort installation of pkg simply
6323            // because an overlay didn't fit properly. For these reasons,
6324            // ignore the return value of createIdmapForPackagePairLI.
6325            createIdmapForPackagePairLI(pkg, opkg);
6326        }
6327    }
6328
6329    private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
6330            PackageParser.Package opkg) {
6331        if (!opkg.mTrustedOverlay) {
6332            Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
6333                    opkg.baseCodePath + ": overlay not trusted");
6334            return false;
6335        }
6336        ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
6337        if (overlaySet == null) {
6338            Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
6339                    opkg.baseCodePath + " but target package has no known overlays");
6340            return false;
6341        }
6342        final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
6343        // TODO: generate idmap for split APKs
6344        try {
6345            mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid);
6346        } catch (InstallerException e) {
6347            Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
6348                    + opkg.baseCodePath);
6349            return false;
6350        }
6351        PackageParser.Package[] overlayArray =
6352            overlaySet.values().toArray(new PackageParser.Package[0]);
6353        Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
6354            public int compare(PackageParser.Package p1, PackageParser.Package p2) {
6355                return p1.mOverlayPriority - p2.mOverlayPriority;
6356            }
6357        };
6358        Arrays.sort(overlayArray, cmp);
6359
6360        pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
6361        int i = 0;
6362        for (PackageParser.Package p : overlayArray) {
6363            pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
6364        }
6365        return true;
6366    }
6367
6368    private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6369        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir");
6370        try {
6371            scanDirLI(dir, parseFlags, scanFlags, currentTime);
6372        } finally {
6373            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6374        }
6375    }
6376
6377    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
6378        final File[] files = dir.listFiles();
6379        if (ArrayUtils.isEmpty(files)) {
6380            Log.d(TAG, "No files in app dir " + dir);
6381            return;
6382        }
6383
6384        if (DEBUG_PACKAGE_SCANNING) {
6385            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
6386                    + " flags=0x" + Integer.toHexString(parseFlags));
6387        }
6388
6389        for (File file : files) {
6390            final boolean isPackage = (isApkFile(file) || file.isDirectory())
6391                    && !PackageInstallerService.isStageName(file.getName());
6392            if (!isPackage) {
6393                // Ignore entries which are not packages
6394                continue;
6395            }
6396            try {
6397                scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
6398                        scanFlags, currentTime, null);
6399            } catch (PackageManagerException e) {
6400                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
6401
6402                // Delete invalid userdata apps
6403                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
6404                        e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
6405                    logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
6406                    removeCodePathLI(file);
6407                }
6408            }
6409        }
6410    }
6411
6412    private static File getSettingsProblemFile() {
6413        File dataDir = Environment.getDataDirectory();
6414        File systemDir = new File(dataDir, "system");
6415        File fname = new File(systemDir, "uiderrors.txt");
6416        return fname;
6417    }
6418
6419    static void reportSettingsProblem(int priority, String msg) {
6420        logCriticalInfo(priority, msg);
6421    }
6422
6423    static void logCriticalInfo(int priority, String msg) {
6424        Slog.println(priority, TAG, msg);
6425        EventLogTags.writePmCriticalInfo(msg);
6426        try {
6427            File fname = getSettingsProblemFile();
6428            FileOutputStream out = new FileOutputStream(fname, true);
6429            PrintWriter pw = new FastPrintWriter(out);
6430            SimpleDateFormat formatter = new SimpleDateFormat();
6431            String dateString = formatter.format(new Date(System.currentTimeMillis()));
6432            pw.println(dateString + ": " + msg);
6433            pw.close();
6434            FileUtils.setPermissions(
6435                    fname.toString(),
6436                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
6437                    -1, -1);
6438        } catch (java.io.IOException e) {
6439        }
6440    }
6441
6442    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
6443            int parseFlags) throws PackageManagerException {
6444        if (ps != null
6445                && ps.codePath.equals(srcFile)
6446                && ps.timeStamp == srcFile.lastModified()
6447                && !isCompatSignatureUpdateNeeded(pkg)
6448                && !isRecoverSignatureUpdateNeeded(pkg)) {
6449            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
6450            KeySetManagerService ksms = mSettings.mKeySetManagerService;
6451            ArraySet<PublicKey> signingKs;
6452            synchronized (mPackages) {
6453                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
6454            }
6455            if (ps.signatures.mSignatures != null
6456                    && ps.signatures.mSignatures.length != 0
6457                    && signingKs != null) {
6458                // Optimization: reuse the existing cached certificates
6459                // if the package appears to be unchanged.
6460                pkg.mSignatures = ps.signatures.mSignatures;
6461                pkg.mSigningKeys = signingKs;
6462                return;
6463            }
6464
6465            Slog.w(TAG, "PackageSetting for " + ps.name
6466                    + " is missing signatures.  Collecting certs again to recover them.");
6467        } else {
6468            Log.i(TAG, srcFile.toString() + " changed; collecting certs");
6469        }
6470
6471        try {
6472            PackageParser.collectCertificates(pkg, parseFlags);
6473        } catch (PackageParserException e) {
6474            throw PackageManagerException.from(e);
6475        }
6476    }
6477
6478    /**
6479     *  Traces a package scan.
6480     *  @see #scanPackageLI(File, int, int, long, UserHandle)
6481     */
6482    private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags,
6483            long currentTime, UserHandle user) throws PackageManagerException {
6484        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
6485        try {
6486            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
6487        } finally {
6488            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6489        }
6490    }
6491
6492    /**
6493     *  Scans a package and returns the newly parsed package.
6494     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
6495     */
6496    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
6497            long currentTime, UserHandle user) throws PackageManagerException {
6498        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
6499        parseFlags |= mDefParseFlags;
6500        PackageParser pp = new PackageParser();
6501        pp.setSeparateProcesses(mSeparateProcesses);
6502        pp.setOnlyCoreApps(mOnlyCore);
6503        pp.setDisplayMetrics(mMetrics);
6504
6505        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
6506            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
6507        }
6508
6509        final PackageParser.Package pkg;
6510        try {
6511            pkg = pp.parsePackage(scanFile, parseFlags);
6512        } catch (PackageParserException e) {
6513            throw PackageManagerException.from(e);
6514        }
6515
6516        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6517    }
6518
6519    /**
6520     *  Scans a package and returns the newly parsed package.
6521     *  @throws PackageManagerException on a parse error.
6522     */
6523    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
6524            int parseFlags, int scanFlags, long currentTime, UserHandle user)
6525            throws PackageManagerException {
6526        // If the package has children and this is the first dive in the function
6527        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
6528        // packages (parent and children) would be successfully scanned before the
6529        // actual scan since scanning mutates internal state and we want to atomically
6530        // install the package and its children.
6531        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
6532            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
6533                scanFlags |= SCAN_CHECK_ONLY;
6534            }
6535        } else {
6536            scanFlags &= ~SCAN_CHECK_ONLY;
6537        }
6538
6539        // Scan the parent
6540        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags,
6541                scanFlags, currentTime, user);
6542
6543        // Scan the children
6544        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
6545        for (int i = 0; i < childCount; i++) {
6546            PackageParser.Package childPackage = pkg.childPackages.get(i);
6547            scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags,
6548                    currentTime, user);
6549        }
6550
6551
6552        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
6553            return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
6554        }
6555
6556        return scannedPkg;
6557    }
6558
6559    /**
6560     *  Scans a package and returns the newly parsed package.
6561     *  @throws PackageManagerException on a parse error.
6562     */
6563    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
6564            int parseFlags, int scanFlags, long currentTime, UserHandle user)
6565            throws PackageManagerException {
6566        PackageSetting ps = null;
6567        PackageSetting updatedPkg;
6568        // reader
6569        synchronized (mPackages) {
6570            // Look to see if we already know about this package.
6571            String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
6572            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
6573                // This package has been renamed to its original name.  Let's
6574                // use that.
6575                ps = mSettings.peekPackageLPr(oldName);
6576            }
6577            // If there was no original package, see one for the real package name.
6578            if (ps == null) {
6579                ps = mSettings.peekPackageLPr(pkg.packageName);
6580            }
6581            // Check to see if this package could be hiding/updating a system
6582            // package.  Must look for it either under the original or real
6583            // package name depending on our state.
6584            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
6585            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
6586
6587            // If this is a package we don't know about on the system partition, we
6588            // may need to remove disabled child packages on the system partition
6589            // or may need to not add child packages if the parent apk is updated
6590            // on the data partition and no longer defines this child package.
6591            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6592                // If this is a parent package for an updated system app and this system
6593                // app got an OTA update which no longer defines some of the child packages
6594                // we have to prune them from the disabled system packages.
6595                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
6596                if (disabledPs != null) {
6597                    final int scannedChildCount = (pkg.childPackages != null)
6598                            ? pkg.childPackages.size() : 0;
6599                    final int disabledChildCount = disabledPs.childPackageNames != null
6600                            ? disabledPs.childPackageNames.size() : 0;
6601                    for (int i = 0; i < disabledChildCount; i++) {
6602                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
6603                        boolean disabledPackageAvailable = false;
6604                        for (int j = 0; j < scannedChildCount; j++) {
6605                            PackageParser.Package childPkg = pkg.childPackages.get(j);
6606                            if (childPkg.packageName.equals(disabledChildPackageName)) {
6607                                disabledPackageAvailable = true;
6608                                break;
6609                            }
6610                         }
6611                         if (!disabledPackageAvailable) {
6612                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
6613                         }
6614                    }
6615                }
6616            }
6617        }
6618
6619        boolean updatedPkgBetter = false;
6620        // First check if this is a system package that may involve an update
6621        if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
6622            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
6623            // it needs to drop FLAG_PRIVILEGED.
6624            if (locationIsPrivileged(scanFile)) {
6625                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6626            } else {
6627                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
6628            }
6629
6630            if (ps != null && !ps.codePath.equals(scanFile)) {
6631                // The path has changed from what was last scanned...  check the
6632                // version of the new path against what we have stored to determine
6633                // what to do.
6634                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
6635                if (pkg.mVersionCode <= ps.versionCode) {
6636                    // The system package has been updated and the code path does not match
6637                    // Ignore entry. Skip it.
6638                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
6639                            + " ignored: updated version " + ps.versionCode
6640                            + " better than this " + pkg.mVersionCode);
6641                    if (!updatedPkg.codePath.equals(scanFile)) {
6642                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
6643                                + ps.name + " changing from " + updatedPkg.codePathString
6644                                + " to " + scanFile);
6645                        updatedPkg.codePath = scanFile;
6646                        updatedPkg.codePathString = scanFile.toString();
6647                        updatedPkg.resourcePath = scanFile;
6648                        updatedPkg.resourcePathString = scanFile.toString();
6649                    }
6650                    updatedPkg.pkg = pkg;
6651                    updatedPkg.versionCode = pkg.mVersionCode;
6652
6653                    // Update the disabled system child packages to point to the package too.
6654                    final int childCount = updatedPkg.childPackageNames != null
6655                            ? updatedPkg.childPackageNames.size() : 0;
6656                    for (int i = 0; i < childCount; i++) {
6657                        String childPackageName = updatedPkg.childPackageNames.get(i);
6658                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
6659                                childPackageName);
6660                        if (updatedChildPkg != null) {
6661                            updatedChildPkg.pkg = pkg;
6662                            updatedChildPkg.versionCode = pkg.mVersionCode;
6663                        }
6664                    }
6665
6666                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
6667                            + scanFile + " ignored: updated version " + ps.versionCode
6668                            + " better than this " + pkg.mVersionCode);
6669                } else {
6670                    // The current app on the system partition is better than
6671                    // what we have updated to on the data partition; switch
6672                    // back to the system partition version.
6673                    // At this point, its safely assumed that package installation for
6674                    // apps in system partition will go through. If not there won't be a working
6675                    // version of the app
6676                    // writer
6677                    synchronized (mPackages) {
6678                        // Just remove the loaded entries from package lists.
6679                        mPackages.remove(ps.name);
6680                    }
6681
6682                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6683                            + " reverting from " + ps.codePathString
6684                            + ": new version " + pkg.mVersionCode
6685                            + " better than installed " + ps.versionCode);
6686
6687                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6688                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6689                    synchronized (mInstallLock) {
6690                        args.cleanUpResourcesLI();
6691                    }
6692                    synchronized (mPackages) {
6693                        mSettings.enableSystemPackageLPw(ps.name);
6694                    }
6695                    updatedPkgBetter = true;
6696                }
6697            }
6698        }
6699
6700        if (updatedPkg != null) {
6701            // An updated system app will not have the PARSE_IS_SYSTEM flag set
6702            // initially
6703            parseFlags |= PackageParser.PARSE_IS_SYSTEM;
6704
6705            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
6706            // flag set initially
6707            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
6708                parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
6709            }
6710        }
6711
6712        // Verify certificates against what was last scanned
6713        collectCertificatesLI(ps, pkg, scanFile, parseFlags);
6714
6715        /*
6716         * A new system app appeared, but we already had a non-system one of the
6717         * same name installed earlier.
6718         */
6719        boolean shouldHideSystemApp = false;
6720        if (updatedPkg == null && ps != null
6721                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
6722            /*
6723             * Check to make sure the signatures match first. If they don't,
6724             * wipe the installed application and its data.
6725             */
6726            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
6727                    != PackageManager.SIGNATURE_MATCH) {
6728                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
6729                        + " signatures don't match existing userdata copy; removing");
6730                deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null);
6731                ps = null;
6732            } else {
6733                /*
6734                 * If the newly-added system app is an older version than the
6735                 * already installed version, hide it. It will be scanned later
6736                 * and re-added like an update.
6737                 */
6738                if (pkg.mVersionCode <= ps.versionCode) {
6739                    shouldHideSystemApp = true;
6740                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
6741                            + " but new version " + pkg.mVersionCode + " better than installed "
6742                            + ps.versionCode + "; hiding system");
6743                } else {
6744                    /*
6745                     * The newly found system app is a newer version that the
6746                     * one previously installed. Simply remove the
6747                     * already-installed application and replace it with our own
6748                     * while keeping the application data.
6749                     */
6750                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
6751                            + " reverting from " + ps.codePathString + ": new version "
6752                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
6753                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
6754                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
6755                    synchronized (mInstallLock) {
6756                        args.cleanUpResourcesLI();
6757                    }
6758                }
6759            }
6760        }
6761
6762        // The apk is forward locked (not public) if its code and resources
6763        // are kept in different files. (except for app in either system or
6764        // vendor path).
6765        // TODO grab this value from PackageSettings
6766        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
6767            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
6768                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
6769            }
6770        }
6771
6772        // TODO: extend to support forward-locked splits
6773        String resourcePath = null;
6774        String baseResourcePath = null;
6775        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
6776            if (ps != null && ps.resourcePathString != null) {
6777                resourcePath = ps.resourcePathString;
6778                baseResourcePath = ps.resourcePathString;
6779            } else {
6780                // Should not happen at all. Just log an error.
6781                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
6782            }
6783        } else {
6784            resourcePath = pkg.codePath;
6785            baseResourcePath = pkg.baseCodePath;
6786        }
6787
6788        // Set application objects path explicitly.
6789        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
6790        pkg.setApplicationInfoCodePath(pkg.codePath);
6791        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
6792        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
6793        pkg.setApplicationInfoResourcePath(resourcePath);
6794        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
6795        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
6796
6797        // Note that we invoke the following method only if we are about to unpack an application
6798        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
6799                | SCAN_UPDATE_SIGNATURE, currentTime, user);
6800
6801        /*
6802         * If the system app should be overridden by a previously installed
6803         * data, hide the system app now and let the /data/app scan pick it up
6804         * again.
6805         */
6806        if (shouldHideSystemApp) {
6807            synchronized (mPackages) {
6808                mSettings.disableSystemPackageLPw(pkg.packageName, true);
6809            }
6810        }
6811
6812        return scannedPkg;
6813    }
6814
6815    private static String fixProcessName(String defProcessName,
6816            String processName, int uid) {
6817        if (processName == null) {
6818            return defProcessName;
6819        }
6820        return processName;
6821    }
6822
6823    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
6824            throws PackageManagerException {
6825        if (pkgSetting.signatures.mSignatures != null) {
6826            // Already existing package. Make sure signatures match
6827            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
6828                    == PackageManager.SIGNATURE_MATCH;
6829            if (!match) {
6830                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
6831                        == PackageManager.SIGNATURE_MATCH;
6832            }
6833            if (!match) {
6834                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
6835                        == PackageManager.SIGNATURE_MATCH;
6836            }
6837            if (!match) {
6838                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
6839                        + pkg.packageName + " signatures do not match the "
6840                        + "previously installed version; ignoring!");
6841            }
6842        }
6843
6844        // Check for shared user signatures
6845        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
6846            // Already existing package. Make sure signatures match
6847            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
6848                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
6849            if (!match) {
6850                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
6851                        == PackageManager.SIGNATURE_MATCH;
6852            }
6853            if (!match) {
6854                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
6855                        == PackageManager.SIGNATURE_MATCH;
6856            }
6857            if (!match) {
6858                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
6859                        "Package " + pkg.packageName
6860                        + " has no signatures that match those in shared user "
6861                        + pkgSetting.sharedUser.name + "; ignoring!");
6862            }
6863        }
6864    }
6865
6866    /**
6867     * Enforces that only the system UID or root's UID can call a method exposed
6868     * via Binder.
6869     *
6870     * @param message used as message if SecurityException is thrown
6871     * @throws SecurityException if the caller is not system or root
6872     */
6873    private static final void enforceSystemOrRoot(String message) {
6874        final int uid = Binder.getCallingUid();
6875        if (uid != Process.SYSTEM_UID && uid != 0) {
6876            throw new SecurityException(message);
6877        }
6878    }
6879
6880    @Override
6881    public void performFstrimIfNeeded() {
6882        enforceSystemOrRoot("Only the system can request fstrim");
6883
6884        // Before everything else, see whether we need to fstrim.
6885        try {
6886            IMountService ms = PackageHelper.getMountService();
6887            if (ms != null) {
6888                final boolean isUpgrade = isUpgrade();
6889                boolean doTrim = isUpgrade;
6890                if (doTrim) {
6891                    Slog.w(TAG, "Running disk maintenance immediately due to system update");
6892                } else {
6893                    final long interval = android.provider.Settings.Global.getLong(
6894                            mContext.getContentResolver(),
6895                            android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
6896                            DEFAULT_MANDATORY_FSTRIM_INTERVAL);
6897                    if (interval > 0) {
6898                        final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
6899                        if (timeSinceLast > interval) {
6900                            doTrim = true;
6901                            Slog.w(TAG, "No disk maintenance in " + timeSinceLast
6902                                    + "; running immediately");
6903                        }
6904                    }
6905                }
6906                if (doTrim) {
6907                    if (!isFirstBoot()) {
6908                        try {
6909                            ActivityManagerNative.getDefault().showBootMessage(
6910                                    mContext.getResources().getString(
6911                                            R.string.android_upgrading_fstrim), true);
6912                        } catch (RemoteException e) {
6913                        }
6914                    }
6915                    ms.runMaintenance();
6916                }
6917            } else {
6918                Slog.e(TAG, "Mount service unavailable!");
6919            }
6920        } catch (RemoteException e) {
6921            // Can't happen; MountService is local
6922        }
6923    }
6924
6925    @Override
6926    public void updatePackagesIfNeeded() {
6927        enforceSystemOrRoot("Only the system can request package update");
6928
6929        // We need to re-extract after an OTA.
6930        boolean causeUpgrade = isUpgrade();
6931
6932        // First boot or factory reset.
6933        // Note: we also handle devices that are upgrading to N right now as if it is their
6934        //       first boot, as they do not have profile data.
6935        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
6936
6937        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
6938        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
6939
6940        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
6941            return;
6942        }
6943
6944        List<PackageParser.Package> pkgs;
6945        synchronized (mPackages) {
6946            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
6947        }
6948
6949        int curr = 0;
6950        int total = pkgs.size();
6951        for (PackageParser.Package pkg : pkgs) {
6952            curr++;
6953
6954            if (DEBUG_DEXOPT) {
6955                Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName);
6956            }
6957
6958            if (PackageDexOptimizer.canOptimizePackage(pkg)) {
6959                // If the cache was pruned, any compiled odex files will likely be out of date
6960                // and would have to be patched (would be SELF_PATCHOAT, which is deprecated).
6961                // Instead, force the extraction in this case.
6962                performDexOpt(pkg.packageName,
6963                        null /* instructionSet */,
6964                        false /* checkProfiles */,
6965                        causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
6966                        false /* force */);
6967            }
6968        }
6969    }
6970
6971    @Override
6972    public void notifyPackageUse(String packageName) {
6973        synchronized (mPackages) {
6974            PackageParser.Package p = mPackages.get(packageName);
6975            if (p == null) {
6976                return;
6977            }
6978            p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
6979        }
6980    }
6981
6982    // TODO: this is not used nor needed. Delete it.
6983    @Override
6984    public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
6985        return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */,
6986                getFullCompilerFilter(), false /* force */);
6987    }
6988
6989    @Override
6990    public boolean performDexOpt(String packageName, String instructionSet,
6991            boolean checkProfiles, int compileReason, boolean force) {
6992        return performDexOptTraced(packageName, instructionSet, checkProfiles,
6993                getCompilerFilterForReason(compileReason), force);
6994    }
6995
6996    @Override
6997    public boolean performDexOptMode(String packageName, String instructionSet,
6998            boolean checkProfiles, String targetCompilerFilter, boolean force) {
6999        return performDexOptTraced(packageName, instructionSet, checkProfiles,
7000                targetCompilerFilter, force);
7001    }
7002
7003    private boolean performDexOptTraced(String packageName, String instructionSet,
7004                boolean checkProfiles, String targetCompilerFilter, boolean force) {
7005        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7006        try {
7007            return performDexOptInternal(packageName, instructionSet, checkProfiles,
7008                    targetCompilerFilter, force);
7009        } finally {
7010            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7011        }
7012    }
7013
7014    private boolean performDexOptInternal(String packageName, String instructionSet,
7015                boolean checkProfiles, String targetCompilerFilter, boolean force) {
7016        PackageParser.Package p;
7017        final String targetInstructionSet;
7018        synchronized (mPackages) {
7019            p = mPackages.get(packageName);
7020            if (p == null) {
7021                return false;
7022            }
7023            mPackageUsage.write(false);
7024
7025            targetInstructionSet = instructionSet != null ? instructionSet :
7026                    getPrimaryInstructionSet(p.applicationInfo);
7027        }
7028        long callingId = Binder.clearCallingIdentity();
7029        try {
7030            synchronized (mInstallLock) {
7031                final String[] instructionSets = new String[] { targetInstructionSet };
7032                int result = performDexOptInternalWithDependenciesLI(p, instructionSets,
7033                        checkProfiles, targetCompilerFilter, force);
7034                return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
7035            }
7036        } finally {
7037            Binder.restoreCallingIdentity(callingId);
7038        }
7039    }
7040
7041    public ArraySet<String> getOptimizablePackages() {
7042        ArraySet<String> pkgs = new ArraySet<String>();
7043        synchronized (mPackages) {
7044            for (PackageParser.Package p : mPackages.values()) {
7045                if (PackageDexOptimizer.canOptimizePackage(p)) {
7046                    pkgs.add(p.packageName);
7047                }
7048            }
7049        }
7050        return pkgs;
7051    }
7052
7053    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
7054            String instructionSets[], boolean checkProfiles, String targetCompilerFilter,
7055            boolean force) {
7056        // Select the dex optimizer based on the force parameter.
7057        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
7058        //       allocate an object here.
7059        PackageDexOptimizer pdo = force
7060                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
7061                : mPackageDexOptimizer;
7062
7063        // Optimize all dependencies first. Note: we ignore the return value and march on
7064        // on errors.
7065        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
7066        if (!deps.isEmpty()) {
7067            for (PackageParser.Package depPackage : deps) {
7068                // TODO: Analyze and investigate if we (should) profile libraries.
7069                // Currently this will do a full compilation of the library by default.
7070                pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */,
7071                        getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY));
7072            }
7073        }
7074
7075        return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter);
7076    }
7077
7078    Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
7079        if (p.usesLibraries != null || p.usesOptionalLibraries != null) {
7080            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
7081            Set<String> collectedNames = new HashSet<>();
7082            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
7083
7084            retValue.remove(p);
7085
7086            return retValue;
7087        } else {
7088            return Collections.emptyList();
7089        }
7090    }
7091
7092    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
7093            Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7094        if (!collectedNames.contains(p.packageName)) {
7095            collectedNames.add(p.packageName);
7096            collected.add(p);
7097
7098            if (p.usesLibraries != null) {
7099                findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames);
7100            }
7101            if (p.usesOptionalLibraries != null) {
7102                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected,
7103                        collectedNames);
7104            }
7105        }
7106    }
7107
7108    private void findSharedNonSystemLibrariesRecursive(Collection<String> libs,
7109            Collection<PackageParser.Package> collected, Set<String> collectedNames) {
7110        for (String libName : libs) {
7111            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName);
7112            if (libPkg != null) {
7113                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
7114            }
7115        }
7116    }
7117
7118    private PackageParser.Package findSharedNonSystemLibrary(String libName) {
7119        synchronized (mPackages) {
7120            PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName);
7121            if (lib != null && lib.apk != null) {
7122                return mPackages.get(lib.apk);
7123            }
7124        }
7125        return null;
7126    }
7127
7128    public void shutdown() {
7129        mPackageUsage.write(true);
7130    }
7131
7132    @Override
7133    public void forceDexOpt(String packageName) {
7134        enforceSystemOrRoot("forceDexOpt");
7135
7136        PackageParser.Package pkg;
7137        synchronized (mPackages) {
7138            pkg = mPackages.get(packageName);
7139            if (pkg == null) {
7140                throw new IllegalArgumentException("Unknown package: " + packageName);
7141            }
7142        }
7143
7144        synchronized (mInstallLock) {
7145            final String[] instructionSets = new String[] {
7146                    getPrimaryInstructionSet(pkg.applicationInfo) };
7147
7148            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
7149
7150            // Whoever is calling forceDexOpt wants a fully compiled package.
7151            // Don't use profiles since that may cause compilation to be skipped.
7152            final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets,
7153                    false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT),
7154                    true /* force */);
7155
7156            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7157            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
7158                throw new IllegalStateException("Failed to dexopt: " + res);
7159            }
7160        }
7161    }
7162
7163    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
7164        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
7165            Slog.w(TAG, "Unable to update from " + oldPkg.name
7166                    + " to " + newPkg.packageName
7167                    + ": old package not in system partition");
7168            return false;
7169        } else if (mPackages.get(oldPkg.name) != null) {
7170            Slog.w(TAG, "Unable to update from " + oldPkg.name
7171                    + " to " + newPkg.packageName
7172                    + ": old package still exists");
7173            return false;
7174        }
7175        return true;
7176    }
7177
7178    private boolean removeDataDirsLI(String volumeUuid, String packageName) {
7179        // TODO: triage flags as part of 26466827
7180        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
7181
7182        boolean res = true;
7183        final int[] users = sUserManager.getUserIds();
7184        for (int user : users) {
7185            try {
7186                mInstaller.destroyAppData(volumeUuid, packageName, user, flags);
7187            } catch (InstallerException e) {
7188                Slog.w(TAG, "Failed to delete data directory", e);
7189                res = false;
7190            }
7191        }
7192        return res;
7193    }
7194
7195    void removeCodePathLI(File codePath) {
7196        if (codePath.isDirectory()) {
7197            try {
7198                mInstaller.rmPackageDir(codePath.getAbsolutePath());
7199            } catch (InstallerException e) {
7200                Slog.w(TAG, "Failed to remove code path", e);
7201            }
7202        } else {
7203            codePath.delete();
7204        }
7205    }
7206
7207    void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) {
7208        try {
7209            mInstaller.destroyAppData(volumeUuid, packageName, userId, flags);
7210        } catch (InstallerException e) {
7211            Slog.w(TAG, "Failed to destroy app data", e);
7212        }
7213    }
7214
7215    void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags,
7216            int appId, String seinfo) {
7217        try {
7218            mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo);
7219        } catch (InstallerException e) {
7220            Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e);
7221        }
7222    }
7223
7224    private void deleteProfilesLI(String packageName, boolean destroy) {
7225        final PackageParser.Package pkg;
7226        synchronized (mPackages) {
7227            pkg = mPackages.get(packageName);
7228        }
7229        if (pkg == null) {
7230            Slog.w(TAG, "Failed to delete profiles. No package: " + packageName);
7231            return;
7232        }
7233        deleteProfilesLI(pkg, destroy);
7234    }
7235
7236    private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) {
7237        try {
7238            if (destroy) {
7239                mInstaller.destroyAppProfiles(pkg.packageName);
7240            } else {
7241                mInstaller.clearAppProfiles(pkg.packageName);
7242            }
7243        } catch (InstallerException ex) {
7244            Log.e(TAG, "Could not delete profiles for package " + pkg.packageName);
7245        }
7246    }
7247
7248    private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
7249        final PackageParser.Package pkg;
7250        synchronized (mPackages) {
7251            pkg = mPackages.get(packageName);
7252        }
7253        if (pkg == null) {
7254            Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName);
7255            return;
7256        }
7257        deleteCodeCacheDirsLI(pkg);
7258    }
7259
7260    private void deleteCodeCacheDirsLI(PackageParser.Package pkg) {
7261        // TODO: triage flags as part of 26466827
7262        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
7263
7264        int[] users = sUserManager.getUserIds();
7265        int res = 0;
7266        for (int user : users) {
7267            // Remove the parent code cache
7268            try {
7269                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user,
7270                        flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
7271            } catch (InstallerException e) {
7272                Slog.w(TAG, "Failed to delete code cache directory", e);
7273            }
7274            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7275            for (int i = 0; i < childCount; i++) {
7276                PackageParser.Package childPkg = pkg.childPackages.get(i);
7277                // Remove the child code cache
7278                try {
7279                    mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName,
7280                            user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
7281                } catch (InstallerException e) {
7282                    Slog.w(TAG, "Failed to delete code cache directory", e);
7283                }
7284            }
7285        }
7286    }
7287
7288    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
7289            long lastUpdateTime) {
7290        // Set parent install/update time
7291        PackageSetting ps = (PackageSetting) pkg.mExtras;
7292        if (ps != null) {
7293            ps.firstInstallTime = firstInstallTime;
7294            ps.lastUpdateTime = lastUpdateTime;
7295        }
7296        // Set children install/update time
7297        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7298        for (int i = 0; i < childCount; i++) {
7299            PackageParser.Package childPkg = pkg.childPackages.get(i);
7300            ps = (PackageSetting) childPkg.mExtras;
7301            if (ps != null) {
7302                ps.firstInstallTime = firstInstallTime;
7303                ps.lastUpdateTime = lastUpdateTime;
7304            }
7305        }
7306    }
7307
7308    private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
7309            PackageParser.Package changingLib) {
7310        if (file.path != null) {
7311            usesLibraryFiles.add(file.path);
7312            return;
7313        }
7314        PackageParser.Package p = mPackages.get(file.apk);
7315        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
7316            // If we are doing this while in the middle of updating a library apk,
7317            // then we need to make sure to use that new apk for determining the
7318            // dependencies here.  (We haven't yet finished committing the new apk
7319            // to the package manager state.)
7320            if (p == null || p.packageName.equals(changingLib.packageName)) {
7321                p = changingLib;
7322            }
7323        }
7324        if (p != null) {
7325            usesLibraryFiles.addAll(p.getAllCodePaths());
7326        }
7327    }
7328
7329    private void updateSharedLibrariesLPw(PackageParser.Package pkg,
7330            PackageParser.Package changingLib) throws PackageManagerException {
7331        if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
7332            final ArraySet<String> usesLibraryFiles = new ArraySet<>();
7333            int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
7334            for (int i=0; i<N; i++) {
7335                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
7336                if (file == null) {
7337                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
7338                            "Package " + pkg.packageName + " requires unavailable shared library "
7339                            + pkg.usesLibraries.get(i) + "; failing!");
7340                }
7341                addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7342            }
7343            N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
7344            for (int i=0; i<N; i++) {
7345                final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
7346                if (file == null) {
7347                    Slog.w(TAG, "Package " + pkg.packageName
7348                            + " desires unavailable shared library "
7349                            + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
7350                } else {
7351                    addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
7352                }
7353            }
7354            N = usesLibraryFiles.size();
7355            if (N > 0) {
7356                pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
7357            } else {
7358                pkg.usesLibraryFiles = null;
7359            }
7360        }
7361    }
7362
7363    private static boolean hasString(List<String> list, List<String> which) {
7364        if (list == null) {
7365            return false;
7366        }
7367        for (int i=list.size()-1; i>=0; i--) {
7368            for (int j=which.size()-1; j>=0; j--) {
7369                if (which.get(j).equals(list.get(i))) {
7370                    return true;
7371                }
7372            }
7373        }
7374        return false;
7375    }
7376
7377    private void updateAllSharedLibrariesLPw() {
7378        for (PackageParser.Package pkg : mPackages.values()) {
7379            try {
7380                updateSharedLibrariesLPw(pkg, null);
7381            } catch (PackageManagerException e) {
7382                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7383            }
7384        }
7385    }
7386
7387    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
7388            PackageParser.Package changingPkg) {
7389        ArrayList<PackageParser.Package> res = null;
7390        for (PackageParser.Package pkg : mPackages.values()) {
7391            if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
7392                    || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
7393                if (res == null) {
7394                    res = new ArrayList<PackageParser.Package>();
7395                }
7396                res.add(pkg);
7397                try {
7398                    updateSharedLibrariesLPw(pkg, changingPkg);
7399                } catch (PackageManagerException e) {
7400                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
7401                }
7402            }
7403        }
7404        return res;
7405    }
7406
7407    /**
7408     * Derive the value of the {@code cpuAbiOverride} based on the provided
7409     * value and an optional stored value from the package settings.
7410     */
7411    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
7412        String cpuAbiOverride = null;
7413
7414        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
7415            cpuAbiOverride = null;
7416        } else if (abiOverride != null) {
7417            cpuAbiOverride = abiOverride;
7418        } else if (settings != null) {
7419            cpuAbiOverride = settings.cpuAbiOverrideString;
7420        }
7421
7422        return cpuAbiOverride;
7423    }
7424
7425    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
7426            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7427        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
7428        // If the package has children and this is the first dive in the function
7429        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
7430        // whether all packages (parent and children) would be successfully scanned
7431        // before the actual scan since scanning mutates internal state and we want
7432        // to atomically install the package and its children.
7433        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7434            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
7435                scanFlags |= SCAN_CHECK_ONLY;
7436            }
7437        } else {
7438            scanFlags &= ~SCAN_CHECK_ONLY;
7439        }
7440
7441        final PackageParser.Package scannedPkg;
7442        try {
7443            // Scan the parent
7444            scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
7445            // Scan the children
7446            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
7447            for (int i = 0; i < childCount; i++) {
7448                PackageParser.Package childPkg = pkg.childPackages.get(i);
7449                scanPackageLI(childPkg, parseFlags,
7450                        scanFlags, currentTime, user);
7451            }
7452        } finally {
7453            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7454        }
7455
7456        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7457            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
7458        }
7459
7460        return scannedPkg;
7461    }
7462
7463    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
7464            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7465        boolean success = false;
7466        try {
7467            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
7468                    currentTime, user);
7469            success = true;
7470            return res;
7471        } finally {
7472            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
7473                removeDataDirsLI(pkg.volumeUuid, pkg.packageName);
7474            }
7475        }
7476    }
7477
7478    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
7479            int scanFlags, long currentTime, UserHandle user)
7480            throws PackageManagerException {
7481        final File scanFile = new File(pkg.codePath);
7482        if (pkg.applicationInfo.getCodePath() == null ||
7483                pkg.applicationInfo.getResourcePath() == null) {
7484            // Bail out. The resource and code paths haven't been set.
7485            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
7486                    "Code and resource paths haven't been set correctly");
7487        }
7488
7489        if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
7490            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
7491        } else {
7492            // Only allow system apps to be flagged as core apps.
7493            pkg.coreApp = false;
7494        }
7495
7496        if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
7497            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
7498        }
7499
7500        if (mCustomResolverComponentName != null &&
7501                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
7502            setUpCustomResolverActivity(pkg);
7503        }
7504
7505        if (pkg.packageName.equals("android")) {
7506            synchronized (mPackages) {
7507                if (mAndroidApplication != null) {
7508                    Slog.w(TAG, "*************************************************");
7509                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
7510                    Slog.w(TAG, " file=" + scanFile);
7511                    Slog.w(TAG, "*************************************************");
7512                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7513                            "Core android package being redefined.  Skipping.");
7514                }
7515
7516                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7517                    // Set up information for our fall-back user intent resolution activity.
7518                    mPlatformPackage = pkg;
7519                    pkg.mVersionCode = mSdkVersion;
7520                    mAndroidApplication = pkg.applicationInfo;
7521
7522                    if (!mResolverReplaced) {
7523                        mResolveActivity.applicationInfo = mAndroidApplication;
7524                        mResolveActivity.name = ResolverActivity.class.getName();
7525                        mResolveActivity.packageName = mAndroidApplication.packageName;
7526                        mResolveActivity.processName = "system:ui";
7527                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
7528                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
7529                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
7530                        mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
7531                        mResolveActivity.exported = true;
7532                        mResolveActivity.enabled = true;
7533                        mResolveInfo.activityInfo = mResolveActivity;
7534                        mResolveInfo.priority = 0;
7535                        mResolveInfo.preferredOrder = 0;
7536                        mResolveInfo.match = 0;
7537                        mResolveComponentName = new ComponentName(
7538                                mAndroidApplication.packageName, mResolveActivity.name);
7539                    }
7540                }
7541            }
7542        }
7543
7544        if (DEBUG_PACKAGE_SCANNING) {
7545            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7546                Log.d(TAG, "Scanning package " + pkg.packageName);
7547        }
7548
7549        synchronized (mPackages) {
7550            if (mPackages.containsKey(pkg.packageName)
7551                    || mSharedLibraries.containsKey(pkg.packageName)) {
7552                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
7553                        "Application package " + pkg.packageName
7554                                + " already installed.  Skipping duplicate.");
7555            }
7556
7557            // If we're only installing presumed-existing packages, require that the
7558            // scanned APK is both already known and at the path previously established
7559            // for it.  Previously unknown packages we pick up normally, but if we have an
7560            // a priori expectation about this package's install presence, enforce it.
7561            // With a singular exception for new system packages. When an OTA contains
7562            // a new system package, we allow the codepath to change from a system location
7563            // to the user-installed location. If we don't allow this change, any newer,
7564            // user-installed version of the application will be ignored.
7565            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
7566                if (mExpectingBetter.containsKey(pkg.packageName)) {
7567                    logCriticalInfo(Log.WARN,
7568                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
7569                } else {
7570                    PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
7571                    if (known != null) {
7572                        if (DEBUG_PACKAGE_SCANNING) {
7573                            Log.d(TAG, "Examining " + pkg.codePath
7574                                    + " and requiring known paths " + known.codePathString
7575                                    + " & " + known.resourcePathString);
7576                        }
7577                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
7578                                || !pkg.applicationInfo.getResourcePath().equals(
7579                                known.resourcePathString)) {
7580                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
7581                                    "Application package " + pkg.packageName
7582                                            + " found at " + pkg.applicationInfo.getCodePath()
7583                                            + " but expected at " + known.codePathString
7584                                            + "; ignoring.");
7585                        }
7586                    }
7587                }
7588            }
7589        }
7590
7591        // Initialize package source and resource directories
7592        File destCodeFile = new File(pkg.applicationInfo.getCodePath());
7593        File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
7594
7595        SharedUserSetting suid = null;
7596        PackageSetting pkgSetting = null;
7597
7598        if (!isSystemApp(pkg)) {
7599            // Only system apps can use these features.
7600            pkg.mOriginalPackages = null;
7601            pkg.mRealPackage = null;
7602            pkg.mAdoptPermissions = null;
7603        }
7604
7605        // Getting the package setting may have a side-effect, so if we
7606        // are only checking if scan would succeed, stash a copy of the
7607        // old setting to restore at the end.
7608        PackageSetting nonMutatedPs = null;
7609
7610        // writer
7611        synchronized (mPackages) {
7612            if (pkg.mSharedUserId != null) {
7613                suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true);
7614                if (suid == null) {
7615                    throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7616                            "Creating application package " + pkg.packageName
7617                            + " for shared user failed");
7618                }
7619                if (DEBUG_PACKAGE_SCANNING) {
7620                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
7621                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
7622                                + "): packages=" + suid.packages);
7623                }
7624            }
7625
7626            // Check if we are renaming from an original package name.
7627            PackageSetting origPackage = null;
7628            String realName = null;
7629            if (pkg.mOriginalPackages != null) {
7630                // This package may need to be renamed to a previously
7631                // installed name.  Let's check on that...
7632                final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
7633                if (pkg.mOriginalPackages.contains(renamed)) {
7634                    // This package had originally been installed as the
7635                    // original name, and we have already taken care of
7636                    // transitioning to the new one.  Just update the new
7637                    // one to continue using the old name.
7638                    realName = pkg.mRealPackage;
7639                    if (!pkg.packageName.equals(renamed)) {
7640                        // Callers into this function may have already taken
7641                        // care of renaming the package; only do it here if
7642                        // it is not already done.
7643                        pkg.setPackageName(renamed);
7644                    }
7645
7646                } else {
7647                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
7648                        if ((origPackage = mSettings.peekPackageLPr(
7649                                pkg.mOriginalPackages.get(i))) != null) {
7650                            // We do have the package already installed under its
7651                            // original name...  should we use it?
7652                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
7653                                // New package is not compatible with original.
7654                                origPackage = null;
7655                                continue;
7656                            } else if (origPackage.sharedUser != null) {
7657                                // Make sure uid is compatible between packages.
7658                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
7659                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
7660                                            + " to " + pkg.packageName + ": old uid "
7661                                            + origPackage.sharedUser.name
7662                                            + " differs from " + pkg.mSharedUserId);
7663                                    origPackage = null;
7664                                    continue;
7665                                }
7666                            } else {
7667                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
7668                                        + pkg.packageName + " to old name " + origPackage.name);
7669                            }
7670                            break;
7671                        }
7672                    }
7673                }
7674            }
7675
7676            if (mTransferedPackages.contains(pkg.packageName)) {
7677                Slog.w(TAG, "Package " + pkg.packageName
7678                        + " was transferred to another, but its .apk remains");
7679            }
7680
7681            // See comments in nonMutatedPs declaration
7682            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7683                PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
7684                if (foundPs != null) {
7685                    nonMutatedPs = new PackageSetting(foundPs);
7686                }
7687            }
7688
7689            // Just create the setting, don't add it yet. For already existing packages
7690            // the PkgSetting exists already and doesn't have to be created.
7691            pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
7692                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
7693                    pkg.applicationInfo.primaryCpuAbi,
7694                    pkg.applicationInfo.secondaryCpuAbi,
7695                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
7696                    user, false);
7697            if (pkgSetting == null) {
7698                throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
7699                        "Creating application package " + pkg.packageName + " failed");
7700            }
7701
7702            if (pkgSetting.origPackage != null) {
7703                // If we are first transitioning from an original package,
7704                // fix up the new package's name now.  We need to do this after
7705                // looking up the package under its new name, so getPackageLP
7706                // can take care of fiddling things correctly.
7707                pkg.setPackageName(origPackage.name);
7708
7709                // File a report about this.
7710                String msg = "New package " + pkgSetting.realName
7711                        + " renamed to replace old package " + pkgSetting.name;
7712                reportSettingsProblem(Log.WARN, msg);
7713
7714                // Make a note of it.
7715                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
7716                    mTransferedPackages.add(origPackage.name);
7717                }
7718
7719                // No longer need to retain this.
7720                pkgSetting.origPackage = null;
7721            }
7722
7723            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
7724                // Make a note of it.
7725                mTransferedPackages.add(pkg.packageName);
7726            }
7727
7728            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
7729                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
7730            }
7731
7732            if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7733                // Check all shared libraries and map to their actual file path.
7734                // We only do this here for apps not on a system dir, because those
7735                // are the only ones that can fail an install due to this.  We
7736                // will take care of the system apps by updating all of their
7737                // library paths after the scan is done.
7738                updateSharedLibrariesLPw(pkg, null);
7739            }
7740
7741            if (mFoundPolicyFile) {
7742                SELinuxMMAC.assignSeinfoValue(pkg);
7743            }
7744
7745            pkg.applicationInfo.uid = pkgSetting.appId;
7746            pkg.mExtras = pkgSetting;
7747            if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) {
7748                if (checkUpgradeKeySetLP(pkgSetting, pkg)) {
7749                    // We just determined the app is signed correctly, so bring
7750                    // over the latest parsed certs.
7751                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7752                } else {
7753                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7754                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
7755                                "Package " + pkg.packageName + " upgrade keys do not match the "
7756                                + "previously installed version");
7757                    } else {
7758                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
7759                        String msg = "System package " + pkg.packageName
7760                            + " signature changed; retaining data.";
7761                        reportSettingsProblem(Log.WARN, msg);
7762                    }
7763                }
7764            } else {
7765                try {
7766                    verifySignaturesLP(pkgSetting, pkg);
7767                    // We just determined the app is signed correctly, so bring
7768                    // over the latest parsed certs.
7769                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7770                } catch (PackageManagerException e) {
7771                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
7772                        throw e;
7773                    }
7774                    // The signature has changed, but this package is in the system
7775                    // image...  let's recover!
7776                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
7777                    // However...  if this package is part of a shared user, but it
7778                    // doesn't match the signature of the shared user, let's fail.
7779                    // What this means is that you can't change the signatures
7780                    // associated with an overall shared user, which doesn't seem all
7781                    // that unreasonable.
7782                    if (pkgSetting.sharedUser != null) {
7783                        if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
7784                                              pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
7785                            throw new PackageManagerException(
7786                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
7787                                            "Signature mismatch for shared user: "
7788                                            + pkgSetting.sharedUser);
7789                        }
7790                    }
7791                    // File a report about this.
7792                    String msg = "System package " + pkg.packageName
7793                        + " signature changed; retaining data.";
7794                    reportSettingsProblem(Log.WARN, msg);
7795                }
7796            }
7797            // Verify that this new package doesn't have any content providers
7798            // that conflict with existing packages.  Only do this if the
7799            // package isn't already installed, since we don't want to break
7800            // things that are installed.
7801            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
7802                final int N = pkg.providers.size();
7803                int i;
7804                for (i=0; i<N; i++) {
7805                    PackageParser.Provider p = pkg.providers.get(i);
7806                    if (p.info.authority != null) {
7807                        String names[] = p.info.authority.split(";");
7808                        for (int j = 0; j < names.length; j++) {
7809                            if (mProvidersByAuthority.containsKey(names[j])) {
7810                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
7811                                final String otherPackageName =
7812                                        ((other != null && other.getComponentName() != null) ?
7813                                                other.getComponentName().getPackageName() : "?");
7814                                throw new PackageManagerException(
7815                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
7816                                                "Can't install because provider name " + names[j]
7817                                                + " (in package " + pkg.applicationInfo.packageName
7818                                                + ") is already used by " + otherPackageName);
7819                            }
7820                        }
7821                    }
7822                }
7823            }
7824
7825            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
7826                // This package wants to adopt ownership of permissions from
7827                // another package.
7828                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
7829                    final String origName = pkg.mAdoptPermissions.get(i);
7830                    final PackageSetting orig = mSettings.peekPackageLPr(origName);
7831                    if (orig != null) {
7832                        if (verifyPackageUpdateLPr(orig, pkg)) {
7833                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
7834                                    + pkg.packageName);
7835                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
7836                        }
7837                    }
7838                }
7839            }
7840        }
7841
7842        final String pkgName = pkg.packageName;
7843
7844        final long scanFileTime = scanFile.lastModified();
7845        final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
7846        pkg.applicationInfo.processName = fixProcessName(
7847                pkg.applicationInfo.packageName,
7848                pkg.applicationInfo.processName,
7849                pkg.applicationInfo.uid);
7850
7851        if (pkg != mPlatformPackage) {
7852            // Get all of our default paths setup
7853            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
7854        }
7855
7856        final String path = scanFile.getPath();
7857        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
7858
7859        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
7860            derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */);
7861
7862            // Some system apps still use directory structure for native libraries
7863            // in which case we might end up not detecting abi solely based on apk
7864            // structure. Try to detect abi based on directory structure.
7865            if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
7866                    pkg.applicationInfo.primaryCpuAbi == null) {
7867                setBundledAppAbisAndRoots(pkg, pkgSetting);
7868                setNativeLibraryPaths(pkg);
7869            }
7870
7871        } else {
7872            if ((scanFlags & SCAN_MOVE) != 0) {
7873                // We haven't run dex-opt for this move (since we've moved the compiled output too)
7874                // but we already have this packages package info in the PackageSetting. We just
7875                // use that and derive the native library path based on the new codepath.
7876                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
7877                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
7878            }
7879
7880            // Set native library paths again. For moves, the path will be updated based on the
7881            // ABIs we've determined above. For non-moves, the path will be updated based on the
7882            // ABIs we determined during compilation, but the path will depend on the final
7883            // package path (after the rename away from the stage path).
7884            setNativeLibraryPaths(pkg);
7885        }
7886
7887        // This is a special case for the "system" package, where the ABI is
7888        // dictated by the zygote configuration (and init.rc). We should keep track
7889        // of this ABI so that we can deal with "normal" applications that run under
7890        // the same UID correctly.
7891        if (mPlatformPackage == pkg) {
7892            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
7893                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
7894        }
7895
7896        // If there's a mismatch between the abi-override in the package setting
7897        // and the abiOverride specified for the install. Warn about this because we
7898        // would've already compiled the app without taking the package setting into
7899        // account.
7900        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
7901            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
7902                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
7903                        " for package " + pkg.packageName);
7904            }
7905        }
7906
7907        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
7908        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
7909        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
7910
7911        // Copy the derived override back to the parsed package, so that we can
7912        // update the package settings accordingly.
7913        pkg.cpuAbiOverride = cpuAbiOverride;
7914
7915        if (DEBUG_ABI_SELECTION) {
7916            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
7917                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
7918                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
7919        }
7920
7921        // Push the derived path down into PackageSettings so we know what to
7922        // clean up at uninstall time.
7923        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
7924
7925        if (DEBUG_ABI_SELECTION) {
7926            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
7927                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
7928                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
7929        }
7930
7931        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
7932            // We don't do this here during boot because we can do it all
7933            // at once after scanning all existing packages.
7934            //
7935            // We also do this *before* we perform dexopt on this package, so that
7936            // we can avoid redundant dexopts, and also to make sure we've got the
7937            // code and package path correct.
7938            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
7939                    pkg, true /* boot complete */);
7940        }
7941
7942        if (mFactoryTest && pkg.requestedPermissions.contains(
7943                android.Manifest.permission.FACTORY_TEST)) {
7944            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
7945        }
7946
7947        ArrayList<PackageParser.Package> clientLibPkgs = null;
7948
7949        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
7950            if (nonMutatedPs != null) {
7951                synchronized (mPackages) {
7952                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
7953                }
7954            }
7955            return pkg;
7956        }
7957
7958        // Only privileged apps and updated privileged apps can add child packages.
7959        if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
7960            if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) {
7961                throw new PackageManagerException("Only privileged apps and updated "
7962                        + "privileged apps can add child packages. Ignoring package "
7963                        + pkg.packageName);
7964            }
7965            final int childCount = pkg.childPackages.size();
7966            for (int i = 0; i < childCount; i++) {
7967                PackageParser.Package childPkg = pkg.childPackages.get(i);
7968                if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
7969                        childPkg.packageName)) {
7970                    throw new PackageManagerException("Cannot override a child package of "
7971                            + "another disabled system app. Ignoring package " + pkg.packageName);
7972                }
7973            }
7974        }
7975
7976        // writer
7977        synchronized (mPackages) {
7978            if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7979                // Only system apps can add new shared libraries.
7980                if (pkg.libraryNames != null) {
7981                    for (int i=0; i<pkg.libraryNames.size(); i++) {
7982                        String name = pkg.libraryNames.get(i);
7983                        boolean allowed = false;
7984                        if (pkg.isUpdatedSystemApp()) {
7985                            // New library entries can only be added through the
7986                            // system image.  This is important to get rid of a lot
7987                            // of nasty edge cases: for example if we allowed a non-
7988                            // system update of the app to add a library, then uninstalling
7989                            // the update would make the library go away, and assumptions
7990                            // we made such as through app install filtering would now
7991                            // have allowed apps on the device which aren't compatible
7992                            // with it.  Better to just have the restriction here, be
7993                            // conservative, and create many fewer cases that can negatively
7994                            // impact the user experience.
7995                            final PackageSetting sysPs = mSettings
7996                                    .getDisabledSystemPkgLPr(pkg.packageName);
7997                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
7998                                for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
7999                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
8000                                        allowed = true;
8001                                        break;
8002                                    }
8003                                }
8004                            }
8005                        } else {
8006                            allowed = true;
8007                        }
8008                        if (allowed) {
8009                            if (!mSharedLibraries.containsKey(name)) {
8010                                mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
8011                            } else if (!name.equals(pkg.packageName)) {
8012                                Slog.w(TAG, "Package " + pkg.packageName + " library "
8013                                        + name + " already exists; skipping");
8014                            }
8015                        } else {
8016                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
8017                                    + name + " that is not declared on system image; skipping");
8018                        }
8019                    }
8020                    if ((scanFlags & SCAN_BOOTING) == 0) {
8021                        // If we are not booting, we need to update any applications
8022                        // that are clients of our shared library.  If we are booting,
8023                        // this will all be done once the scan is complete.
8024                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
8025                    }
8026                }
8027            }
8028        }
8029
8030        // Request the ActivityManager to kill the process(only for existing packages)
8031        // so that we do not end up in a confused state while the user is still using the older
8032        // version of the application while the new one gets installed.
8033        final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0;
8034        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
8035        if (killApp) {
8036            if (isReplacing) {
8037                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication");
8038
8039                killApplication(pkg.applicationInfo.packageName,
8040                            pkg.applicationInfo.uid, "replace pkg");
8041
8042                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8043            }
8044        }
8045
8046        // Also need to kill any apps that are dependent on the library.
8047        if (clientLibPkgs != null) {
8048            for (int i=0; i<clientLibPkgs.size(); i++) {
8049                PackageParser.Package clientPkg = clientLibPkgs.get(i);
8050                killApplication(clientPkg.applicationInfo.packageName,
8051                        clientPkg.applicationInfo.uid, "update lib");
8052            }
8053        }
8054
8055        // Make sure we're not adding any bogus keyset info
8056        KeySetManagerService ksms = mSettings.mKeySetManagerService;
8057        ksms.assertScannedPackageValid(pkg);
8058
8059        // writer
8060        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
8061
8062        boolean createIdmapFailed = false;
8063        synchronized (mPackages) {
8064            // We don't expect installation to fail beyond this point
8065
8066            // Add the new setting to mSettings
8067            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
8068            // Add the new setting to mPackages
8069            mPackages.put(pkg.applicationInfo.packageName, pkg);
8070            // Make sure we don't accidentally delete its data.
8071            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
8072            while (iter.hasNext()) {
8073                PackageCleanItem item = iter.next();
8074                if (pkgName.equals(item.packageName)) {
8075                    iter.remove();
8076                }
8077            }
8078
8079            // Take care of first install / last update times.
8080            if (currentTime != 0) {
8081                if (pkgSetting.firstInstallTime == 0) {
8082                    pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
8083                } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
8084                    pkgSetting.lastUpdateTime = currentTime;
8085                }
8086            } else if (pkgSetting.firstInstallTime == 0) {
8087                // We need *something*.  Take time time stamp of the file.
8088                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
8089            } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
8090                if (scanFileTime != pkgSetting.timeStamp) {
8091                    // A package on the system image has changed; consider this
8092                    // to be an update.
8093                    pkgSetting.lastUpdateTime = scanFileTime;
8094                }
8095            }
8096
8097            // Add the package's KeySets to the global KeySetManagerService
8098            ksms.addScannedPackageLPw(pkg);
8099
8100            int N = pkg.providers.size();
8101            StringBuilder r = null;
8102            int i;
8103            for (i=0; i<N; i++) {
8104                PackageParser.Provider p = pkg.providers.get(i);
8105                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
8106                        p.info.processName, pkg.applicationInfo.uid);
8107                mProviders.addProvider(p);
8108                p.syncable = p.info.isSyncable;
8109                if (p.info.authority != null) {
8110                    String names[] = p.info.authority.split(";");
8111                    p.info.authority = null;
8112                    for (int j = 0; j < names.length; j++) {
8113                        if (j == 1 && p.syncable) {
8114                            // We only want the first authority for a provider to possibly be
8115                            // syncable, so if we already added this provider using a different
8116                            // authority clear the syncable flag. We copy the provider before
8117                            // changing it because the mProviders object contains a reference
8118                            // to a provider that we don't want to change.
8119                            // Only do this for the second authority since the resulting provider
8120                            // object can be the same for all future authorities for this provider.
8121                            p = new PackageParser.Provider(p);
8122                            p.syncable = false;
8123                        }
8124                        if (!mProvidersByAuthority.containsKey(names[j])) {
8125                            mProvidersByAuthority.put(names[j], p);
8126                            if (p.info.authority == null) {
8127                                p.info.authority = names[j];
8128                            } else {
8129                                p.info.authority = p.info.authority + ";" + names[j];
8130                            }
8131                            if (DEBUG_PACKAGE_SCANNING) {
8132                                if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
8133                                    Log.d(TAG, "Registered content provider: " + names[j]
8134                                            + ", className = " + p.info.name + ", isSyncable = "
8135                                            + p.info.isSyncable);
8136                            }
8137                        } else {
8138                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
8139                            Slog.w(TAG, "Skipping provider name " + names[j] +
8140                                    " (in package " + pkg.applicationInfo.packageName +
8141                                    "): name already used by "
8142                                    + ((other != null && other.getComponentName() != null)
8143                                            ? other.getComponentName().getPackageName() : "?"));
8144                        }
8145                    }
8146                }
8147                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8148                    if (r == null) {
8149                        r = new StringBuilder(256);
8150                    } else {
8151                        r.append(' ');
8152                    }
8153                    r.append(p.info.name);
8154                }
8155            }
8156            if (r != null) {
8157                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
8158            }
8159
8160            N = pkg.services.size();
8161            r = null;
8162            for (i=0; i<N; i++) {
8163                PackageParser.Service s = pkg.services.get(i);
8164                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
8165                        s.info.processName, pkg.applicationInfo.uid);
8166                mServices.addService(s);
8167                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8168                    if (r == null) {
8169                        r = new StringBuilder(256);
8170                    } else {
8171                        r.append(' ');
8172                    }
8173                    r.append(s.info.name);
8174                }
8175            }
8176            if (r != null) {
8177                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
8178            }
8179
8180            N = pkg.receivers.size();
8181            r = null;
8182            for (i=0; i<N; i++) {
8183                PackageParser.Activity a = pkg.receivers.get(i);
8184                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8185                        a.info.processName, pkg.applicationInfo.uid);
8186                mReceivers.addActivity(a, "receiver");
8187                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8188                    if (r == null) {
8189                        r = new StringBuilder(256);
8190                    } else {
8191                        r.append(' ');
8192                    }
8193                    r.append(a.info.name);
8194                }
8195            }
8196            if (r != null) {
8197                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
8198            }
8199
8200            N = pkg.activities.size();
8201            r = null;
8202            for (i=0; i<N; i++) {
8203                PackageParser.Activity a = pkg.activities.get(i);
8204                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
8205                        a.info.processName, pkg.applicationInfo.uid);
8206                mActivities.addActivity(a, "activity");
8207                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8208                    if (r == null) {
8209                        r = new StringBuilder(256);
8210                    } else {
8211                        r.append(' ');
8212                    }
8213                    r.append(a.info.name);
8214                }
8215            }
8216            if (r != null) {
8217                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
8218            }
8219
8220            N = pkg.permissionGroups.size();
8221            r = null;
8222            for (i=0; i<N; i++) {
8223                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
8224                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
8225                if (cur == null) {
8226                    mPermissionGroups.put(pg.info.name, pg);
8227                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8228                        if (r == null) {
8229                            r = new StringBuilder(256);
8230                        } else {
8231                            r.append(' ');
8232                        }
8233                        r.append(pg.info.name);
8234                    }
8235                } else {
8236                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
8237                            + pg.info.packageName + " ignored: original from "
8238                            + cur.info.packageName);
8239                    if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8240                        if (r == null) {
8241                            r = new StringBuilder(256);
8242                        } else {
8243                            r.append(' ');
8244                        }
8245                        r.append("DUP:");
8246                        r.append(pg.info.name);
8247                    }
8248                }
8249            }
8250            if (r != null) {
8251                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
8252            }
8253
8254            N = pkg.permissions.size();
8255            r = null;
8256            for (i=0; i<N; i++) {
8257                PackageParser.Permission p = pkg.permissions.get(i);
8258
8259                // Assume by default that we did not install this permission into the system.
8260                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
8261
8262                // Now that permission groups have a special meaning, we ignore permission
8263                // groups for legacy apps to prevent unexpected behavior. In particular,
8264                // permissions for one app being granted to someone just becase they happen
8265                // to be in a group defined by another app (before this had no implications).
8266                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
8267                    p.group = mPermissionGroups.get(p.info.group);
8268                    // Warn for a permission in an unknown group.
8269                    if (p.info.group != null && p.group == null) {
8270                        Slog.w(TAG, "Permission " + p.info.name + " from package "
8271                                + p.info.packageName + " in an unknown group " + p.info.group);
8272                    }
8273                }
8274
8275                ArrayMap<String, BasePermission> permissionMap =
8276                        p.tree ? mSettings.mPermissionTrees
8277                                : mSettings.mPermissions;
8278                BasePermission bp = permissionMap.get(p.info.name);
8279
8280                // Allow system apps to redefine non-system permissions
8281                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
8282                    final boolean currentOwnerIsSystem = (bp.perm != null
8283                            && isSystemApp(bp.perm.owner));
8284                    if (isSystemApp(p.owner)) {
8285                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
8286                            // It's a built-in permission and no owner, take ownership now
8287                            bp.packageSetting = pkgSetting;
8288                            bp.perm = p;
8289                            bp.uid = pkg.applicationInfo.uid;
8290                            bp.sourcePackage = p.info.packageName;
8291                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8292                        } else if (!currentOwnerIsSystem) {
8293                            String msg = "New decl " + p.owner + " of permission  "
8294                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
8295                            reportSettingsProblem(Log.WARN, msg);
8296                            bp = null;
8297                        }
8298                    }
8299                }
8300
8301                if (bp == null) {
8302                    bp = new BasePermission(p.info.name, p.info.packageName,
8303                            BasePermission.TYPE_NORMAL);
8304                    permissionMap.put(p.info.name, bp);
8305                }
8306
8307                if (bp.perm == null) {
8308                    if (bp.sourcePackage == null
8309                            || bp.sourcePackage.equals(p.info.packageName)) {
8310                        BasePermission tree = findPermissionTreeLP(p.info.name);
8311                        if (tree == null
8312                                || tree.sourcePackage.equals(p.info.packageName)) {
8313                            bp.packageSetting = pkgSetting;
8314                            bp.perm = p;
8315                            bp.uid = pkg.applicationInfo.uid;
8316                            bp.sourcePackage = p.info.packageName;
8317                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
8318                            if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8319                                if (r == null) {
8320                                    r = new StringBuilder(256);
8321                                } else {
8322                                    r.append(' ');
8323                                }
8324                                r.append(p.info.name);
8325                            }
8326                        } else {
8327                            Slog.w(TAG, "Permission " + p.info.name + " from package "
8328                                    + p.info.packageName + " ignored: base tree "
8329                                    + tree.name + " is from package "
8330                                    + tree.sourcePackage);
8331                        }
8332                    } else {
8333                        Slog.w(TAG, "Permission " + p.info.name + " from package "
8334                                + p.info.packageName + " ignored: original from "
8335                                + bp.sourcePackage);
8336                    }
8337                } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8338                    if (r == null) {
8339                        r = new StringBuilder(256);
8340                    } else {
8341                        r.append(' ');
8342                    }
8343                    r.append("DUP:");
8344                    r.append(p.info.name);
8345                }
8346                if (bp.perm == p) {
8347                    bp.protectionLevel = p.info.protectionLevel;
8348                }
8349            }
8350
8351            if (r != null) {
8352                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
8353            }
8354
8355            N = pkg.instrumentation.size();
8356            r = null;
8357            for (i=0; i<N; i++) {
8358                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
8359                a.info.packageName = pkg.applicationInfo.packageName;
8360                a.info.sourceDir = pkg.applicationInfo.sourceDir;
8361                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
8362                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
8363                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
8364                a.info.dataDir = pkg.applicationInfo.dataDir;
8365                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
8366                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
8367
8368                // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
8369                // need other information about the application, like the ABI and what not ?
8370                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
8371                mInstrumentation.put(a.getComponentName(), a);
8372                if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
8373                    if (r == null) {
8374                        r = new StringBuilder(256);
8375                    } else {
8376                        r.append(' ');
8377                    }
8378                    r.append(a.info.name);
8379                }
8380            }
8381            if (r != null) {
8382                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
8383            }
8384
8385            if (pkg.protectedBroadcasts != null) {
8386                N = pkg.protectedBroadcasts.size();
8387                for (i=0; i<N; i++) {
8388                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
8389                }
8390            }
8391
8392            pkgSetting.setTimeStamp(scanFileTime);
8393
8394            // Create idmap files for pairs of (packages, overlay packages).
8395            // Note: "android", ie framework-res.apk, is handled by native layers.
8396            if (pkg.mOverlayTarget != null) {
8397                // This is an overlay package.
8398                if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
8399                    if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
8400                        mOverlays.put(pkg.mOverlayTarget,
8401                                new ArrayMap<String, PackageParser.Package>());
8402                    }
8403                    ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
8404                    map.put(pkg.packageName, pkg);
8405                    PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
8406                    if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
8407                        createIdmapFailed = true;
8408                    }
8409                }
8410            } else if (mOverlays.containsKey(pkg.packageName) &&
8411                    !pkg.packageName.equals("android")) {
8412                // This is a regular package, with one or more known overlay packages.
8413                createIdmapsForPackageLI(pkg);
8414            }
8415        }
8416
8417        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8418
8419        if (createIdmapFailed) {
8420            throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
8421                    "scanPackageLI failed to createIdmap");
8422        }
8423        return pkg;
8424    }
8425
8426    /**
8427     * Derive the ABI of a non-system package located at {@code scanFile}. This information
8428     * is derived purely on the basis of the contents of {@code scanFile} and
8429     * {@code cpuAbiOverride}.
8430     *
8431     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
8432     */
8433    private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
8434                                 String cpuAbiOverride, boolean extractLibs)
8435            throws PackageManagerException {
8436        // TODO: We can probably be smarter about this stuff. For installed apps,
8437        // we can calculate this information at install time once and for all. For
8438        // system apps, we can probably assume that this information doesn't change
8439        // after the first boot scan. As things stand, we do lots of unnecessary work.
8440
8441        // Give ourselves some initial paths; we'll come back for another
8442        // pass once we've determined ABI below.
8443        setNativeLibraryPaths(pkg);
8444
8445        // We would never need to extract libs for forward-locked and external packages,
8446        // since the container service will do it for us. We shouldn't attempt to
8447        // extract libs from system app when it was not updated.
8448        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
8449                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
8450            extractLibs = false;
8451        }
8452
8453        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
8454        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
8455
8456        NativeLibraryHelper.Handle handle = null;
8457        try {
8458            handle = NativeLibraryHelper.Handle.create(pkg);
8459            // TODO(multiArch): This can be null for apps that didn't go through the
8460            // usual installation process. We can calculate it again, like we
8461            // do during install time.
8462            //
8463            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
8464            // unnecessary.
8465            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
8466
8467            // Null out the abis so that they can be recalculated.
8468            pkg.applicationInfo.primaryCpuAbi = null;
8469            pkg.applicationInfo.secondaryCpuAbi = null;
8470            if (isMultiArch(pkg.applicationInfo)) {
8471                // Warn if we've set an abiOverride for multi-lib packages..
8472                // By definition, we need to copy both 32 and 64 bit libraries for
8473                // such packages.
8474                if (pkg.cpuAbiOverride != null
8475                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
8476                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
8477                }
8478
8479                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
8480                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
8481                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
8482                    if (extractLibs) {
8483                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8484                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
8485                                useIsaSpecificSubdirs);
8486                    } else {
8487                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
8488                    }
8489                }
8490
8491                maybeThrowExceptionForMultiArchCopy(
8492                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
8493
8494                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
8495                    if (extractLibs) {
8496                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8497                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
8498                                useIsaSpecificSubdirs);
8499                    } else {
8500                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
8501                    }
8502                }
8503
8504                maybeThrowExceptionForMultiArchCopy(
8505                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
8506
8507                if (abi64 >= 0) {
8508                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
8509                }
8510
8511                if (abi32 >= 0) {
8512                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
8513                    if (abi64 >= 0) {
8514                        if (cpuAbiOverride == null && pkg.use32bitAbi) {
8515                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
8516                            pkg.applicationInfo.primaryCpuAbi = abi;
8517                        } else {
8518                            pkg.applicationInfo.secondaryCpuAbi = abi;
8519                        }
8520                    } else {
8521                        pkg.applicationInfo.primaryCpuAbi = abi;
8522                    }
8523                }
8524
8525            } else {
8526                String[] abiList = (cpuAbiOverride != null) ?
8527                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
8528
8529                // Enable gross and lame hacks for apps that are built with old
8530                // SDK tools. We must scan their APKs for renderscript bitcode and
8531                // not launch them if it's present. Don't bother checking on devices
8532                // that don't have 64 bit support.
8533                boolean needsRenderScriptOverride = false;
8534                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
8535                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
8536                    abiList = Build.SUPPORTED_32_BIT_ABIS;
8537                    needsRenderScriptOverride = true;
8538                }
8539
8540                final int copyRet;
8541                if (extractLibs) {
8542                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
8543                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
8544                } else {
8545                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
8546                }
8547
8548                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
8549                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
8550                            "Error unpackaging native libs for app, errorCode=" + copyRet);
8551                }
8552
8553                if (copyRet >= 0) {
8554                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
8555                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
8556                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
8557                } else if (needsRenderScriptOverride) {
8558                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
8559                }
8560            }
8561        } catch (IOException ioe) {
8562            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
8563        } finally {
8564            IoUtils.closeQuietly(handle);
8565        }
8566
8567        // Now that we've calculated the ABIs and determined if it's an internal app,
8568        // we will go ahead and populate the nativeLibraryPath.
8569        setNativeLibraryPaths(pkg);
8570    }
8571
8572    /**
8573     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
8574     * i.e, so that all packages can be run inside a single process if required.
8575     *
8576     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
8577     * this function will either try and make the ABI for all packages in {@code packagesForUser}
8578     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
8579     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
8580     * updating a package that belongs to a shared user.
8581     *
8582     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
8583     * adds unnecessary complexity.
8584     */
8585    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
8586            PackageParser.Package scannedPackage, boolean bootComplete) {
8587        String requiredInstructionSet = null;
8588        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
8589            requiredInstructionSet = VMRuntime.getInstructionSet(
8590                     scannedPackage.applicationInfo.primaryCpuAbi);
8591        }
8592
8593        PackageSetting requirer = null;
8594        for (PackageSetting ps : packagesForUser) {
8595            // If packagesForUser contains scannedPackage, we skip it. This will happen
8596            // when scannedPackage is an update of an existing package. Without this check,
8597            // we will never be able to change the ABI of any package belonging to a shared
8598            // user, even if it's compatible with other packages.
8599            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8600                if (ps.primaryCpuAbiString == null) {
8601                    continue;
8602                }
8603
8604                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
8605                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
8606                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
8607                    // this but there's not much we can do.
8608                    String errorMessage = "Instruction set mismatch, "
8609                            + ((requirer == null) ? "[caller]" : requirer)
8610                            + " requires " + requiredInstructionSet + " whereas " + ps
8611                            + " requires " + instructionSet;
8612                    Slog.w(TAG, errorMessage);
8613                }
8614
8615                if (requiredInstructionSet == null) {
8616                    requiredInstructionSet = instructionSet;
8617                    requirer = ps;
8618                }
8619            }
8620        }
8621
8622        if (requiredInstructionSet != null) {
8623            String adjustedAbi;
8624            if (requirer != null) {
8625                // requirer != null implies that either scannedPackage was null or that scannedPackage
8626                // did not require an ABI, in which case we have to adjust scannedPackage to match
8627                // the ABI of the set (which is the same as requirer's ABI)
8628                adjustedAbi = requirer.primaryCpuAbiString;
8629                if (scannedPackage != null) {
8630                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
8631                }
8632            } else {
8633                // requirer == null implies that we're updating all ABIs in the set to
8634                // match scannedPackage.
8635                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
8636            }
8637
8638            for (PackageSetting ps : packagesForUser) {
8639                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
8640                    if (ps.primaryCpuAbiString != null) {
8641                        continue;
8642                    }
8643
8644                    ps.primaryCpuAbiString = adjustedAbi;
8645                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
8646                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
8647                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
8648                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
8649                                + " (requirer="
8650                                + (requirer == null ? "null" : requirer.pkg.packageName)
8651                                + ", scannedPackage="
8652                                + (scannedPackage != null ? scannedPackage.packageName : "null")
8653                                + ")");
8654                        try {
8655                            mInstaller.rmdex(ps.codePathString,
8656                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
8657                        } catch (InstallerException ignored) {
8658                        }
8659                    }
8660                }
8661            }
8662        }
8663    }
8664
8665    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
8666        synchronized (mPackages) {
8667            mResolverReplaced = true;
8668            // Set up information for custom user intent resolution activity.
8669            mResolveActivity.applicationInfo = pkg.applicationInfo;
8670            mResolveActivity.name = mCustomResolverComponentName.getClassName();
8671            mResolveActivity.packageName = pkg.applicationInfo.packageName;
8672            mResolveActivity.processName = pkg.applicationInfo.packageName;
8673            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8674            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8675                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8676            mResolveActivity.theme = 0;
8677            mResolveActivity.exported = true;
8678            mResolveActivity.enabled = true;
8679            mResolveInfo.activityInfo = mResolveActivity;
8680            mResolveInfo.priority = 0;
8681            mResolveInfo.preferredOrder = 0;
8682            mResolveInfo.match = 0;
8683            mResolveComponentName = mCustomResolverComponentName;
8684            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
8685                    mResolveComponentName);
8686        }
8687    }
8688
8689    private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) {
8690        final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName());
8691
8692        // Set up information for ephemeral installer activity
8693        mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo;
8694        mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName();
8695        mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName;
8696        mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName;
8697        mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
8698        mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
8699                ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
8700        mEphemeralInstallerActivity.theme = 0;
8701        mEphemeralInstallerActivity.exported = true;
8702        mEphemeralInstallerActivity.enabled = true;
8703        mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity;
8704        mEphemeralInstallerInfo.priority = 0;
8705        mEphemeralInstallerInfo.preferredOrder = 0;
8706        mEphemeralInstallerInfo.match = 0;
8707
8708        if (DEBUG_EPHEMERAL) {
8709            Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent);
8710        }
8711    }
8712
8713    private static String calculateBundledApkRoot(final String codePathString) {
8714        final File codePath = new File(codePathString);
8715        final File codeRoot;
8716        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
8717            codeRoot = Environment.getRootDirectory();
8718        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
8719            codeRoot = Environment.getOemDirectory();
8720        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
8721            codeRoot = Environment.getVendorDirectory();
8722        } else {
8723            // Unrecognized code path; take its top real segment as the apk root:
8724            // e.g. /something/app/blah.apk => /something
8725            try {
8726                File f = codePath.getCanonicalFile();
8727                File parent = f.getParentFile();    // non-null because codePath is a file
8728                File tmp;
8729                while ((tmp = parent.getParentFile()) != null) {
8730                    f = parent;
8731                    parent = tmp;
8732                }
8733                codeRoot = f;
8734                Slog.w(TAG, "Unrecognized code path "
8735                        + codePath + " - using " + codeRoot);
8736            } catch (IOException e) {
8737                // Can't canonicalize the code path -- shenanigans?
8738                Slog.w(TAG, "Can't canonicalize code path " + codePath);
8739                return Environment.getRootDirectory().getPath();
8740            }
8741        }
8742        return codeRoot.getPath();
8743    }
8744
8745    /**
8746     * Derive and set the location of native libraries for the given package,
8747     * which varies depending on where and how the package was installed.
8748     */
8749    private void setNativeLibraryPaths(PackageParser.Package pkg) {
8750        final ApplicationInfo info = pkg.applicationInfo;
8751        final String codePath = pkg.codePath;
8752        final File codeFile = new File(codePath);
8753        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
8754        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
8755
8756        info.nativeLibraryRootDir = null;
8757        info.nativeLibraryRootRequiresIsa = false;
8758        info.nativeLibraryDir = null;
8759        info.secondaryNativeLibraryDir = null;
8760
8761        if (isApkFile(codeFile)) {
8762            // Monolithic install
8763            if (bundledApp) {
8764                // If "/system/lib64/apkname" exists, assume that is the per-package
8765                // native library directory to use; otherwise use "/system/lib/apkname".
8766                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
8767                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
8768                        getPrimaryInstructionSet(info));
8769
8770                // This is a bundled system app so choose the path based on the ABI.
8771                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
8772                // is just the default path.
8773                final String apkName = deriveCodePathName(codePath);
8774                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
8775                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
8776                        apkName).getAbsolutePath();
8777
8778                if (info.secondaryCpuAbi != null) {
8779                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
8780                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
8781                            secondaryLibDir, apkName).getAbsolutePath();
8782                }
8783            } else if (asecApp) {
8784                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
8785                        .getAbsolutePath();
8786            } else {
8787                final String apkName = deriveCodePathName(codePath);
8788                info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
8789                        .getAbsolutePath();
8790            }
8791
8792            info.nativeLibraryRootRequiresIsa = false;
8793            info.nativeLibraryDir = info.nativeLibraryRootDir;
8794        } else {
8795            // Cluster install
8796            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
8797            info.nativeLibraryRootRequiresIsa = true;
8798
8799            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
8800                    getPrimaryInstructionSet(info)).getAbsolutePath();
8801
8802            if (info.secondaryCpuAbi != null) {
8803                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
8804                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
8805            }
8806        }
8807    }
8808
8809    /**
8810     * Calculate the abis and roots for a bundled app. These can uniquely
8811     * be determined from the contents of the system partition, i.e whether
8812     * it contains 64 or 32 bit shared libraries etc. We do not validate any
8813     * of this information, and instead assume that the system was built
8814     * sensibly.
8815     */
8816    private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
8817                                           PackageSetting pkgSetting) {
8818        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
8819
8820        // If "/system/lib64/apkname" exists, assume that is the per-package
8821        // native library directory to use; otherwise use "/system/lib/apkname".
8822        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
8823        setBundledAppAbi(pkg, apkRoot, apkName);
8824        // pkgSetting might be null during rescan following uninstall of updates
8825        // to a bundled app, so accommodate that possibility.  The settings in
8826        // that case will be established later from the parsed package.
8827        //
8828        // If the settings aren't null, sync them up with what we've just derived.
8829        // note that apkRoot isn't stored in the package settings.
8830        if (pkgSetting != null) {
8831            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
8832            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
8833        }
8834    }
8835
8836    /**
8837     * Deduces the ABI of a bundled app and sets the relevant fields on the
8838     * parsed pkg object.
8839     *
8840     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
8841     *        under which system libraries are installed.
8842     * @param apkName the name of the installed package.
8843     */
8844    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
8845        final File codeFile = new File(pkg.codePath);
8846
8847        final boolean has64BitLibs;
8848        final boolean has32BitLibs;
8849        if (isApkFile(codeFile)) {
8850            // Monolithic install
8851            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
8852            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
8853        } else {
8854            // Cluster install
8855            final File rootDir = new File(codeFile, LIB_DIR_NAME);
8856            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
8857                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
8858                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
8859                has64BitLibs = (new File(rootDir, isa)).exists();
8860            } else {
8861                has64BitLibs = false;
8862            }
8863            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
8864                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
8865                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
8866                has32BitLibs = (new File(rootDir, isa)).exists();
8867            } else {
8868                has32BitLibs = false;
8869            }
8870        }
8871
8872        if (has64BitLibs && !has32BitLibs) {
8873            // The package has 64 bit libs, but not 32 bit libs. Its primary
8874            // ABI should be 64 bit. We can safely assume here that the bundled
8875            // native libraries correspond to the most preferred ABI in the list.
8876
8877            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8878            pkg.applicationInfo.secondaryCpuAbi = null;
8879        } else if (has32BitLibs && !has64BitLibs) {
8880            // The package has 32 bit libs but not 64 bit libs. Its primary
8881            // ABI should be 32 bit.
8882
8883            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8884            pkg.applicationInfo.secondaryCpuAbi = null;
8885        } else if (has32BitLibs && has64BitLibs) {
8886            // The application has both 64 and 32 bit bundled libraries. We check
8887            // here that the app declares multiArch support, and warn if it doesn't.
8888            //
8889            // We will be lenient here and record both ABIs. The primary will be the
8890            // ABI that's higher on the list, i.e, a device that's configured to prefer
8891            // 64 bit apps will see a 64 bit primary ABI,
8892
8893            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
8894                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
8895            }
8896
8897            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
8898                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8899                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8900            } else {
8901                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
8902                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
8903            }
8904        } else {
8905            pkg.applicationInfo.primaryCpuAbi = null;
8906            pkg.applicationInfo.secondaryCpuAbi = null;
8907        }
8908    }
8909
8910    private void killPackage(PackageParser.Package pkg, String reason) {
8911        // Kill the parent package
8912        killApplication(pkg.packageName, pkg.applicationInfo.uid, reason);
8913        // Kill the child packages
8914        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8915        for (int i = 0; i < childCount; i++) {
8916            PackageParser.Package childPkg = pkg.childPackages.get(i);
8917            killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason);
8918        }
8919    }
8920
8921    private void killApplication(String pkgName, int appId, String reason) {
8922        // Request the ActivityManager to kill the process(only for existing packages)
8923        // so that we do not end up in a confused state while the user is still using the older
8924        // version of the application while the new one gets installed.
8925        IActivityManager am = ActivityManagerNative.getDefault();
8926        if (am != null) {
8927            try {
8928                am.killApplicationWithAppId(pkgName, appId, reason);
8929            } catch (RemoteException e) {
8930            }
8931        }
8932    }
8933
8934    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
8935        // Remove the parent package setting
8936        PackageSetting ps = (PackageSetting) pkg.mExtras;
8937        if (ps != null) {
8938            removePackageLI(ps, chatty);
8939        }
8940        // Remove the child package setting
8941        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8942        for (int i = 0; i < childCount; i++) {
8943            PackageParser.Package childPkg = pkg.childPackages.get(i);
8944            ps = (PackageSetting) childPkg.mExtras;
8945            if (ps != null) {
8946                removePackageLI(ps, chatty);
8947            }
8948        }
8949    }
8950
8951    void removePackageLI(PackageSetting ps, boolean chatty) {
8952        if (DEBUG_INSTALL) {
8953            if (chatty)
8954                Log.d(TAG, "Removing package " + ps.name);
8955        }
8956
8957        // writer
8958        synchronized (mPackages) {
8959            mPackages.remove(ps.name);
8960            final PackageParser.Package pkg = ps.pkg;
8961            if (pkg != null) {
8962                cleanPackageDataStructuresLILPw(pkg, chatty);
8963            }
8964        }
8965    }
8966
8967    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
8968        if (DEBUG_INSTALL) {
8969            if (chatty)
8970                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
8971        }
8972
8973        // writer
8974        synchronized (mPackages) {
8975            // Remove the parent package
8976            mPackages.remove(pkg.applicationInfo.packageName);
8977            cleanPackageDataStructuresLILPw(pkg, chatty);
8978
8979            // Remove the child packages
8980            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8981            for (int i = 0; i < childCount; i++) {
8982                PackageParser.Package childPkg = pkg.childPackages.get(i);
8983                mPackages.remove(childPkg.applicationInfo.packageName);
8984                cleanPackageDataStructuresLILPw(childPkg, chatty);
8985            }
8986        }
8987    }
8988
8989    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
8990        int N = pkg.providers.size();
8991        StringBuilder r = null;
8992        int i;
8993        for (i=0; i<N; i++) {
8994            PackageParser.Provider p = pkg.providers.get(i);
8995            mProviders.removeProvider(p);
8996            if (p.info.authority == null) {
8997
8998                /* There was another ContentProvider with this authority when
8999                 * this app was installed so this authority is null,
9000                 * Ignore it as we don't have to unregister the provider.
9001                 */
9002                continue;
9003            }
9004            String names[] = p.info.authority.split(";");
9005            for (int j = 0; j < names.length; j++) {
9006                if (mProvidersByAuthority.get(names[j]) == p) {
9007                    mProvidersByAuthority.remove(names[j]);
9008                    if (DEBUG_REMOVE) {
9009                        if (chatty)
9010                            Log.d(TAG, "Unregistered content provider: " + names[j]
9011                                    + ", className = " + p.info.name + ", isSyncable = "
9012                                    + p.info.isSyncable);
9013                    }
9014                }
9015            }
9016            if (DEBUG_REMOVE && chatty) {
9017                if (r == null) {
9018                    r = new StringBuilder(256);
9019                } else {
9020                    r.append(' ');
9021                }
9022                r.append(p.info.name);
9023            }
9024        }
9025        if (r != null) {
9026            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
9027        }
9028
9029        N = pkg.services.size();
9030        r = null;
9031        for (i=0; i<N; i++) {
9032            PackageParser.Service s = pkg.services.get(i);
9033            mServices.removeService(s);
9034            if (chatty) {
9035                if (r == null) {
9036                    r = new StringBuilder(256);
9037                } else {
9038                    r.append(' ');
9039                }
9040                r.append(s.info.name);
9041            }
9042        }
9043        if (r != null) {
9044            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
9045        }
9046
9047        N = pkg.receivers.size();
9048        r = null;
9049        for (i=0; i<N; i++) {
9050            PackageParser.Activity a = pkg.receivers.get(i);
9051            mReceivers.removeActivity(a, "receiver");
9052            if (DEBUG_REMOVE && chatty) {
9053                if (r == null) {
9054                    r = new StringBuilder(256);
9055                } else {
9056                    r.append(' ');
9057                }
9058                r.append(a.info.name);
9059            }
9060        }
9061        if (r != null) {
9062            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
9063        }
9064
9065        N = pkg.activities.size();
9066        r = null;
9067        for (i=0; i<N; i++) {
9068            PackageParser.Activity a = pkg.activities.get(i);
9069            mActivities.removeActivity(a, "activity");
9070            if (DEBUG_REMOVE && chatty) {
9071                if (r == null) {
9072                    r = new StringBuilder(256);
9073                } else {
9074                    r.append(' ');
9075                }
9076                r.append(a.info.name);
9077            }
9078        }
9079        if (r != null) {
9080            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
9081        }
9082
9083        N = pkg.permissions.size();
9084        r = null;
9085        for (i=0; i<N; i++) {
9086            PackageParser.Permission p = pkg.permissions.get(i);
9087            BasePermission bp = mSettings.mPermissions.get(p.info.name);
9088            if (bp == null) {
9089                bp = mSettings.mPermissionTrees.get(p.info.name);
9090            }
9091            if (bp != null && bp.perm == p) {
9092                bp.perm = null;
9093                if (DEBUG_REMOVE && chatty) {
9094                    if (r == null) {
9095                        r = new StringBuilder(256);
9096                    } else {
9097                        r.append(' ');
9098                    }
9099                    r.append(p.info.name);
9100                }
9101            }
9102            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9103                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
9104                if (appOpPkgs != null) {
9105                    appOpPkgs.remove(pkg.packageName);
9106                }
9107            }
9108        }
9109        if (r != null) {
9110            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9111        }
9112
9113        N = pkg.requestedPermissions.size();
9114        r = null;
9115        for (i=0; i<N; i++) {
9116            String perm = pkg.requestedPermissions.get(i);
9117            BasePermission bp = mSettings.mPermissions.get(perm);
9118            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9119                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
9120                if (appOpPkgs != null) {
9121                    appOpPkgs.remove(pkg.packageName);
9122                    if (appOpPkgs.isEmpty()) {
9123                        mAppOpPermissionPackages.remove(perm);
9124                    }
9125                }
9126            }
9127        }
9128        if (r != null) {
9129            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
9130        }
9131
9132        N = pkg.instrumentation.size();
9133        r = null;
9134        for (i=0; i<N; i++) {
9135            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
9136            mInstrumentation.remove(a.getComponentName());
9137            if (DEBUG_REMOVE && chatty) {
9138                if (r == null) {
9139                    r = new StringBuilder(256);
9140                } else {
9141                    r.append(' ');
9142                }
9143                r.append(a.info.name);
9144            }
9145        }
9146        if (r != null) {
9147            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
9148        }
9149
9150        r = null;
9151        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9152            // Only system apps can hold shared libraries.
9153            if (pkg.libraryNames != null) {
9154                for (i=0; i<pkg.libraryNames.size(); i++) {
9155                    String name = pkg.libraryNames.get(i);
9156                    SharedLibraryEntry cur = mSharedLibraries.get(name);
9157                    if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
9158                        mSharedLibraries.remove(name);
9159                        if (DEBUG_REMOVE && chatty) {
9160                            if (r == null) {
9161                                r = new StringBuilder(256);
9162                            } else {
9163                                r.append(' ');
9164                            }
9165                            r.append(name);
9166                        }
9167                    }
9168                }
9169            }
9170        }
9171        if (r != null) {
9172            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
9173        }
9174    }
9175
9176    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
9177        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
9178            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
9179                return true;
9180            }
9181        }
9182        return false;
9183    }
9184
9185    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
9186    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
9187    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
9188
9189    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
9190        // Update the parent permissions
9191        updatePermissionsLPw(pkg.packageName, pkg, flags);
9192        // Update the child permissions
9193        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9194        for (int i = 0; i < childCount; i++) {
9195            PackageParser.Package childPkg = pkg.childPackages.get(i);
9196            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
9197        }
9198    }
9199
9200    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
9201            int flags) {
9202        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
9203        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
9204    }
9205
9206    private void updatePermissionsLPw(String changingPkg,
9207            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
9208        // Make sure there are no dangling permission trees.
9209        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
9210        while (it.hasNext()) {
9211            final BasePermission bp = it.next();
9212            if (bp.packageSetting == null) {
9213                // We may not yet have parsed the package, so just see if
9214                // we still know about its settings.
9215                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9216            }
9217            if (bp.packageSetting == null) {
9218                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
9219                        + " from package " + bp.sourcePackage);
9220                it.remove();
9221            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9222                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9223                    Slog.i(TAG, "Removing old permission tree: " + bp.name
9224                            + " from package " + bp.sourcePackage);
9225                    flags |= UPDATE_PERMISSIONS_ALL;
9226                    it.remove();
9227                }
9228            }
9229        }
9230
9231        // Make sure all dynamic permissions have been assigned to a package,
9232        // and make sure there are no dangling permissions.
9233        it = mSettings.mPermissions.values().iterator();
9234        while (it.hasNext()) {
9235            final BasePermission bp = it.next();
9236            if (bp.type == BasePermission.TYPE_DYNAMIC) {
9237                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
9238                        + bp.name + " pkg=" + bp.sourcePackage
9239                        + " info=" + bp.pendingInfo);
9240                if (bp.packageSetting == null && bp.pendingInfo != null) {
9241                    final BasePermission tree = findPermissionTreeLP(bp.name);
9242                    if (tree != null && tree.perm != null) {
9243                        bp.packageSetting = tree.packageSetting;
9244                        bp.perm = new PackageParser.Permission(tree.perm.owner,
9245                                new PermissionInfo(bp.pendingInfo));
9246                        bp.perm.info.packageName = tree.perm.info.packageName;
9247                        bp.perm.info.name = bp.name;
9248                        bp.uid = tree.uid;
9249                    }
9250                }
9251            }
9252            if (bp.packageSetting == null) {
9253                // We may not yet have parsed the package, so just see if
9254                // we still know about its settings.
9255                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
9256            }
9257            if (bp.packageSetting == null) {
9258                Slog.w(TAG, "Removing dangling permission: " + bp.name
9259                        + " from package " + bp.sourcePackage);
9260                it.remove();
9261            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
9262                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
9263                    Slog.i(TAG, "Removing old permission: " + bp.name
9264                            + " from package " + bp.sourcePackage);
9265                    flags |= UPDATE_PERMISSIONS_ALL;
9266                    it.remove();
9267                }
9268            }
9269        }
9270
9271        // Now update the permissions for all packages, in particular
9272        // replace the granted permissions of the system packages.
9273        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
9274            for (PackageParser.Package pkg : mPackages.values()) {
9275                if (pkg != pkgInfo) {
9276                    // Only replace for packages on requested volume
9277                    final String volumeUuid = getVolumeUuidForPackage(pkg);
9278                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
9279                            && Objects.equals(replaceVolumeUuid, volumeUuid);
9280                    grantPermissionsLPw(pkg, replace, changingPkg);
9281                }
9282            }
9283        }
9284
9285        if (pkgInfo != null) {
9286            // Only replace for packages on requested volume
9287            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
9288            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
9289                    && Objects.equals(replaceVolumeUuid, volumeUuid);
9290            grantPermissionsLPw(pkgInfo, replace, changingPkg);
9291        }
9292    }
9293
9294    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
9295            String packageOfInterest) {
9296        // IMPORTANT: There are two types of permissions: install and runtime.
9297        // Install time permissions are granted when the app is installed to
9298        // all device users and users added in the future. Runtime permissions
9299        // are granted at runtime explicitly to specific users. Normal and signature
9300        // protected permissions are install time permissions. Dangerous permissions
9301        // are install permissions if the app's target SDK is Lollipop MR1 or older,
9302        // otherwise they are runtime permissions. This function does not manage
9303        // runtime permissions except for the case an app targeting Lollipop MR1
9304        // being upgraded to target a newer SDK, in which case dangerous permissions
9305        // are transformed from install time to runtime ones.
9306
9307        final PackageSetting ps = (PackageSetting) pkg.mExtras;
9308        if (ps == null) {
9309            return;
9310        }
9311
9312        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
9313
9314        PermissionsState permissionsState = ps.getPermissionsState();
9315        PermissionsState origPermissions = permissionsState;
9316
9317        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
9318
9319        boolean runtimePermissionsRevoked = false;
9320        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
9321
9322        boolean changedInstallPermission = false;
9323
9324        if (replace) {
9325            ps.installPermissionsFixed = false;
9326            if (!ps.isSharedUser()) {
9327                origPermissions = new PermissionsState(permissionsState);
9328                permissionsState.reset();
9329            } else {
9330                // We need to know only about runtime permission changes since the
9331                // calling code always writes the install permissions state but
9332                // the runtime ones are written only if changed. The only cases of
9333                // changed runtime permissions here are promotion of an install to
9334                // runtime and revocation of a runtime from a shared user.
9335                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
9336                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
9337                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
9338                    runtimePermissionsRevoked = true;
9339                }
9340            }
9341        }
9342
9343        permissionsState.setGlobalGids(mGlobalGids);
9344
9345        final int N = pkg.requestedPermissions.size();
9346        for (int i=0; i<N; i++) {
9347            final String name = pkg.requestedPermissions.get(i);
9348            final BasePermission bp = mSettings.mPermissions.get(name);
9349
9350            if (DEBUG_INSTALL) {
9351                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
9352            }
9353
9354            if (bp == null || bp.packageSetting == null) {
9355                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
9356                    Slog.w(TAG, "Unknown permission " + name
9357                            + " in package " + pkg.packageName);
9358                }
9359                continue;
9360            }
9361
9362            final String perm = bp.name;
9363            boolean allowedSig = false;
9364            int grant = GRANT_DENIED;
9365
9366            // Keep track of app op permissions.
9367            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
9368                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
9369                if (pkgs == null) {
9370                    pkgs = new ArraySet<>();
9371                    mAppOpPermissionPackages.put(bp.name, pkgs);
9372                }
9373                pkgs.add(pkg.packageName);
9374            }
9375
9376            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
9377            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
9378                    >= Build.VERSION_CODES.M;
9379            switch (level) {
9380                case PermissionInfo.PROTECTION_NORMAL: {
9381                    // For all apps normal permissions are install time ones.
9382                    grant = GRANT_INSTALL;
9383                } break;
9384
9385                case PermissionInfo.PROTECTION_DANGEROUS: {
9386                    // If a permission review is required for legacy apps we represent
9387                    // their permissions as always granted runtime ones since we need
9388                    // to keep the review required permission flag per user while an
9389                    // install permission's state is shared across all users.
9390                    if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) {
9391                        // For legacy apps dangerous permissions are install time ones.
9392                        grant = GRANT_INSTALL;
9393                    } else if (origPermissions.hasInstallPermission(bp.name)) {
9394                        // For legacy apps that became modern, install becomes runtime.
9395                        grant = GRANT_UPGRADE;
9396                    } else if (mPromoteSystemApps
9397                            && isSystemApp(ps)
9398                            && mExistingSystemPackages.contains(ps.name)) {
9399                        // For legacy system apps, install becomes runtime.
9400                        // We cannot check hasInstallPermission() for system apps since those
9401                        // permissions were granted implicitly and not persisted pre-M.
9402                        grant = GRANT_UPGRADE;
9403                    } else {
9404                        // For modern apps keep runtime permissions unchanged.
9405                        grant = GRANT_RUNTIME;
9406                    }
9407                } break;
9408
9409                case PermissionInfo.PROTECTION_SIGNATURE: {
9410                    // For all apps signature permissions are install time ones.
9411                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
9412                    if (allowedSig) {
9413                        grant = GRANT_INSTALL;
9414                    }
9415                } break;
9416            }
9417
9418            if (DEBUG_INSTALL) {
9419                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
9420            }
9421
9422            if (grant != GRANT_DENIED) {
9423                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
9424                    // If this is an existing, non-system package, then
9425                    // we can't add any new permissions to it.
9426                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
9427                        // Except...  if this is a permission that was added
9428                        // to the platform (note: need to only do this when
9429                        // updating the platform).
9430                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
9431                            grant = GRANT_DENIED;
9432                        }
9433                    }
9434                }
9435
9436                switch (grant) {
9437                    case GRANT_INSTALL: {
9438                        // Revoke this as runtime permission to handle the case of
9439                        // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps
9440                        for (int userId : UserManagerService.getInstance().getUserIds()) {
9441                            if (origPermissions.getRuntimePermissionState(
9442                                    bp.name, userId) != null) {
9443                                // Revoke the runtime permission and clear the flags.
9444                                origPermissions.revokeRuntimePermission(bp, userId);
9445                                origPermissions.updatePermissionFlags(bp, userId,
9446                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
9447                                // If we revoked a permission permission, we have to write.
9448                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9449                                        changedRuntimePermissionUserIds, userId);
9450                            }
9451                        }
9452                        // Grant an install permission.
9453                        if (permissionsState.grantInstallPermission(bp) !=
9454                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
9455                            changedInstallPermission = true;
9456                        }
9457                    } break;
9458
9459                    case GRANT_RUNTIME: {
9460                        // Grant previously granted runtime permissions.
9461                        for (int userId : UserManagerService.getInstance().getUserIds()) {
9462                            PermissionState permissionState = origPermissions
9463                                    .getRuntimePermissionState(bp.name, userId);
9464                            int flags = permissionState != null
9465                                    ? permissionState.getFlags() : 0;
9466                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
9467                                if (permissionsState.grantRuntimePermission(bp, userId) ==
9468                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
9469                                    // If we cannot put the permission as it was, we have to write.
9470                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9471                                            changedRuntimePermissionUserIds, userId);
9472                                }
9473                                // If the app supports runtime permissions no need for a review.
9474                                if (Build.PERMISSIONS_REVIEW_REQUIRED
9475                                        && appSupportsRuntimePermissions
9476                                        && (flags & PackageManager
9477                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
9478                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
9479                                    // Since we changed the flags, we have to write.
9480                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9481                                            changedRuntimePermissionUserIds, userId);
9482                                }
9483                            } else if (Build.PERMISSIONS_REVIEW_REQUIRED
9484                                    && !appSupportsRuntimePermissions) {
9485                                // For legacy apps that need a permission review, every new
9486                                // runtime permission is granted but it is pending a review.
9487                                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
9488                                    permissionsState.grantRuntimePermission(bp, userId);
9489                                    flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
9490                                    // We changed the permission and flags, hence have to write.
9491                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9492                                            changedRuntimePermissionUserIds, userId);
9493                                }
9494                            }
9495                            // Propagate the permission flags.
9496                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
9497                        }
9498                    } break;
9499
9500                    case GRANT_UPGRADE: {
9501                        // Grant runtime permissions for a previously held install permission.
9502                        PermissionState permissionState = origPermissions
9503                                .getInstallPermissionState(bp.name);
9504                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
9505
9506                        if (origPermissions.revokeInstallPermission(bp)
9507                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
9508                            // We will be transferring the permission flags, so clear them.
9509                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
9510                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
9511                            changedInstallPermission = true;
9512                        }
9513
9514                        // If the permission is not to be promoted to runtime we ignore it and
9515                        // also its other flags as they are not applicable to install permissions.
9516                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
9517                            for (int userId : currentUserIds) {
9518                                if (permissionsState.grantRuntimePermission(bp, userId) !=
9519                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
9520                                    // Transfer the permission flags.
9521                                    permissionsState.updatePermissionFlags(bp, userId,
9522                                            flags, flags);
9523                                    // If we granted the permission, we have to write.
9524                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
9525                                            changedRuntimePermissionUserIds, userId);
9526                                }
9527                            }
9528                        }
9529                    } break;
9530
9531                    default: {
9532                        if (packageOfInterest == null
9533                                || packageOfInterest.equals(pkg.packageName)) {
9534                            Slog.w(TAG, "Not granting permission " + perm
9535                                    + " to package " + pkg.packageName
9536                                    + " because it was previously installed without");
9537                        }
9538                    } break;
9539                }
9540            } else {
9541                if (permissionsState.revokeInstallPermission(bp) !=
9542                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
9543                    // Also drop the permission flags.
9544                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
9545                            PackageManager.MASK_PERMISSION_FLAGS, 0);
9546                    changedInstallPermission = true;
9547                    Slog.i(TAG, "Un-granting permission " + perm
9548                            + " from package " + pkg.packageName
9549                            + " (protectionLevel=" + bp.protectionLevel
9550                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
9551                            + ")");
9552                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
9553                    // Don't print warning for app op permissions, since it is fine for them
9554                    // not to be granted, there is a UI for the user to decide.
9555                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
9556                        Slog.w(TAG, "Not granting permission " + perm
9557                                + " to package " + pkg.packageName
9558                                + " (protectionLevel=" + bp.protectionLevel
9559                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
9560                                + ")");
9561                    }
9562                }
9563            }
9564        }
9565
9566        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
9567                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
9568            // This is the first that we have heard about this package, so the
9569            // permissions we have now selected are fixed until explicitly
9570            // changed.
9571            ps.installPermissionsFixed = true;
9572        }
9573
9574        // Persist the runtime permissions state for users with changes. If permissions
9575        // were revoked because no app in the shared user declares them we have to
9576        // write synchronously to avoid losing runtime permissions state.
9577        for (int userId : changedRuntimePermissionUserIds) {
9578            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
9579        }
9580
9581        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9582    }
9583
9584    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
9585        boolean allowed = false;
9586        final int NP = PackageParser.NEW_PERMISSIONS.length;
9587        for (int ip=0; ip<NP; ip++) {
9588            final PackageParser.NewPermissionInfo npi
9589                    = PackageParser.NEW_PERMISSIONS[ip];
9590            if (npi.name.equals(perm)
9591                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
9592                allowed = true;
9593                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
9594                        + pkg.packageName);
9595                break;
9596            }
9597        }
9598        return allowed;
9599    }
9600
9601    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
9602            BasePermission bp, PermissionsState origPermissions) {
9603        boolean allowed;
9604        allowed = (compareSignatures(
9605                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
9606                        == PackageManager.SIGNATURE_MATCH)
9607                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
9608                        == PackageManager.SIGNATURE_MATCH);
9609        if (!allowed && (bp.protectionLevel
9610                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
9611            if (isSystemApp(pkg)) {
9612                // For updated system applications, a system permission
9613                // is granted only if it had been defined by the original application.
9614                if (pkg.isUpdatedSystemApp()) {
9615                    final PackageSetting sysPs = mSettings
9616                            .getDisabledSystemPkgLPr(pkg.packageName);
9617                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
9618                        // If the original was granted this permission, we take
9619                        // that grant decision as read and propagate it to the
9620                        // update.
9621                        if (sysPs.isPrivileged()) {
9622                            allowed = true;
9623                        }
9624                    } else {
9625                        // The system apk may have been updated with an older
9626                        // version of the one on the data partition, but which
9627                        // granted a new system permission that it didn't have
9628                        // before.  In this case we do want to allow the app to
9629                        // now get the new permission if the ancestral apk is
9630                        // privileged to get it.
9631                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
9632                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
9633                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
9634                                    allowed = true;
9635                                    break;
9636                                }
9637                            }
9638                        }
9639                        // Also if a privileged parent package on the system image or any of
9640                        // its children requested a privileged permission, the updated child
9641                        // packages can also get the permission.
9642                        if (pkg.parentPackage != null) {
9643                            final PackageSetting disabledSysParentPs = mSettings
9644                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
9645                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
9646                                    && disabledSysParentPs.isPrivileged()) {
9647                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
9648                                    allowed = true;
9649                                } else if (disabledSysParentPs.pkg.childPackages != null) {
9650                                    final int count = disabledSysParentPs.pkg.childPackages.size();
9651                                    for (int i = 0; i < count; i++) {
9652                                        PackageParser.Package disabledSysChildPkg =
9653                                                disabledSysParentPs.pkg.childPackages.get(i);
9654                                        if (isPackageRequestingPermission(disabledSysChildPkg,
9655                                                perm)) {
9656                                            allowed = true;
9657                                            break;
9658                                        }
9659                                    }
9660                                }
9661                            }
9662                        }
9663                    }
9664                } else {
9665                    allowed = isPrivilegedApp(pkg);
9666                }
9667            }
9668        }
9669        if (!allowed) {
9670            if (!allowed && (bp.protectionLevel
9671                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
9672                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
9673                // If this was a previously normal/dangerous permission that got moved
9674                // to a system permission as part of the runtime permission redesign, then
9675                // we still want to blindly grant it to old apps.
9676                allowed = true;
9677            }
9678            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
9679                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
9680                // If this permission is to be granted to the system installer and
9681                // this app is an installer, then it gets the permission.
9682                allowed = true;
9683            }
9684            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
9685                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
9686                // If this permission is to be granted to the system verifier and
9687                // this app is a verifier, then it gets the permission.
9688                allowed = true;
9689            }
9690            if (!allowed && (bp.protectionLevel
9691                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
9692                    && isSystemApp(pkg)) {
9693                // Any pre-installed system app is allowed to get this permission.
9694                allowed = true;
9695            }
9696            if (!allowed && (bp.protectionLevel
9697                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
9698                // For development permissions, a development permission
9699                // is granted only if it was already granted.
9700                allowed = origPermissions.hasInstallPermission(perm);
9701            }
9702            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
9703                    && pkg.packageName.equals(mSetupWizardPackage)) {
9704                // If this permission is to be granted to the system setup wizard and
9705                // this app is a setup wizard, then it gets the permission.
9706                allowed = true;
9707            }
9708        }
9709        return allowed;
9710    }
9711
9712    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
9713        final int permCount = pkg.requestedPermissions.size();
9714        for (int j = 0; j < permCount; j++) {
9715            String requestedPermission = pkg.requestedPermissions.get(j);
9716            if (permission.equals(requestedPermission)) {
9717                return true;
9718            }
9719        }
9720        return false;
9721    }
9722
9723    final class ActivityIntentResolver
9724            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
9725        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9726                boolean defaultOnly, int userId) {
9727            if (!sUserManager.exists(userId)) return null;
9728            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9729            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9730        }
9731
9732        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9733                int userId) {
9734            if (!sUserManager.exists(userId)) return null;
9735            mFlags = flags;
9736            return super.queryIntent(intent, resolvedType,
9737                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9738        }
9739
9740        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9741                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
9742            if (!sUserManager.exists(userId)) return null;
9743            if (packageActivities == null) {
9744                return null;
9745            }
9746            mFlags = flags;
9747            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9748            final int N = packageActivities.size();
9749            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
9750                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
9751
9752            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
9753            for (int i = 0; i < N; ++i) {
9754                intentFilters = packageActivities.get(i).intents;
9755                if (intentFilters != null && intentFilters.size() > 0) {
9756                    PackageParser.ActivityIntentInfo[] array =
9757                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
9758                    intentFilters.toArray(array);
9759                    listCut.add(array);
9760                }
9761            }
9762            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9763        }
9764
9765        public final void addActivity(PackageParser.Activity a, String type) {
9766            final boolean systemApp = a.info.applicationInfo.isSystemApp();
9767            mActivities.put(a.getComponentName(), a);
9768            if (DEBUG_SHOW_INFO)
9769                Log.v(
9770                TAG, "  " + type + " " +
9771                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
9772            if (DEBUG_SHOW_INFO)
9773                Log.v(TAG, "    Class=" + a.info.name);
9774            final int NI = a.intents.size();
9775            for (int j=0; j<NI; j++) {
9776                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9777                if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
9778                    intent.setPriority(0);
9779                    Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
9780                            + a.className + " with priority > 0, forcing to 0");
9781                }
9782                if (DEBUG_SHOW_INFO) {
9783                    Log.v(TAG, "    IntentFilter:");
9784                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9785                }
9786                if (!intent.debugCheck()) {
9787                    Log.w(TAG, "==> For Activity " + a.info.name);
9788                }
9789                addFilter(intent);
9790            }
9791        }
9792
9793        public final void removeActivity(PackageParser.Activity a, String type) {
9794            mActivities.remove(a.getComponentName());
9795            if (DEBUG_SHOW_INFO) {
9796                Log.v(TAG, "  " + type + " "
9797                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
9798                                : a.info.name) + ":");
9799                Log.v(TAG, "    Class=" + a.info.name);
9800            }
9801            final int NI = a.intents.size();
9802            for (int j=0; j<NI; j++) {
9803                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
9804                if (DEBUG_SHOW_INFO) {
9805                    Log.v(TAG, "    IntentFilter:");
9806                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
9807                }
9808                removeFilter(intent);
9809            }
9810        }
9811
9812        @Override
9813        protected boolean allowFilterResult(
9814                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
9815            ActivityInfo filterAi = filter.activity.info;
9816            for (int i=dest.size()-1; i>=0; i--) {
9817                ActivityInfo destAi = dest.get(i).activityInfo;
9818                if (destAi.name == filterAi.name
9819                        && destAi.packageName == filterAi.packageName) {
9820                    return false;
9821                }
9822            }
9823            return true;
9824        }
9825
9826        @Override
9827        protected ActivityIntentInfo[] newArray(int size) {
9828            return new ActivityIntentInfo[size];
9829        }
9830
9831        @Override
9832        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
9833            if (!sUserManager.exists(userId)) return true;
9834            PackageParser.Package p = filter.activity.owner;
9835            if (p != null) {
9836                PackageSetting ps = (PackageSetting)p.mExtras;
9837                if (ps != null) {
9838                    // System apps are never considered stopped for purposes of
9839                    // filtering, because there may be no way for the user to
9840                    // actually re-launch them.
9841                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
9842                            && ps.getStopped(userId);
9843                }
9844            }
9845            return false;
9846        }
9847
9848        @Override
9849        protected boolean isPackageForFilter(String packageName,
9850                PackageParser.ActivityIntentInfo info) {
9851            return packageName.equals(info.activity.owner.packageName);
9852        }
9853
9854        @Override
9855        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
9856                int match, int userId) {
9857            if (!sUserManager.exists(userId)) return null;
9858            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
9859                return null;
9860            }
9861            final PackageParser.Activity activity = info.activity;
9862            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
9863            if (ps == null) {
9864                return null;
9865            }
9866            ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
9867                    ps.readUserState(userId), userId);
9868            if (ai == null) {
9869                return null;
9870            }
9871            final ResolveInfo res = new ResolveInfo();
9872            res.activityInfo = ai;
9873            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
9874                res.filter = info;
9875            }
9876            if (info != null) {
9877                res.handleAllWebDataURI = info.handleAllWebDataURI();
9878            }
9879            res.priority = info.getPriority();
9880            res.preferredOrder = activity.owner.mPreferredOrder;
9881            //System.out.println("Result: " + res.activityInfo.className +
9882            //                   " = " + res.priority);
9883            res.match = match;
9884            res.isDefault = info.hasDefault;
9885            res.labelRes = info.labelRes;
9886            res.nonLocalizedLabel = info.nonLocalizedLabel;
9887            if (userNeedsBadging(userId)) {
9888                res.noResourceId = true;
9889            } else {
9890                res.icon = info.icon;
9891            }
9892            res.iconResourceId = info.icon;
9893            res.system = res.activityInfo.applicationInfo.isSystemApp();
9894            return res;
9895        }
9896
9897        @Override
9898        protected void sortResults(List<ResolveInfo> results) {
9899            Collections.sort(results, mResolvePrioritySorter);
9900        }
9901
9902        @Override
9903        protected void dumpFilter(PrintWriter out, String prefix,
9904                PackageParser.ActivityIntentInfo filter) {
9905            out.print(prefix); out.print(
9906                    Integer.toHexString(System.identityHashCode(filter.activity)));
9907                    out.print(' ');
9908                    filter.activity.printComponentShortName(out);
9909                    out.print(" filter ");
9910                    out.println(Integer.toHexString(System.identityHashCode(filter)));
9911        }
9912
9913        @Override
9914        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
9915            return filter.activity;
9916        }
9917
9918        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
9919            PackageParser.Activity activity = (PackageParser.Activity)label;
9920            out.print(prefix); out.print(
9921                    Integer.toHexString(System.identityHashCode(activity)));
9922                    out.print(' ');
9923                    activity.printComponentShortName(out);
9924            if (count > 1) {
9925                out.print(" ("); out.print(count); out.print(" filters)");
9926            }
9927            out.println();
9928        }
9929
9930//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
9931//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
9932//            final List<ResolveInfo> retList = Lists.newArrayList();
9933//            while (i.hasNext()) {
9934//                final ResolveInfo resolveInfo = i.next();
9935//                if (isEnabledLP(resolveInfo.activityInfo)) {
9936//                    retList.add(resolveInfo);
9937//                }
9938//            }
9939//            return retList;
9940//        }
9941
9942        // Keys are String (activity class name), values are Activity.
9943        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
9944                = new ArrayMap<ComponentName, PackageParser.Activity>();
9945        private int mFlags;
9946    }
9947
9948    private final class ServiceIntentResolver
9949            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
9950        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
9951                boolean defaultOnly, int userId) {
9952            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
9953            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
9954        }
9955
9956        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
9957                int userId) {
9958            if (!sUserManager.exists(userId)) return null;
9959            mFlags = flags;
9960            return super.queryIntent(intent, resolvedType,
9961                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
9962        }
9963
9964        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
9965                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
9966            if (!sUserManager.exists(userId)) return null;
9967            if (packageServices == null) {
9968                return null;
9969            }
9970            mFlags = flags;
9971            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
9972            final int N = packageServices.size();
9973            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
9974                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
9975
9976            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
9977            for (int i = 0; i < N; ++i) {
9978                intentFilters = packageServices.get(i).intents;
9979                if (intentFilters != null && intentFilters.size() > 0) {
9980                    PackageParser.ServiceIntentInfo[] array =
9981                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
9982                    intentFilters.toArray(array);
9983                    listCut.add(array);
9984                }
9985            }
9986            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
9987        }
9988
9989        public final void addService(PackageParser.Service s) {
9990            mServices.put(s.getComponentName(), s);
9991            if (DEBUG_SHOW_INFO) {
9992                Log.v(TAG, "  "
9993                        + (s.info.nonLocalizedLabel != null
9994                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
9995                Log.v(TAG, "    Class=" + s.info.name);
9996            }
9997            final int NI = s.intents.size();
9998            int j;
9999            for (j=0; j<NI; j++) {
10000                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10001                if (DEBUG_SHOW_INFO) {
10002                    Log.v(TAG, "    IntentFilter:");
10003                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10004                }
10005                if (!intent.debugCheck()) {
10006                    Log.w(TAG, "==> For Service " + s.info.name);
10007                }
10008                addFilter(intent);
10009            }
10010        }
10011
10012        public final void removeService(PackageParser.Service s) {
10013            mServices.remove(s.getComponentName());
10014            if (DEBUG_SHOW_INFO) {
10015                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
10016                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
10017                Log.v(TAG, "    Class=" + s.info.name);
10018            }
10019            final int NI = s.intents.size();
10020            int j;
10021            for (j=0; j<NI; j++) {
10022                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
10023                if (DEBUG_SHOW_INFO) {
10024                    Log.v(TAG, "    IntentFilter:");
10025                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10026                }
10027                removeFilter(intent);
10028            }
10029        }
10030
10031        @Override
10032        protected boolean allowFilterResult(
10033                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
10034            ServiceInfo filterSi = filter.service.info;
10035            for (int i=dest.size()-1; i>=0; i--) {
10036                ServiceInfo destAi = dest.get(i).serviceInfo;
10037                if (destAi.name == filterSi.name
10038                        && destAi.packageName == filterSi.packageName) {
10039                    return false;
10040                }
10041            }
10042            return true;
10043        }
10044
10045        @Override
10046        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
10047            return new PackageParser.ServiceIntentInfo[size];
10048        }
10049
10050        @Override
10051        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
10052            if (!sUserManager.exists(userId)) return true;
10053            PackageParser.Package p = filter.service.owner;
10054            if (p != null) {
10055                PackageSetting ps = (PackageSetting)p.mExtras;
10056                if (ps != null) {
10057                    // System apps are never considered stopped for purposes of
10058                    // filtering, because there may be no way for the user to
10059                    // actually re-launch them.
10060                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
10061                            && ps.getStopped(userId);
10062                }
10063            }
10064            return false;
10065        }
10066
10067        @Override
10068        protected boolean isPackageForFilter(String packageName,
10069                PackageParser.ServiceIntentInfo info) {
10070            return packageName.equals(info.service.owner.packageName);
10071        }
10072
10073        @Override
10074        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
10075                int match, int userId) {
10076            if (!sUserManager.exists(userId)) return null;
10077            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
10078            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
10079                return null;
10080            }
10081            final PackageParser.Service service = info.service;
10082            PackageSetting ps = (PackageSetting) service.owner.mExtras;
10083            if (ps == null) {
10084                return null;
10085            }
10086            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
10087                    ps.readUserState(userId), userId);
10088            if (si == null) {
10089                return null;
10090            }
10091            final ResolveInfo res = new ResolveInfo();
10092            res.serviceInfo = si;
10093            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
10094                res.filter = filter;
10095            }
10096            res.priority = info.getPriority();
10097            res.preferredOrder = service.owner.mPreferredOrder;
10098            res.match = match;
10099            res.isDefault = info.hasDefault;
10100            res.labelRes = info.labelRes;
10101            res.nonLocalizedLabel = info.nonLocalizedLabel;
10102            res.icon = info.icon;
10103            res.system = res.serviceInfo.applicationInfo.isSystemApp();
10104            return res;
10105        }
10106
10107        @Override
10108        protected void sortResults(List<ResolveInfo> results) {
10109            Collections.sort(results, mResolvePrioritySorter);
10110        }
10111
10112        @Override
10113        protected void dumpFilter(PrintWriter out, String prefix,
10114                PackageParser.ServiceIntentInfo filter) {
10115            out.print(prefix); out.print(
10116                    Integer.toHexString(System.identityHashCode(filter.service)));
10117                    out.print(' ');
10118                    filter.service.printComponentShortName(out);
10119                    out.print(" filter ");
10120                    out.println(Integer.toHexString(System.identityHashCode(filter)));
10121        }
10122
10123        @Override
10124        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
10125            return filter.service;
10126        }
10127
10128        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10129            PackageParser.Service service = (PackageParser.Service)label;
10130            out.print(prefix); out.print(
10131                    Integer.toHexString(System.identityHashCode(service)));
10132                    out.print(' ');
10133                    service.printComponentShortName(out);
10134            if (count > 1) {
10135                out.print(" ("); out.print(count); out.print(" filters)");
10136            }
10137            out.println();
10138        }
10139
10140//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
10141//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
10142//            final List<ResolveInfo> retList = Lists.newArrayList();
10143//            while (i.hasNext()) {
10144//                final ResolveInfo resolveInfo = (ResolveInfo) i;
10145//                if (isEnabledLP(resolveInfo.serviceInfo)) {
10146//                    retList.add(resolveInfo);
10147//                }
10148//            }
10149//            return retList;
10150//        }
10151
10152        // Keys are String (activity class name), values are Activity.
10153        private final ArrayMap<ComponentName, PackageParser.Service> mServices
10154                = new ArrayMap<ComponentName, PackageParser.Service>();
10155        private int mFlags;
10156    };
10157
10158    private final class ProviderIntentResolver
10159            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
10160        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
10161                boolean defaultOnly, int userId) {
10162            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
10163            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
10164        }
10165
10166        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
10167                int userId) {
10168            if (!sUserManager.exists(userId))
10169                return null;
10170            mFlags = flags;
10171            return super.queryIntent(intent, resolvedType,
10172                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
10173        }
10174
10175        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
10176                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
10177            if (!sUserManager.exists(userId))
10178                return null;
10179            if (packageProviders == null) {
10180                return null;
10181            }
10182            mFlags = flags;
10183            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
10184            final int N = packageProviders.size();
10185            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
10186                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
10187
10188            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
10189            for (int i = 0; i < N; ++i) {
10190                intentFilters = packageProviders.get(i).intents;
10191                if (intentFilters != null && intentFilters.size() > 0) {
10192                    PackageParser.ProviderIntentInfo[] array =
10193                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
10194                    intentFilters.toArray(array);
10195                    listCut.add(array);
10196                }
10197            }
10198            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
10199        }
10200
10201        public final void addProvider(PackageParser.Provider p) {
10202            if (mProviders.containsKey(p.getComponentName())) {
10203                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
10204                return;
10205            }
10206
10207            mProviders.put(p.getComponentName(), p);
10208            if (DEBUG_SHOW_INFO) {
10209                Log.v(TAG, "  "
10210                        + (p.info.nonLocalizedLabel != null
10211                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
10212                Log.v(TAG, "    Class=" + p.info.name);
10213            }
10214            final int NI = p.intents.size();
10215            int j;
10216            for (j = 0; j < NI; j++) {
10217                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
10218                if (DEBUG_SHOW_INFO) {
10219                    Log.v(TAG, "    IntentFilter:");
10220                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10221                }
10222                if (!intent.debugCheck()) {
10223                    Log.w(TAG, "==> For Provider " + p.info.name);
10224                }
10225                addFilter(intent);
10226            }
10227        }
10228
10229        public final void removeProvider(PackageParser.Provider p) {
10230            mProviders.remove(p.getComponentName());
10231            if (DEBUG_SHOW_INFO) {
10232                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
10233                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
10234                Log.v(TAG, "    Class=" + p.info.name);
10235            }
10236            final int NI = p.intents.size();
10237            int j;
10238            for (j = 0; j < NI; j++) {
10239                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
10240                if (DEBUG_SHOW_INFO) {
10241                    Log.v(TAG, "    IntentFilter:");
10242                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
10243                }
10244                removeFilter(intent);
10245            }
10246        }
10247
10248        @Override
10249        protected boolean allowFilterResult(
10250                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
10251            ProviderInfo filterPi = filter.provider.info;
10252            for (int i = dest.size() - 1; i >= 0; i--) {
10253                ProviderInfo destPi = dest.get(i).providerInfo;
10254                if (destPi.name == filterPi.name
10255                        && destPi.packageName == filterPi.packageName) {
10256                    return false;
10257                }
10258            }
10259            return true;
10260        }
10261
10262        @Override
10263        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
10264            return new PackageParser.ProviderIntentInfo[size];
10265        }
10266
10267        @Override
10268        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
10269            if (!sUserManager.exists(userId))
10270                return true;
10271            PackageParser.Package p = filter.provider.owner;
10272            if (p != null) {
10273                PackageSetting ps = (PackageSetting) p.mExtras;
10274                if (ps != null) {
10275                    // System apps are never considered stopped for purposes of
10276                    // filtering, because there may be no way for the user to
10277                    // actually re-launch them.
10278                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
10279                            && ps.getStopped(userId);
10280                }
10281            }
10282            return false;
10283        }
10284
10285        @Override
10286        protected boolean isPackageForFilter(String packageName,
10287                PackageParser.ProviderIntentInfo info) {
10288            return packageName.equals(info.provider.owner.packageName);
10289        }
10290
10291        @Override
10292        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
10293                int match, int userId) {
10294            if (!sUserManager.exists(userId))
10295                return null;
10296            final PackageParser.ProviderIntentInfo info = filter;
10297            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
10298                return null;
10299            }
10300            final PackageParser.Provider provider = info.provider;
10301            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
10302            if (ps == null) {
10303                return null;
10304            }
10305            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
10306                    ps.readUserState(userId), userId);
10307            if (pi == null) {
10308                return null;
10309            }
10310            final ResolveInfo res = new ResolveInfo();
10311            res.providerInfo = pi;
10312            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
10313                res.filter = filter;
10314            }
10315            res.priority = info.getPriority();
10316            res.preferredOrder = provider.owner.mPreferredOrder;
10317            res.match = match;
10318            res.isDefault = info.hasDefault;
10319            res.labelRes = info.labelRes;
10320            res.nonLocalizedLabel = info.nonLocalizedLabel;
10321            res.icon = info.icon;
10322            res.system = res.providerInfo.applicationInfo.isSystemApp();
10323            return res;
10324        }
10325
10326        @Override
10327        protected void sortResults(List<ResolveInfo> results) {
10328            Collections.sort(results, mResolvePrioritySorter);
10329        }
10330
10331        @Override
10332        protected void dumpFilter(PrintWriter out, String prefix,
10333                PackageParser.ProviderIntentInfo filter) {
10334            out.print(prefix);
10335            out.print(
10336                    Integer.toHexString(System.identityHashCode(filter.provider)));
10337            out.print(' ');
10338            filter.provider.printComponentShortName(out);
10339            out.print(" filter ");
10340            out.println(Integer.toHexString(System.identityHashCode(filter)));
10341        }
10342
10343        @Override
10344        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
10345            return filter.provider;
10346        }
10347
10348        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
10349            PackageParser.Provider provider = (PackageParser.Provider)label;
10350            out.print(prefix); out.print(
10351                    Integer.toHexString(System.identityHashCode(provider)));
10352                    out.print(' ');
10353                    provider.printComponentShortName(out);
10354            if (count > 1) {
10355                out.print(" ("); out.print(count); out.print(" filters)");
10356            }
10357            out.println();
10358        }
10359
10360        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
10361                = new ArrayMap<ComponentName, PackageParser.Provider>();
10362        private int mFlags;
10363    }
10364
10365    private static final class EphemeralIntentResolver
10366            extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> {
10367        @Override
10368        protected EphemeralResolveIntentInfo[] newArray(int size) {
10369            return new EphemeralResolveIntentInfo[size];
10370        }
10371
10372        @Override
10373        protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) {
10374            return true;
10375        }
10376
10377        @Override
10378        protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match,
10379                int userId) {
10380            if (!sUserManager.exists(userId)) {
10381                return null;
10382            }
10383            return info.getEphemeralResolveInfo();
10384        }
10385    }
10386
10387    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
10388            new Comparator<ResolveInfo>() {
10389        public int compare(ResolveInfo r1, ResolveInfo r2) {
10390            int v1 = r1.priority;
10391            int v2 = r2.priority;
10392            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
10393            if (v1 != v2) {
10394                return (v1 > v2) ? -1 : 1;
10395            }
10396            v1 = r1.preferredOrder;
10397            v2 = r2.preferredOrder;
10398            if (v1 != v2) {
10399                return (v1 > v2) ? -1 : 1;
10400            }
10401            if (r1.isDefault != r2.isDefault) {
10402                return r1.isDefault ? -1 : 1;
10403            }
10404            v1 = r1.match;
10405            v2 = r2.match;
10406            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
10407            if (v1 != v2) {
10408                return (v1 > v2) ? -1 : 1;
10409            }
10410            if (r1.system != r2.system) {
10411                return r1.system ? -1 : 1;
10412            }
10413            if (r1.activityInfo != null) {
10414                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
10415            }
10416            if (r1.serviceInfo != null) {
10417                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
10418            }
10419            if (r1.providerInfo != null) {
10420                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
10421            }
10422            return 0;
10423        }
10424    };
10425
10426    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
10427            new Comparator<ProviderInfo>() {
10428        public int compare(ProviderInfo p1, ProviderInfo p2) {
10429            final int v1 = p1.initOrder;
10430            final int v2 = p2.initOrder;
10431            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
10432        }
10433    };
10434
10435    final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
10436            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
10437            final int[] userIds) {
10438        mHandler.post(new Runnable() {
10439            @Override
10440            public void run() {
10441                try {
10442                    final IActivityManager am = ActivityManagerNative.getDefault();
10443                    if (am == null) return;
10444                    final int[] resolvedUserIds;
10445                    if (userIds == null) {
10446                        resolvedUserIds = am.getRunningUserIds();
10447                    } else {
10448                        resolvedUserIds = userIds;
10449                    }
10450                    for (int id : resolvedUserIds) {
10451                        final Intent intent = new Intent(action,
10452                                pkg != null ? Uri.fromParts("package", pkg, null) : null);
10453                        if (extras != null) {
10454                            intent.putExtras(extras);
10455                        }
10456                        if (targetPkg != null) {
10457                            intent.setPackage(targetPkg);
10458                        }
10459                        // Modify the UID when posting to other users
10460                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
10461                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
10462                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
10463                            intent.putExtra(Intent.EXTRA_UID, uid);
10464                        }
10465                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
10466                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
10467                        if (DEBUG_BROADCASTS) {
10468                            RuntimeException here = new RuntimeException("here");
10469                            here.fillInStackTrace();
10470                            Slog.d(TAG, "Sending to user " + id + ": "
10471                                    + intent.toShortString(false, true, false, false)
10472                                    + " " + intent.getExtras(), here);
10473                        }
10474                        am.broadcastIntent(null, intent, null, finishedReceiver,
10475                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
10476                                null, finishedReceiver != null, false, id);
10477                    }
10478                } catch (RemoteException ex) {
10479                }
10480            }
10481        });
10482    }
10483
10484    /**
10485     * Check if the external storage media is available. This is true if there
10486     * is a mounted external storage medium or if the external storage is
10487     * emulated.
10488     */
10489    private boolean isExternalMediaAvailable() {
10490        return mMediaMounted || Environment.isExternalStorageEmulated();
10491    }
10492
10493    @Override
10494    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
10495        // writer
10496        synchronized (mPackages) {
10497            if (!isExternalMediaAvailable()) {
10498                // If the external storage is no longer mounted at this point,
10499                // the caller may not have been able to delete all of this
10500                // packages files and can not delete any more.  Bail.
10501                return null;
10502            }
10503            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
10504            if (lastPackage != null) {
10505                pkgs.remove(lastPackage);
10506            }
10507            if (pkgs.size() > 0) {
10508                return pkgs.get(0);
10509            }
10510        }
10511        return null;
10512    }
10513
10514    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
10515        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
10516                userId, andCode ? 1 : 0, packageName);
10517        if (mSystemReady) {
10518            msg.sendToTarget();
10519        } else {
10520            if (mPostSystemReadyMessages == null) {
10521                mPostSystemReadyMessages = new ArrayList<>();
10522            }
10523            mPostSystemReadyMessages.add(msg);
10524        }
10525    }
10526
10527    void startCleaningPackages() {
10528        // reader
10529        if (!isExternalMediaAvailable()) {
10530            return;
10531        }
10532        synchronized (mPackages) {
10533            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
10534                return;
10535            }
10536        }
10537        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
10538        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
10539        IActivityManager am = ActivityManagerNative.getDefault();
10540        if (am != null) {
10541            try {
10542                am.startService(null, intent, null, mContext.getOpPackageName(),
10543                        UserHandle.USER_SYSTEM);
10544            } catch (RemoteException e) {
10545            }
10546        }
10547    }
10548
10549    @Override
10550    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
10551            int installFlags, String installerPackageName, int userId) {
10552        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
10553
10554        final int callingUid = Binder.getCallingUid();
10555        enforceCrossUserPermission(callingUid, userId,
10556                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
10557
10558        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
10559            try {
10560                if (observer != null) {
10561                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
10562                }
10563            } catch (RemoteException re) {
10564            }
10565            return;
10566        }
10567
10568        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
10569            installFlags |= PackageManager.INSTALL_FROM_ADB;
10570
10571        } else {
10572            // Caller holds INSTALL_PACKAGES permission, so we're less strict
10573            // about installerPackageName.
10574
10575            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
10576            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
10577        }
10578
10579        UserHandle user;
10580        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
10581            user = UserHandle.ALL;
10582        } else {
10583            user = new UserHandle(userId);
10584        }
10585
10586        // Only system components can circumvent runtime permissions when installing.
10587        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
10588                && mContext.checkCallingOrSelfPermission(Manifest.permission
10589                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
10590            throw new SecurityException("You need the "
10591                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
10592                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
10593        }
10594
10595        final File originFile = new File(originPath);
10596        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
10597
10598        final Message msg = mHandler.obtainMessage(INIT_COPY);
10599        final VerificationInfo verificationInfo = new VerificationInfo(
10600                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
10601        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
10602                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
10603                null /*packageAbiOverride*/, null /*grantedPermissions*/);
10604        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
10605        msg.obj = params;
10606
10607        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
10608                System.identityHashCode(msg.obj));
10609        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10610                System.identityHashCode(msg.obj));
10611
10612        mHandler.sendMessage(msg);
10613    }
10614
10615    void installStage(String packageName, File stagedDir, String stagedCid,
10616            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
10617            String installerPackageName, int installerUid, UserHandle user) {
10618        if (DEBUG_EPHEMERAL) {
10619            if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
10620                Slog.d(TAG, "Ephemeral install of " + packageName);
10621            }
10622        }
10623        final VerificationInfo verificationInfo = new VerificationInfo(
10624                sessionParams.originatingUri, sessionParams.referrerUri,
10625                sessionParams.originatingUid, installerUid);
10626
10627        final OriginInfo origin;
10628        if (stagedDir != null) {
10629            origin = OriginInfo.fromStagedFile(stagedDir);
10630        } else {
10631            origin = OriginInfo.fromStagedContainer(stagedCid);
10632        }
10633
10634        final Message msg = mHandler.obtainMessage(INIT_COPY);
10635        final InstallParams params = new InstallParams(origin, null, observer,
10636                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
10637                verificationInfo, user, sessionParams.abiOverride,
10638                sessionParams.grantedRuntimePermissions);
10639        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
10640        msg.obj = params;
10641
10642        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
10643                System.identityHashCode(msg.obj));
10644        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
10645                System.identityHashCode(msg.obj));
10646
10647        mHandler.sendMessage(msg);
10648    }
10649
10650    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
10651            int userId) {
10652        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
10653        sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
10654    }
10655
10656    private void sendPackageAddedForUser(String packageName, boolean isSystem,
10657            int appId, int userId) {
10658        Bundle extras = new Bundle(1);
10659        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
10660
10661        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
10662                packageName, extras, 0, null, null, new int[] {userId});
10663        try {
10664            IActivityManager am = ActivityManagerNative.getDefault();
10665            if (isSystem && am.isUserRunning(userId, 0)) {
10666                // The just-installed/enabled app is bundled on the system, so presumed
10667                // to be able to run automatically without needing an explicit launch.
10668                // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
10669                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
10670                        .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
10671                        .setPackage(packageName);
10672                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
10673                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
10674            }
10675        } catch (RemoteException e) {
10676            // shouldn't happen
10677            Slog.w(TAG, "Unable to bootstrap installed package", e);
10678        }
10679    }
10680
10681    @Override
10682    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
10683            int userId) {
10684        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10685        PackageSetting pkgSetting;
10686        final int uid = Binder.getCallingUid();
10687        enforceCrossUserPermission(uid, userId,
10688                true /* requireFullPermission */, true /* checkShell */,
10689                "setApplicationHiddenSetting for user " + userId);
10690
10691        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
10692            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
10693            return false;
10694        }
10695
10696        long callingId = Binder.clearCallingIdentity();
10697        try {
10698            boolean sendAdded = false;
10699            boolean sendRemoved = false;
10700            // writer
10701            synchronized (mPackages) {
10702                pkgSetting = mSettings.mPackages.get(packageName);
10703                if (pkgSetting == null) {
10704                    return false;
10705                }
10706                if (pkgSetting.getHidden(userId) != hidden) {
10707                    pkgSetting.setHidden(hidden, userId);
10708                    mSettings.writePackageRestrictionsLPr(userId);
10709                    if (hidden) {
10710                        sendRemoved = true;
10711                    } else {
10712                        sendAdded = true;
10713                    }
10714                }
10715            }
10716            if (sendAdded) {
10717                sendPackageAddedForUser(packageName, pkgSetting, userId);
10718                return true;
10719            }
10720            if (sendRemoved) {
10721                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
10722                        "hiding pkg");
10723                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
10724                return true;
10725            }
10726        } finally {
10727            Binder.restoreCallingIdentity(callingId);
10728        }
10729        return false;
10730    }
10731
10732    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
10733            int userId) {
10734        final PackageRemovedInfo info = new PackageRemovedInfo();
10735        info.removedPackage = packageName;
10736        info.removedUsers = new int[] {userId};
10737        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
10738        info.sendPackageRemovedBroadcasts(true /*killApp*/);
10739    }
10740
10741    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
10742        if (pkgList.length > 0) {
10743            Bundle extras = new Bundle(1);
10744            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
10745
10746            sendPackageBroadcast(
10747                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
10748                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
10749                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
10750                    new int[] {userId});
10751        }
10752    }
10753
10754    /**
10755     * Returns true if application is not found or there was an error. Otherwise it returns
10756     * the hidden state of the package for the given user.
10757     */
10758    @Override
10759    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
10760        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10761        enforceCrossUserPermission(Binder.getCallingUid(), userId,
10762                true /* requireFullPermission */, false /* checkShell */,
10763                "getApplicationHidden for user " + userId);
10764        PackageSetting pkgSetting;
10765        long callingId = Binder.clearCallingIdentity();
10766        try {
10767            // writer
10768            synchronized (mPackages) {
10769                pkgSetting = mSettings.mPackages.get(packageName);
10770                if (pkgSetting == null) {
10771                    return true;
10772                }
10773                return pkgSetting.getHidden(userId);
10774            }
10775        } finally {
10776            Binder.restoreCallingIdentity(callingId);
10777        }
10778    }
10779
10780    /**
10781     * @hide
10782     */
10783    @Override
10784    public int installExistingPackageAsUser(String packageName, int userId) {
10785        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
10786                null);
10787        PackageSetting pkgSetting;
10788        final int uid = Binder.getCallingUid();
10789        enforceCrossUserPermission(uid, userId,
10790                true /* requireFullPermission */, true /* checkShell */,
10791                "installExistingPackage for user " + userId);
10792        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
10793            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
10794        }
10795
10796        long callingId = Binder.clearCallingIdentity();
10797        try {
10798            boolean installed = false;
10799
10800            // writer
10801            synchronized (mPackages) {
10802                pkgSetting = mSettings.mPackages.get(packageName);
10803                if (pkgSetting == null) {
10804                    return PackageManager.INSTALL_FAILED_INVALID_URI;
10805                }
10806                if (!pkgSetting.getInstalled(userId)) {
10807                    pkgSetting.setInstalled(true, userId);
10808                    pkgSetting.setHidden(false, userId);
10809                    mSettings.writePackageRestrictionsLPr(userId);
10810                    installed = true;
10811                }
10812            }
10813
10814            if (installed) {
10815                if (pkgSetting.pkg != null) {
10816                    prepareAppDataAfterInstall(pkgSetting.pkg);
10817                }
10818                sendPackageAddedForUser(packageName, pkgSetting, userId);
10819            }
10820        } finally {
10821            Binder.restoreCallingIdentity(callingId);
10822        }
10823
10824        return PackageManager.INSTALL_SUCCEEDED;
10825    }
10826
10827    boolean isUserRestricted(int userId, String restrictionKey) {
10828        Bundle restrictions = sUserManager.getUserRestrictions(userId);
10829        if (restrictions.getBoolean(restrictionKey, false)) {
10830            Log.w(TAG, "User is restricted: " + restrictionKey);
10831            return true;
10832        }
10833        return false;
10834    }
10835
10836    @Override
10837    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
10838            int userId) {
10839        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
10840        enforceCrossUserPermission(Binder.getCallingUid(), userId,
10841                true /* requireFullPermission */, true /* checkShell */,
10842                "setPackagesSuspended for user " + userId);
10843
10844        if (ArrayUtils.isEmpty(packageNames)) {
10845            return packageNames;
10846        }
10847
10848        // List of package names for whom the suspended state has changed.
10849        List<String> changedPackages = new ArrayList<>(packageNames.length);
10850        // List of package names for whom the suspended state is not set as requested in this
10851        // method.
10852        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
10853        for (int i = 0; i < packageNames.length; i++) {
10854            String packageName = packageNames[i];
10855            long callingId = Binder.clearCallingIdentity();
10856            try {
10857                boolean changed = false;
10858                final int appId;
10859                synchronized (mPackages) {
10860                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
10861                    if (pkgSetting == null) {
10862                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
10863                                + "\". Skipping suspending/un-suspending.");
10864                        unactionedPackages.add(packageName);
10865                        continue;
10866                    }
10867                    appId = pkgSetting.appId;
10868                    if (pkgSetting.getSuspended(userId) != suspended) {
10869                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
10870                            unactionedPackages.add(packageName);
10871                            continue;
10872                        }
10873                        pkgSetting.setSuspended(suspended, userId);
10874                        mSettings.writePackageRestrictionsLPr(userId);
10875                        changed = true;
10876                        changedPackages.add(packageName);
10877                    }
10878                }
10879
10880                if (changed && suspended) {
10881                    killApplication(packageName, UserHandle.getUid(userId, appId),
10882                            "suspending package");
10883                }
10884            } finally {
10885                Binder.restoreCallingIdentity(callingId);
10886            }
10887        }
10888
10889        if (!changedPackages.isEmpty()) {
10890            sendPackagesSuspendedForUser(changedPackages.toArray(
10891                    new String[changedPackages.size()]), userId, suspended);
10892        }
10893
10894        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
10895    }
10896
10897    @Override
10898    public boolean isPackageSuspendedForUser(String packageName, int userId) {
10899        enforceCrossUserPermission(Binder.getCallingUid(), userId,
10900                true /* requireFullPermission */, false /* checkShell */,
10901                "isPackageSuspendedForUser for user " + userId);
10902        synchronized (mPackages) {
10903            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
10904            if (pkgSetting == null) {
10905                throw new IllegalArgumentException("Unknown target package: " + packageName);
10906            }
10907            return pkgSetting.getSuspended(userId);
10908        }
10909    }
10910
10911    /**
10912     * TODO: cache and disallow blocking the active dialer.
10913     *
10914     * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions
10915     */
10916    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
10917        if (isPackageDeviceAdmin(packageName, userId)) {
10918            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
10919                    + "\": has an active device admin");
10920            return false;
10921        }
10922
10923        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
10924        if (packageName.equals(activeLauncherPackageName)) {
10925            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
10926                    + "\": contains the active launcher");
10927            return false;
10928        }
10929
10930        if (packageName.equals(mRequiredInstallerPackage)) {
10931            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
10932                    + "\": required for package installation");
10933            return false;
10934        }
10935
10936        if (packageName.equals(mRequiredVerifierPackage)) {
10937            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
10938                    + "\": required for package verification");
10939            return false;
10940        }
10941
10942        final PackageParser.Package pkg = mPackages.get(packageName);
10943        if (pkg != null && isPrivilegedApp(pkg)) {
10944            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
10945                    + "\": is a privileged app");
10946            return false;
10947        }
10948
10949        return true;
10950    }
10951
10952    private String getActiveLauncherPackageName(int userId) {
10953        Intent intent = new Intent(Intent.ACTION_MAIN);
10954        intent.addCategory(Intent.CATEGORY_HOME);
10955        ResolveInfo resolveInfo = resolveIntent(
10956                intent,
10957                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
10958                PackageManager.MATCH_DEFAULT_ONLY,
10959                userId);
10960
10961        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
10962    }
10963
10964    @Override
10965    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
10966        mContext.enforceCallingOrSelfPermission(
10967                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10968                "Only package verification agents can verify applications");
10969
10970        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
10971        final PackageVerificationResponse response = new PackageVerificationResponse(
10972                verificationCode, Binder.getCallingUid());
10973        msg.arg1 = id;
10974        msg.obj = response;
10975        mHandler.sendMessage(msg);
10976    }
10977
10978    @Override
10979    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
10980            long millisecondsToDelay) {
10981        mContext.enforceCallingOrSelfPermission(
10982                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
10983                "Only package verification agents can extend verification timeouts");
10984
10985        final PackageVerificationState state = mPendingVerification.get(id);
10986        final PackageVerificationResponse response = new PackageVerificationResponse(
10987                verificationCodeAtTimeout, Binder.getCallingUid());
10988
10989        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
10990            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
10991        }
10992        if (millisecondsToDelay < 0) {
10993            millisecondsToDelay = 0;
10994        }
10995        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
10996                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
10997            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
10998        }
10999
11000        if ((state != null) && !state.timeoutExtended()) {
11001            state.extendTimeout();
11002
11003            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
11004            msg.arg1 = id;
11005            msg.obj = response;
11006            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
11007        }
11008    }
11009
11010    private void broadcastPackageVerified(int verificationId, Uri packageUri,
11011            int verificationCode, UserHandle user) {
11012        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
11013        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
11014        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11015        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11016        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
11017
11018        mContext.sendBroadcastAsUser(intent, user,
11019                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
11020    }
11021
11022    private ComponentName matchComponentForVerifier(String packageName,
11023            List<ResolveInfo> receivers) {
11024        ActivityInfo targetReceiver = null;
11025
11026        final int NR = receivers.size();
11027        for (int i = 0; i < NR; i++) {
11028            final ResolveInfo info = receivers.get(i);
11029            if (info.activityInfo == null) {
11030                continue;
11031            }
11032
11033            if (packageName.equals(info.activityInfo.packageName)) {
11034                targetReceiver = info.activityInfo;
11035                break;
11036            }
11037        }
11038
11039        if (targetReceiver == null) {
11040            return null;
11041        }
11042
11043        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
11044    }
11045
11046    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
11047            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
11048        if (pkgInfo.verifiers.length == 0) {
11049            return null;
11050        }
11051
11052        final int N = pkgInfo.verifiers.length;
11053        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
11054        for (int i = 0; i < N; i++) {
11055            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
11056
11057            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
11058                    receivers);
11059            if (comp == null) {
11060                continue;
11061            }
11062
11063            final int verifierUid = getUidForVerifier(verifierInfo);
11064            if (verifierUid == -1) {
11065                continue;
11066            }
11067
11068            if (DEBUG_VERIFY) {
11069                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
11070                        + " with the correct signature");
11071            }
11072            sufficientVerifiers.add(comp);
11073            verificationState.addSufficientVerifier(verifierUid);
11074        }
11075
11076        return sufficientVerifiers;
11077    }
11078
11079    private int getUidForVerifier(VerifierInfo verifierInfo) {
11080        synchronized (mPackages) {
11081            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
11082            if (pkg == null) {
11083                return -1;
11084            } else if (pkg.mSignatures.length != 1) {
11085                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
11086                        + " has more than one signature; ignoring");
11087                return -1;
11088            }
11089
11090            /*
11091             * If the public key of the package's signature does not match
11092             * our expected public key, then this is a different package and
11093             * we should skip.
11094             */
11095
11096            final byte[] expectedPublicKey;
11097            try {
11098                final Signature verifierSig = pkg.mSignatures[0];
11099                final PublicKey publicKey = verifierSig.getPublicKey();
11100                expectedPublicKey = publicKey.getEncoded();
11101            } catch (CertificateException e) {
11102                return -1;
11103            }
11104
11105            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
11106
11107            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
11108                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
11109                        + " does not have the expected public key; ignoring");
11110                return -1;
11111            }
11112
11113            return pkg.applicationInfo.uid;
11114        }
11115    }
11116
11117    @Override
11118    public void finishPackageInstall(int token) {
11119        enforceSystemOrRoot("Only the system is allowed to finish installs");
11120
11121        if (DEBUG_INSTALL) {
11122            Slog.v(TAG, "BM finishing package install for " + token);
11123        }
11124        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
11125
11126        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
11127        mHandler.sendMessage(msg);
11128    }
11129
11130    /**
11131     * Get the verification agent timeout.
11132     *
11133     * @return verification timeout in milliseconds
11134     */
11135    private long getVerificationTimeout() {
11136        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
11137                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
11138                DEFAULT_VERIFICATION_TIMEOUT);
11139    }
11140
11141    /**
11142     * Get the default verification agent response code.
11143     *
11144     * @return default verification response code
11145     */
11146    private int getDefaultVerificationResponse() {
11147        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11148                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
11149                DEFAULT_VERIFICATION_RESPONSE);
11150    }
11151
11152    /**
11153     * Check whether or not package verification has been enabled.
11154     *
11155     * @return true if verification should be performed
11156     */
11157    private boolean isVerificationEnabled(int userId, int installFlags) {
11158        if (!DEFAULT_VERIFY_ENABLE) {
11159            return false;
11160        }
11161        // Ephemeral apps don't get the full verification treatment
11162        if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
11163            if (DEBUG_EPHEMERAL) {
11164                Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
11165            }
11166            return false;
11167        }
11168
11169        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
11170
11171        // Check if installing from ADB
11172        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
11173            // Do not run verification in a test harness environment
11174            if (ActivityManager.isRunningInTestHarness()) {
11175                return false;
11176            }
11177            if (ensureVerifyAppsEnabled) {
11178                return true;
11179            }
11180            // Check if the developer does not want package verification for ADB installs
11181            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11182                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
11183                return false;
11184            }
11185        }
11186
11187        if (ensureVerifyAppsEnabled) {
11188            return true;
11189        }
11190
11191        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11192                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
11193    }
11194
11195    @Override
11196    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
11197            throws RemoteException {
11198        mContext.enforceCallingOrSelfPermission(
11199                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
11200                "Only intentfilter verification agents can verify applications");
11201
11202        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
11203        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
11204                Binder.getCallingUid(), verificationCode, failedDomains);
11205        msg.arg1 = id;
11206        msg.obj = response;
11207        mHandler.sendMessage(msg);
11208    }
11209
11210    @Override
11211    public int getIntentVerificationStatus(String packageName, int userId) {
11212        synchronized (mPackages) {
11213            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
11214        }
11215    }
11216
11217    @Override
11218    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
11219        mContext.enforceCallingOrSelfPermission(
11220                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11221
11222        boolean result = false;
11223        synchronized (mPackages) {
11224            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
11225        }
11226        if (result) {
11227            scheduleWritePackageRestrictionsLocked(userId);
11228        }
11229        return result;
11230    }
11231
11232    @Override
11233    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
11234            String packageName) {
11235        synchronized (mPackages) {
11236            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
11237        }
11238    }
11239
11240    @Override
11241    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
11242        if (TextUtils.isEmpty(packageName)) {
11243            return ParceledListSlice.emptyList();
11244        }
11245        synchronized (mPackages) {
11246            PackageParser.Package pkg = mPackages.get(packageName);
11247            if (pkg == null || pkg.activities == null) {
11248                return ParceledListSlice.emptyList();
11249            }
11250            final int count = pkg.activities.size();
11251            ArrayList<IntentFilter> result = new ArrayList<>();
11252            for (int n=0; n<count; n++) {
11253                PackageParser.Activity activity = pkg.activities.get(n);
11254                if (activity.intents != null && activity.intents.size() > 0) {
11255                    result.addAll(activity.intents);
11256                }
11257            }
11258            return new ParceledListSlice<>(result);
11259        }
11260    }
11261
11262    @Override
11263    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
11264        mContext.enforceCallingOrSelfPermission(
11265                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
11266
11267        synchronized (mPackages) {
11268            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
11269            if (packageName != null) {
11270                result |= updateIntentVerificationStatus(packageName,
11271                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
11272                        userId);
11273                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
11274                        packageName, userId);
11275            }
11276            return result;
11277        }
11278    }
11279
11280    @Override
11281    public String getDefaultBrowserPackageName(int userId) {
11282        synchronized (mPackages) {
11283            return mSettings.getDefaultBrowserPackageNameLPw(userId);
11284        }
11285    }
11286
11287    /**
11288     * Get the "allow unknown sources" setting.
11289     *
11290     * @return the current "allow unknown sources" setting
11291     */
11292    private int getUnknownSourcesSettings() {
11293        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11294                android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
11295                -1);
11296    }
11297
11298    @Override
11299    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
11300        final int uid = Binder.getCallingUid();
11301        // writer
11302        synchronized (mPackages) {
11303            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
11304            if (targetPackageSetting == null) {
11305                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
11306            }
11307
11308            PackageSetting installerPackageSetting;
11309            if (installerPackageName != null) {
11310                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
11311                if (installerPackageSetting == null) {
11312                    throw new IllegalArgumentException("Unknown installer package: "
11313                            + installerPackageName);
11314                }
11315            } else {
11316                installerPackageSetting = null;
11317            }
11318
11319            Signature[] callerSignature;
11320            Object obj = mSettings.getUserIdLPr(uid);
11321            if (obj != null) {
11322                if (obj instanceof SharedUserSetting) {
11323                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
11324                } else if (obj instanceof PackageSetting) {
11325                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
11326                } else {
11327                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
11328                }
11329            } else {
11330                throw new SecurityException("Unknown calling UID: " + uid);
11331            }
11332
11333            // Verify: can't set installerPackageName to a package that is
11334            // not signed with the same cert as the caller.
11335            if (installerPackageSetting != null) {
11336                if (compareSignatures(callerSignature,
11337                        installerPackageSetting.signatures.mSignatures)
11338                        != PackageManager.SIGNATURE_MATCH) {
11339                    throw new SecurityException(
11340                            "Caller does not have same cert as new installer package "
11341                            + installerPackageName);
11342                }
11343            }
11344
11345            // Verify: if target already has an installer package, it must
11346            // be signed with the same cert as the caller.
11347            if (targetPackageSetting.installerPackageName != null) {
11348                PackageSetting setting = mSettings.mPackages.get(
11349                        targetPackageSetting.installerPackageName);
11350                // If the currently set package isn't valid, then it's always
11351                // okay to change it.
11352                if (setting != null) {
11353                    if (compareSignatures(callerSignature,
11354                            setting.signatures.mSignatures)
11355                            != PackageManager.SIGNATURE_MATCH) {
11356                        throw new SecurityException(
11357                                "Caller does not have same cert as old installer package "
11358                                + targetPackageSetting.installerPackageName);
11359                    }
11360                }
11361            }
11362
11363            // Okay!
11364            targetPackageSetting.installerPackageName = installerPackageName;
11365            scheduleWriteSettingsLocked();
11366        }
11367    }
11368
11369    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
11370        // Queue up an async operation since the package installation may take a little while.
11371        mHandler.post(new Runnable() {
11372            public void run() {
11373                mHandler.removeCallbacks(this);
11374                 // Result object to be returned
11375                PackageInstalledInfo res = new PackageInstalledInfo();
11376                res.setReturnCode(currentStatus);
11377                res.uid = -1;
11378                res.pkg = null;
11379                res.removedInfo = null;
11380                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
11381                    args.doPreInstall(res.returnCode);
11382                    synchronized (mInstallLock) {
11383                        installPackageTracedLI(args, res);
11384                    }
11385                    args.doPostInstall(res.returnCode, res.uid);
11386                }
11387
11388                // A restore should be performed at this point if (a) the install
11389                // succeeded, (b) the operation is not an update, and (c) the new
11390                // package has not opted out of backup participation.
11391                final boolean update = res.removedInfo != null
11392                        && res.removedInfo.removedPackage != null;
11393                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
11394                boolean doRestore = !update
11395                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
11396
11397                // Set up the post-install work request bookkeeping.  This will be used
11398                // and cleaned up by the post-install event handling regardless of whether
11399                // there's a restore pass performed.  Token values are >= 1.
11400                int token;
11401                if (mNextInstallToken < 0) mNextInstallToken = 1;
11402                token = mNextInstallToken++;
11403
11404                PostInstallData data = new PostInstallData(args, res);
11405                mRunningInstalls.put(token, data);
11406                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
11407
11408                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
11409                    // Pass responsibility to the Backup Manager.  It will perform a
11410                    // restore if appropriate, then pass responsibility back to the
11411                    // Package Manager to run the post-install observer callbacks
11412                    // and broadcasts.
11413                    IBackupManager bm = IBackupManager.Stub.asInterface(
11414                            ServiceManager.getService(Context.BACKUP_SERVICE));
11415                    if (bm != null) {
11416                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
11417                                + " to BM for possible restore");
11418                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
11419                        try {
11420                            // TODO: http://b/22388012
11421                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
11422                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
11423                            } else {
11424                                doRestore = false;
11425                            }
11426                        } catch (RemoteException e) {
11427                            // can't happen; the backup manager is local
11428                        } catch (Exception e) {
11429                            Slog.e(TAG, "Exception trying to enqueue restore", e);
11430                            doRestore = false;
11431                        }
11432                    } else {
11433                        Slog.e(TAG, "Backup Manager not found!");
11434                        doRestore = false;
11435                    }
11436                }
11437
11438                if (!doRestore) {
11439                    // No restore possible, or the Backup Manager was mysteriously not
11440                    // available -- just fire the post-install work request directly.
11441                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
11442
11443                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
11444
11445                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
11446                    mHandler.sendMessage(msg);
11447                }
11448            }
11449        });
11450    }
11451
11452    private abstract class HandlerParams {
11453        private static final int MAX_RETRIES = 4;
11454
11455        /**
11456         * Number of times startCopy() has been attempted and had a non-fatal
11457         * error.
11458         */
11459        private int mRetries = 0;
11460
11461        /** User handle for the user requesting the information or installation. */
11462        private final UserHandle mUser;
11463        String traceMethod;
11464        int traceCookie;
11465
11466        HandlerParams(UserHandle user) {
11467            mUser = user;
11468        }
11469
11470        UserHandle getUser() {
11471            return mUser;
11472        }
11473
11474        HandlerParams setTraceMethod(String traceMethod) {
11475            this.traceMethod = traceMethod;
11476            return this;
11477        }
11478
11479        HandlerParams setTraceCookie(int traceCookie) {
11480            this.traceCookie = traceCookie;
11481            return this;
11482        }
11483
11484        final boolean startCopy() {
11485            boolean res;
11486            try {
11487                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
11488
11489                if (++mRetries > MAX_RETRIES) {
11490                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
11491                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
11492                    handleServiceError();
11493                    return false;
11494                } else {
11495                    handleStartCopy();
11496                    res = true;
11497                }
11498            } catch (RemoteException e) {
11499                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
11500                mHandler.sendEmptyMessage(MCS_RECONNECT);
11501                res = false;
11502            }
11503            handleReturnCode();
11504            return res;
11505        }
11506
11507        final void serviceError() {
11508            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
11509            handleServiceError();
11510            handleReturnCode();
11511        }
11512
11513        abstract void handleStartCopy() throws RemoteException;
11514        abstract void handleServiceError();
11515        abstract void handleReturnCode();
11516    }
11517
11518    class MeasureParams extends HandlerParams {
11519        private final PackageStats mStats;
11520        private boolean mSuccess;
11521
11522        private final IPackageStatsObserver mObserver;
11523
11524        public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
11525            super(new UserHandle(stats.userHandle));
11526            mObserver = observer;
11527            mStats = stats;
11528        }
11529
11530        @Override
11531        public String toString() {
11532            return "MeasureParams{"
11533                + Integer.toHexString(System.identityHashCode(this))
11534                + " " + mStats.packageName + "}";
11535        }
11536
11537        @Override
11538        void handleStartCopy() throws RemoteException {
11539            synchronized (mInstallLock) {
11540                mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
11541            }
11542
11543            if (mSuccess) {
11544                final boolean mounted;
11545                if (Environment.isExternalStorageEmulated()) {
11546                    mounted = true;
11547                } else {
11548                    final String status = Environment.getExternalStorageState();
11549                    mounted = (Environment.MEDIA_MOUNTED.equals(status)
11550                            || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
11551                }
11552
11553                if (mounted) {
11554                    final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
11555
11556                    mStats.externalCacheSize = calculateDirectorySize(mContainerService,
11557                            userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
11558
11559                    mStats.externalDataSize = calculateDirectorySize(mContainerService,
11560                            userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
11561
11562                    // Always subtract cache size, since it's a subdirectory
11563                    mStats.externalDataSize -= mStats.externalCacheSize;
11564
11565                    mStats.externalMediaSize = calculateDirectorySize(mContainerService,
11566                            userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
11567
11568                    mStats.externalObbSize = calculateDirectorySize(mContainerService,
11569                            userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
11570                }
11571            }
11572        }
11573
11574        @Override
11575        void handleReturnCode() {
11576            if (mObserver != null) {
11577                try {
11578                    mObserver.onGetStatsCompleted(mStats, mSuccess);
11579                } catch (RemoteException e) {
11580                    Slog.i(TAG, "Observer no longer exists.");
11581                }
11582            }
11583        }
11584
11585        @Override
11586        void handleServiceError() {
11587            Slog.e(TAG, "Could not measure application " + mStats.packageName
11588                            + " external storage");
11589        }
11590    }
11591
11592    private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
11593            throws RemoteException {
11594        long result = 0;
11595        for (File path : paths) {
11596            result += mcs.calculateDirectorySize(path.getAbsolutePath());
11597        }
11598        return result;
11599    }
11600
11601    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
11602        for (File path : paths) {
11603            try {
11604                mcs.clearDirectory(path.getAbsolutePath());
11605            } catch (RemoteException e) {
11606            }
11607        }
11608    }
11609
11610    static class OriginInfo {
11611        /**
11612         * Location where install is coming from, before it has been
11613         * copied/renamed into place. This could be a single monolithic APK
11614         * file, or a cluster directory. This location may be untrusted.
11615         */
11616        final File file;
11617        final String cid;
11618
11619        /**
11620         * Flag indicating that {@link #file} or {@link #cid} has already been
11621         * staged, meaning downstream users don't need to defensively copy the
11622         * contents.
11623         */
11624        final boolean staged;
11625
11626        /**
11627         * Flag indicating that {@link #file} or {@link #cid} is an already
11628         * installed app that is being moved.
11629         */
11630        final boolean existing;
11631
11632        final String resolvedPath;
11633        final File resolvedFile;
11634
11635        static OriginInfo fromNothing() {
11636            return new OriginInfo(null, null, false, false);
11637        }
11638
11639        static OriginInfo fromUntrustedFile(File file) {
11640            return new OriginInfo(file, null, false, false);
11641        }
11642
11643        static OriginInfo fromExistingFile(File file) {
11644            return new OriginInfo(file, null, false, true);
11645        }
11646
11647        static OriginInfo fromStagedFile(File file) {
11648            return new OriginInfo(file, null, true, false);
11649        }
11650
11651        static OriginInfo fromStagedContainer(String cid) {
11652            return new OriginInfo(null, cid, true, false);
11653        }
11654
11655        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
11656            this.file = file;
11657            this.cid = cid;
11658            this.staged = staged;
11659            this.existing = existing;
11660
11661            if (cid != null) {
11662                resolvedPath = PackageHelper.getSdDir(cid);
11663                resolvedFile = new File(resolvedPath);
11664            } else if (file != null) {
11665                resolvedPath = file.getAbsolutePath();
11666                resolvedFile = file;
11667            } else {
11668                resolvedPath = null;
11669                resolvedFile = null;
11670            }
11671        }
11672    }
11673
11674    static class MoveInfo {
11675        final int moveId;
11676        final String fromUuid;
11677        final String toUuid;
11678        final String packageName;
11679        final String dataAppName;
11680        final int appId;
11681        final String seinfo;
11682        final int targetSdkVersion;
11683
11684        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
11685                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
11686            this.moveId = moveId;
11687            this.fromUuid = fromUuid;
11688            this.toUuid = toUuid;
11689            this.packageName = packageName;
11690            this.dataAppName = dataAppName;
11691            this.appId = appId;
11692            this.seinfo = seinfo;
11693            this.targetSdkVersion = targetSdkVersion;
11694        }
11695    }
11696
11697    static class VerificationInfo {
11698        /** A constant used to indicate that a uid value is not present. */
11699        public static final int NO_UID = -1;
11700
11701        /** URI referencing where the package was downloaded from. */
11702        final Uri originatingUri;
11703
11704        /** HTTP referrer URI associated with the originatingURI. */
11705        final Uri referrer;
11706
11707        /** UID of the application that the install request originated from. */
11708        final int originatingUid;
11709
11710        /** UID of application requesting the install */
11711        final int installerUid;
11712
11713        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
11714            this.originatingUri = originatingUri;
11715            this.referrer = referrer;
11716            this.originatingUid = originatingUid;
11717            this.installerUid = installerUid;
11718        }
11719    }
11720
11721    class InstallParams extends HandlerParams {
11722        final OriginInfo origin;
11723        final MoveInfo move;
11724        final IPackageInstallObserver2 observer;
11725        int installFlags;
11726        final String installerPackageName;
11727        final String volumeUuid;
11728        private InstallArgs mArgs;
11729        private int mRet;
11730        final String packageAbiOverride;
11731        final String[] grantedRuntimePermissions;
11732        final VerificationInfo verificationInfo;
11733
11734        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
11735                int installFlags, String installerPackageName, String volumeUuid,
11736                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
11737                String[] grantedPermissions) {
11738            super(user);
11739            this.origin = origin;
11740            this.move = move;
11741            this.observer = observer;
11742            this.installFlags = installFlags;
11743            this.installerPackageName = installerPackageName;
11744            this.volumeUuid = volumeUuid;
11745            this.verificationInfo = verificationInfo;
11746            this.packageAbiOverride = packageAbiOverride;
11747            this.grantedRuntimePermissions = grantedPermissions;
11748        }
11749
11750        @Override
11751        public String toString() {
11752            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
11753                    + " file=" + origin.file + " cid=" + origin.cid + "}";
11754        }
11755
11756        private int installLocationPolicy(PackageInfoLite pkgLite) {
11757            String packageName = pkgLite.packageName;
11758            int installLocation = pkgLite.installLocation;
11759            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11760            // reader
11761            synchronized (mPackages) {
11762                // Currently installed package which the new package is attempting to replace or
11763                // null if no such package is installed.
11764                PackageParser.Package installedPkg = mPackages.get(packageName);
11765                // Package which currently owns the data which the new package will own if installed.
11766                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
11767                // will be null whereas dataOwnerPkg will contain information about the package
11768                // which was uninstalled while keeping its data.
11769                PackageParser.Package dataOwnerPkg = installedPkg;
11770                if (dataOwnerPkg  == null) {
11771                    PackageSetting ps = mSettings.mPackages.get(packageName);
11772                    if (ps != null) {
11773                        dataOwnerPkg = ps.pkg;
11774                    }
11775                }
11776
11777                if (dataOwnerPkg != null) {
11778                    // If installed, the package will get access to data left on the device by its
11779                    // predecessor. As a security measure, this is permited only if this is not a
11780                    // version downgrade or if the predecessor package is marked as debuggable and
11781                    // a downgrade is explicitly requested.
11782                    if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0)
11783                            || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) {
11784                        try {
11785                            checkDowngrade(dataOwnerPkg, pkgLite);
11786                        } catch (PackageManagerException e) {
11787                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
11788                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
11789                        }
11790                    }
11791                }
11792
11793                if (installedPkg != null) {
11794                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
11795                        // Check for updated system application.
11796                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11797                            if (onSd) {
11798                                Slog.w(TAG, "Cannot install update to system app on sdcard");
11799                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
11800                            }
11801                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11802                        } else {
11803                            if (onSd) {
11804                                // Install flag overrides everything.
11805                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11806                            }
11807                            // If current upgrade specifies particular preference
11808                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
11809                                // Application explicitly specified internal.
11810                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11811                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
11812                                // App explictly prefers external. Let policy decide
11813                            } else {
11814                                // Prefer previous location
11815                                if (isExternal(installedPkg)) {
11816                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11817                                }
11818                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
11819                            }
11820                        }
11821                    } else {
11822                        // Invalid install. Return error code
11823                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
11824                    }
11825                }
11826            }
11827            // All the special cases have been taken care of.
11828            // Return result based on recommended install location.
11829            if (onSd) {
11830                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
11831            }
11832            return pkgLite.recommendedInstallLocation;
11833        }
11834
11835        /*
11836         * Invoke remote method to get package information and install
11837         * location values. Override install location based on default
11838         * policy if needed and then create install arguments based
11839         * on the install location.
11840         */
11841        public void handleStartCopy() throws RemoteException {
11842            int ret = PackageManager.INSTALL_SUCCEEDED;
11843
11844            // If we're already staged, we've firmly committed to an install location
11845            if (origin.staged) {
11846                if (origin.file != null) {
11847                    installFlags |= PackageManager.INSTALL_INTERNAL;
11848                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11849                } else if (origin.cid != null) {
11850                    installFlags |= PackageManager.INSTALL_EXTERNAL;
11851                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
11852                } else {
11853                    throw new IllegalStateException("Invalid stage location");
11854                }
11855            }
11856
11857            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
11858            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
11859            final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
11860            PackageInfoLite pkgLite = null;
11861
11862            if (onInt && onSd) {
11863                // Check if both bits are set.
11864                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
11865                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11866            } else if (onSd && ephemeral) {
11867                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
11868                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11869            } else {
11870                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
11871                        packageAbiOverride);
11872
11873                if (DEBUG_EPHEMERAL && ephemeral) {
11874                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
11875                }
11876
11877                /*
11878                 * If we have too little free space, try to free cache
11879                 * before giving up.
11880                 */
11881                if (!origin.staged && pkgLite.recommendedInstallLocation
11882                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11883                    // TODO: focus freeing disk space on the target device
11884                    final StorageManager storage = StorageManager.from(mContext);
11885                    final long lowThreshold = storage.getStorageLowBytes(
11886                            Environment.getDataDirectory());
11887
11888                    final long sizeBytes = mContainerService.calculateInstalledSize(
11889                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
11890
11891                    try {
11892                        mInstaller.freeCache(null, sizeBytes + lowThreshold);
11893                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
11894                                installFlags, packageAbiOverride);
11895                    } catch (InstallerException e) {
11896                        Slog.w(TAG, "Failed to free cache", e);
11897                    }
11898
11899                    /*
11900                     * The cache free must have deleted the file we
11901                     * downloaded to install.
11902                     *
11903                     * TODO: fix the "freeCache" call to not delete
11904                     *       the file we care about.
11905                     */
11906                    if (pkgLite.recommendedInstallLocation
11907                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11908                        pkgLite.recommendedInstallLocation
11909                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
11910                    }
11911                }
11912            }
11913
11914            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11915                int loc = pkgLite.recommendedInstallLocation;
11916                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
11917                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
11918                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
11919                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
11920                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
11921                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
11922                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
11923                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
11924                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
11925                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
11926                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
11927                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
11928                } else {
11929                    // Override with defaults if needed.
11930                    loc = installLocationPolicy(pkgLite);
11931                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
11932                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
11933                    } else if (!onSd && !onInt) {
11934                        // Override install location with flags
11935                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
11936                            // Set the flag to install on external media.
11937                            installFlags |= PackageManager.INSTALL_EXTERNAL;
11938                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
11939                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
11940                            if (DEBUG_EPHEMERAL) {
11941                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
11942                            }
11943                            installFlags |= PackageManager.INSTALL_EPHEMERAL;
11944                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
11945                                    |PackageManager.INSTALL_INTERNAL);
11946                        } else {
11947                            // Make sure the flag for installing on external
11948                            // media is unset
11949                            installFlags |= PackageManager.INSTALL_INTERNAL;
11950                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
11951                        }
11952                    }
11953                }
11954            }
11955
11956            final InstallArgs args = createInstallArgs(this);
11957            mArgs = args;
11958
11959            if (ret == PackageManager.INSTALL_SUCCEEDED) {
11960                // TODO: http://b/22976637
11961                // Apps installed for "all" users use the device owner to verify the app
11962                UserHandle verifierUser = getUser();
11963                if (verifierUser == UserHandle.ALL) {
11964                    verifierUser = UserHandle.SYSTEM;
11965                }
11966
11967                /*
11968                 * Determine if we have any installed package verifiers. If we
11969                 * do, then we'll defer to them to verify the packages.
11970                 */
11971                final int requiredUid = mRequiredVerifierPackage == null ? -1
11972                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
11973                                verifierUser.getIdentifier());
11974                if (!origin.existing && requiredUid != -1
11975                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
11976                    final Intent verification = new Intent(
11977                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
11978                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11979                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
11980                            PACKAGE_MIME_TYPE);
11981                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
11982
11983                    // Query all live verifiers based on current user state
11984                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
11985                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
11986
11987                    if (DEBUG_VERIFY) {
11988                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
11989                                + verification.toString() + " with " + pkgLite.verifiers.length
11990                                + " optional verifiers");
11991                    }
11992
11993                    final int verificationId = mPendingVerificationToken++;
11994
11995                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
11996
11997                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
11998                            installerPackageName);
11999
12000                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
12001                            installFlags);
12002
12003                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
12004                            pkgLite.packageName);
12005
12006                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
12007                            pkgLite.versionCode);
12008
12009                    if (verificationInfo != null) {
12010                        if (verificationInfo.originatingUri != null) {
12011                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
12012                                    verificationInfo.originatingUri);
12013                        }
12014                        if (verificationInfo.referrer != null) {
12015                            verification.putExtra(Intent.EXTRA_REFERRER,
12016                                    verificationInfo.referrer);
12017                        }
12018                        if (verificationInfo.originatingUid >= 0) {
12019                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
12020                                    verificationInfo.originatingUid);
12021                        }
12022                        if (verificationInfo.installerUid >= 0) {
12023                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
12024                                    verificationInfo.installerUid);
12025                        }
12026                    }
12027
12028                    final PackageVerificationState verificationState = new PackageVerificationState(
12029                            requiredUid, args);
12030
12031                    mPendingVerification.append(verificationId, verificationState);
12032
12033                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
12034                            receivers, verificationState);
12035
12036                    /*
12037                     * If any sufficient verifiers were listed in the package
12038                     * manifest, attempt to ask them.
12039                     */
12040                    if (sufficientVerifiers != null) {
12041                        final int N = sufficientVerifiers.size();
12042                        if (N == 0) {
12043                            Slog.i(TAG, "Additional verifiers required, but none installed.");
12044                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
12045                        } else {
12046                            for (int i = 0; i < N; i++) {
12047                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
12048
12049                                final Intent sufficientIntent = new Intent(verification);
12050                                sufficientIntent.setComponent(verifierComponent);
12051                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
12052                            }
12053                        }
12054                    }
12055
12056                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
12057                            mRequiredVerifierPackage, receivers);
12058                    if (ret == PackageManager.INSTALL_SUCCEEDED
12059                            && mRequiredVerifierPackage != null) {
12060                        Trace.asyncTraceBegin(
12061                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
12062                        /*
12063                         * Send the intent to the required verification agent,
12064                         * but only start the verification timeout after the
12065                         * target BroadcastReceivers have run.
12066                         */
12067                        verification.setComponent(requiredVerifierComponent);
12068                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
12069                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
12070                                new BroadcastReceiver() {
12071                                    @Override
12072                                    public void onReceive(Context context, Intent intent) {
12073                                        final Message msg = mHandler
12074                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
12075                                        msg.arg1 = verificationId;
12076                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
12077                                    }
12078                                }, null, 0, null, null);
12079
12080                        /*
12081                         * We don't want the copy to proceed until verification
12082                         * succeeds, so null out this field.
12083                         */
12084                        mArgs = null;
12085                    }
12086                } else {
12087                    /*
12088                     * No package verification is enabled, so immediately start
12089                     * the remote call to initiate copy using temporary file.
12090                     */
12091                    ret = args.copyApk(mContainerService, true);
12092                }
12093            }
12094
12095            mRet = ret;
12096        }
12097
12098        @Override
12099        void handleReturnCode() {
12100            // If mArgs is null, then MCS couldn't be reached. When it
12101            // reconnects, it will try again to install. At that point, this
12102            // will succeed.
12103            if (mArgs != null) {
12104                processPendingInstall(mArgs, mRet);
12105            }
12106        }
12107
12108        @Override
12109        void handleServiceError() {
12110            mArgs = createInstallArgs(this);
12111            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12112        }
12113
12114        public boolean isForwardLocked() {
12115            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
12116        }
12117    }
12118
12119    /**
12120     * Used during creation of InstallArgs
12121     *
12122     * @param installFlags package installation flags
12123     * @return true if should be installed on external storage
12124     */
12125    private static boolean installOnExternalAsec(int installFlags) {
12126        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
12127            return false;
12128        }
12129        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
12130            return true;
12131        }
12132        return false;
12133    }
12134
12135    /**
12136     * Used during creation of InstallArgs
12137     *
12138     * @param installFlags package installation flags
12139     * @return true if should be installed as forward locked
12140     */
12141    private static boolean installForwardLocked(int installFlags) {
12142        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
12143    }
12144
12145    private InstallArgs createInstallArgs(InstallParams params) {
12146        if (params.move != null) {
12147            return new MoveInstallArgs(params);
12148        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
12149            return new AsecInstallArgs(params);
12150        } else {
12151            return new FileInstallArgs(params);
12152        }
12153    }
12154
12155    /**
12156     * Create args that describe an existing installed package. Typically used
12157     * when cleaning up old installs, or used as a move source.
12158     */
12159    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
12160            String resourcePath, String[] instructionSets) {
12161        final boolean isInAsec;
12162        if (installOnExternalAsec(installFlags)) {
12163            /* Apps on SD card are always in ASEC containers. */
12164            isInAsec = true;
12165        } else if (installForwardLocked(installFlags)
12166                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
12167            /*
12168             * Forward-locked apps are only in ASEC containers if they're the
12169             * new style
12170             */
12171            isInAsec = true;
12172        } else {
12173            isInAsec = false;
12174        }
12175
12176        if (isInAsec) {
12177            return new AsecInstallArgs(codePath, instructionSets,
12178                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
12179        } else {
12180            return new FileInstallArgs(codePath, resourcePath, instructionSets);
12181        }
12182    }
12183
12184    static abstract class InstallArgs {
12185        /** @see InstallParams#origin */
12186        final OriginInfo origin;
12187        /** @see InstallParams#move */
12188        final MoveInfo move;
12189
12190        final IPackageInstallObserver2 observer;
12191        // Always refers to PackageManager flags only
12192        final int installFlags;
12193        final String installerPackageName;
12194        final String volumeUuid;
12195        final UserHandle user;
12196        final String abiOverride;
12197        final String[] installGrantPermissions;
12198        /** If non-null, drop an async trace when the install completes */
12199        final String traceMethod;
12200        final int traceCookie;
12201
12202        // The list of instruction sets supported by this app. This is currently
12203        // only used during the rmdex() phase to clean up resources. We can get rid of this
12204        // if we move dex files under the common app path.
12205        /* nullable */ String[] instructionSets;
12206
12207        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
12208                int installFlags, String installerPackageName, String volumeUuid,
12209                UserHandle user, String[] instructionSets,
12210                String abiOverride, String[] installGrantPermissions,
12211                String traceMethod, int traceCookie) {
12212            this.origin = origin;
12213            this.move = move;
12214            this.installFlags = installFlags;
12215            this.observer = observer;
12216            this.installerPackageName = installerPackageName;
12217            this.volumeUuid = volumeUuid;
12218            this.user = user;
12219            this.instructionSets = instructionSets;
12220            this.abiOverride = abiOverride;
12221            this.installGrantPermissions = installGrantPermissions;
12222            this.traceMethod = traceMethod;
12223            this.traceCookie = traceCookie;
12224        }
12225
12226        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
12227        abstract int doPreInstall(int status);
12228
12229        /**
12230         * Rename package into final resting place. All paths on the given
12231         * scanned package should be updated to reflect the rename.
12232         */
12233        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
12234        abstract int doPostInstall(int status, int uid);
12235
12236        /** @see PackageSettingBase#codePathString */
12237        abstract String getCodePath();
12238        /** @see PackageSettingBase#resourcePathString */
12239        abstract String getResourcePath();
12240
12241        // Need installer lock especially for dex file removal.
12242        abstract void cleanUpResourcesLI();
12243        abstract boolean doPostDeleteLI(boolean delete);
12244
12245        /**
12246         * Called before the source arguments are copied. This is used mostly
12247         * for MoveParams when it needs to read the source file to put it in the
12248         * destination.
12249         */
12250        int doPreCopy() {
12251            return PackageManager.INSTALL_SUCCEEDED;
12252        }
12253
12254        /**
12255         * Called after the source arguments are copied. This is used mostly for
12256         * MoveParams when it needs to read the source file to put it in the
12257         * destination.
12258         *
12259         * @return
12260         */
12261        int doPostCopy(int uid) {
12262            return PackageManager.INSTALL_SUCCEEDED;
12263        }
12264
12265        protected boolean isFwdLocked() {
12266            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
12267        }
12268
12269        protected boolean isExternalAsec() {
12270            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
12271        }
12272
12273        protected boolean isEphemeral() {
12274            return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
12275        }
12276
12277        UserHandle getUser() {
12278            return user;
12279        }
12280    }
12281
12282    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
12283        if (!allCodePaths.isEmpty()) {
12284            if (instructionSets == null) {
12285                throw new IllegalStateException("instructionSet == null");
12286            }
12287            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
12288            for (String codePath : allCodePaths) {
12289                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
12290                    try {
12291                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
12292                    } catch (InstallerException ignored) {
12293                    }
12294                }
12295            }
12296        }
12297    }
12298
12299    /**
12300     * Logic to handle installation of non-ASEC applications, including copying
12301     * and renaming logic.
12302     */
12303    class FileInstallArgs extends InstallArgs {
12304        private File codeFile;
12305        private File resourceFile;
12306
12307        // Example topology:
12308        // /data/app/com.example/base.apk
12309        // /data/app/com.example/split_foo.apk
12310        // /data/app/com.example/lib/arm/libfoo.so
12311        // /data/app/com.example/lib/arm64/libfoo.so
12312        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
12313
12314        /** New install */
12315        FileInstallArgs(InstallParams params) {
12316            super(params.origin, params.move, params.observer, params.installFlags,
12317                    params.installerPackageName, params.volumeUuid,
12318                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12319                    params.grantedRuntimePermissions,
12320                    params.traceMethod, params.traceCookie);
12321            if (isFwdLocked()) {
12322                throw new IllegalArgumentException("Forward locking only supported in ASEC");
12323            }
12324        }
12325
12326        /** Existing install */
12327        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
12328            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
12329                    null, null, null, 0);
12330            this.codeFile = (codePath != null) ? new File(codePath) : null;
12331            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
12332        }
12333
12334        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
12335            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
12336            try {
12337                return doCopyApk(imcs, temp);
12338            } finally {
12339                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12340            }
12341        }
12342
12343        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
12344            if (origin.staged) {
12345                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
12346                codeFile = origin.file;
12347                resourceFile = origin.file;
12348                return PackageManager.INSTALL_SUCCEEDED;
12349            }
12350
12351            try {
12352                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
12353                final File tempDir =
12354                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
12355                codeFile = tempDir;
12356                resourceFile = tempDir;
12357            } catch (IOException e) {
12358                Slog.w(TAG, "Failed to create copy file: " + e);
12359                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
12360            }
12361
12362            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
12363                @Override
12364                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
12365                    if (!FileUtils.isValidExtFilename(name)) {
12366                        throw new IllegalArgumentException("Invalid filename: " + name);
12367                    }
12368                    try {
12369                        final File file = new File(codeFile, name);
12370                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
12371                                O_RDWR | O_CREAT, 0644);
12372                        Os.chmod(file.getAbsolutePath(), 0644);
12373                        return new ParcelFileDescriptor(fd);
12374                    } catch (ErrnoException e) {
12375                        throw new RemoteException("Failed to open: " + e.getMessage());
12376                    }
12377                }
12378            };
12379
12380            int ret = PackageManager.INSTALL_SUCCEEDED;
12381            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
12382            if (ret != PackageManager.INSTALL_SUCCEEDED) {
12383                Slog.e(TAG, "Failed to copy package");
12384                return ret;
12385            }
12386
12387            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
12388            NativeLibraryHelper.Handle handle = null;
12389            try {
12390                handle = NativeLibraryHelper.Handle.create(codeFile);
12391                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
12392                        abiOverride);
12393            } catch (IOException e) {
12394                Slog.e(TAG, "Copying native libraries failed", e);
12395                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12396            } finally {
12397                IoUtils.closeQuietly(handle);
12398            }
12399
12400            return ret;
12401        }
12402
12403        int doPreInstall(int status) {
12404            if (status != PackageManager.INSTALL_SUCCEEDED) {
12405                cleanUp();
12406            }
12407            return status;
12408        }
12409
12410        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12411            if (status != PackageManager.INSTALL_SUCCEEDED) {
12412                cleanUp();
12413                return false;
12414            }
12415
12416            final File targetDir = codeFile.getParentFile();
12417            final File beforeCodeFile = codeFile;
12418            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
12419
12420            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
12421            try {
12422                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
12423            } catch (ErrnoException e) {
12424                Slog.w(TAG, "Failed to rename", e);
12425                return false;
12426            }
12427
12428            if (!SELinux.restoreconRecursive(afterCodeFile)) {
12429                Slog.w(TAG, "Failed to restorecon");
12430                return false;
12431            }
12432
12433            // Reflect the rename internally
12434            codeFile = afterCodeFile;
12435            resourceFile = afterCodeFile;
12436
12437            // Reflect the rename in scanned details
12438            pkg.setCodePath(afterCodeFile.getAbsolutePath());
12439            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
12440                    afterCodeFile, pkg.baseCodePath));
12441            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
12442                    afterCodeFile, pkg.splitCodePaths));
12443
12444            // Reflect the rename in app info
12445            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
12446            pkg.setApplicationInfoCodePath(pkg.codePath);
12447            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
12448            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
12449            pkg.setApplicationInfoResourcePath(pkg.codePath);
12450            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
12451            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
12452
12453            return true;
12454        }
12455
12456        int doPostInstall(int status, int uid) {
12457            if (status != PackageManager.INSTALL_SUCCEEDED) {
12458                cleanUp();
12459            }
12460            return status;
12461        }
12462
12463        @Override
12464        String getCodePath() {
12465            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
12466        }
12467
12468        @Override
12469        String getResourcePath() {
12470            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
12471        }
12472
12473        private boolean cleanUp() {
12474            if (codeFile == null || !codeFile.exists()) {
12475                return false;
12476            }
12477
12478            removeCodePathLI(codeFile);
12479
12480            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
12481                resourceFile.delete();
12482            }
12483
12484            return true;
12485        }
12486
12487        void cleanUpResourcesLI() {
12488            // Try enumerating all code paths before deleting
12489            List<String> allCodePaths = Collections.EMPTY_LIST;
12490            if (codeFile != null && codeFile.exists()) {
12491                try {
12492                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
12493                    allCodePaths = pkg.getAllCodePaths();
12494                } catch (PackageParserException e) {
12495                    // Ignored; we tried our best
12496                }
12497            }
12498
12499            cleanUp();
12500            removeDexFiles(allCodePaths, instructionSets);
12501        }
12502
12503        boolean doPostDeleteLI(boolean delete) {
12504            // XXX err, shouldn't we respect the delete flag?
12505            cleanUpResourcesLI();
12506            return true;
12507        }
12508    }
12509
12510    private boolean isAsecExternal(String cid) {
12511        final String asecPath = PackageHelper.getSdFilesystem(cid);
12512        return !asecPath.startsWith(mAsecInternalPath);
12513    }
12514
12515    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
12516            PackageManagerException {
12517        if (copyRet < 0) {
12518            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
12519                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
12520                throw new PackageManagerException(copyRet, message);
12521            }
12522        }
12523    }
12524
12525    /**
12526     * Extract the MountService "container ID" from the full code path of an
12527     * .apk.
12528     */
12529    static String cidFromCodePath(String fullCodePath) {
12530        int eidx = fullCodePath.lastIndexOf("/");
12531        String subStr1 = fullCodePath.substring(0, eidx);
12532        int sidx = subStr1.lastIndexOf("/");
12533        return subStr1.substring(sidx+1, eidx);
12534    }
12535
12536    /**
12537     * Logic to handle installation of ASEC applications, including copying and
12538     * renaming logic.
12539     */
12540    class AsecInstallArgs extends InstallArgs {
12541        static final String RES_FILE_NAME = "pkg.apk";
12542        static final String PUBLIC_RES_FILE_NAME = "res.zip";
12543
12544        String cid;
12545        String packagePath;
12546        String resourcePath;
12547
12548        /** New install */
12549        AsecInstallArgs(InstallParams params) {
12550            super(params.origin, params.move, params.observer, params.installFlags,
12551                    params.installerPackageName, params.volumeUuid,
12552                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12553                    params.grantedRuntimePermissions,
12554                    params.traceMethod, params.traceCookie);
12555        }
12556
12557        /** Existing install */
12558        AsecInstallArgs(String fullCodePath, String[] instructionSets,
12559                        boolean isExternal, boolean isForwardLocked) {
12560            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
12561                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
12562                    instructionSets, null, null, null, 0);
12563            // Hackily pretend we're still looking at a full code path
12564            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
12565                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
12566            }
12567
12568            // Extract cid from fullCodePath
12569            int eidx = fullCodePath.lastIndexOf("/");
12570            String subStr1 = fullCodePath.substring(0, eidx);
12571            int sidx = subStr1.lastIndexOf("/");
12572            cid = subStr1.substring(sidx+1, eidx);
12573            setMountPath(subStr1);
12574        }
12575
12576        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
12577            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
12578                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
12579                    instructionSets, null, null, null, 0);
12580            this.cid = cid;
12581            setMountPath(PackageHelper.getSdDir(cid));
12582        }
12583
12584        void createCopyFile() {
12585            cid = mInstallerService.allocateExternalStageCidLegacy();
12586        }
12587
12588        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
12589            if (origin.staged && origin.cid != null) {
12590                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
12591                cid = origin.cid;
12592                setMountPath(PackageHelper.getSdDir(cid));
12593                return PackageManager.INSTALL_SUCCEEDED;
12594            }
12595
12596            if (temp) {
12597                createCopyFile();
12598            } else {
12599                /*
12600                 * Pre-emptively destroy the container since it's destroyed if
12601                 * copying fails due to it existing anyway.
12602                 */
12603                PackageHelper.destroySdDir(cid);
12604            }
12605
12606            final String newMountPath = imcs.copyPackageToContainer(
12607                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
12608                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
12609
12610            if (newMountPath != null) {
12611                setMountPath(newMountPath);
12612                return PackageManager.INSTALL_SUCCEEDED;
12613            } else {
12614                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12615            }
12616        }
12617
12618        @Override
12619        String getCodePath() {
12620            return packagePath;
12621        }
12622
12623        @Override
12624        String getResourcePath() {
12625            return resourcePath;
12626        }
12627
12628        int doPreInstall(int status) {
12629            if (status != PackageManager.INSTALL_SUCCEEDED) {
12630                // Destroy container
12631                PackageHelper.destroySdDir(cid);
12632            } else {
12633                boolean mounted = PackageHelper.isContainerMounted(cid);
12634                if (!mounted) {
12635                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
12636                            Process.SYSTEM_UID);
12637                    if (newMountPath != null) {
12638                        setMountPath(newMountPath);
12639                    } else {
12640                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12641                    }
12642                }
12643            }
12644            return status;
12645        }
12646
12647        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12648            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
12649            String newMountPath = null;
12650            if (PackageHelper.isContainerMounted(cid)) {
12651                // Unmount the container
12652                if (!PackageHelper.unMountSdDir(cid)) {
12653                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
12654                    return false;
12655                }
12656            }
12657            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
12658                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
12659                        " which might be stale. Will try to clean up.");
12660                // Clean up the stale container and proceed to recreate.
12661                if (!PackageHelper.destroySdDir(newCacheId)) {
12662                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
12663                    return false;
12664                }
12665                // Successfully cleaned up stale container. Try to rename again.
12666                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
12667                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
12668                            + " inspite of cleaning it up.");
12669                    return false;
12670                }
12671            }
12672            if (!PackageHelper.isContainerMounted(newCacheId)) {
12673                Slog.w(TAG, "Mounting container " + newCacheId);
12674                newMountPath = PackageHelper.mountSdDir(newCacheId,
12675                        getEncryptKey(), Process.SYSTEM_UID);
12676            } else {
12677                newMountPath = PackageHelper.getSdDir(newCacheId);
12678            }
12679            if (newMountPath == null) {
12680                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
12681                return false;
12682            }
12683            Log.i(TAG, "Succesfully renamed " + cid +
12684                    " to " + newCacheId +
12685                    " at new path: " + newMountPath);
12686            cid = newCacheId;
12687
12688            final File beforeCodeFile = new File(packagePath);
12689            setMountPath(newMountPath);
12690            final File afterCodeFile = new File(packagePath);
12691
12692            // Reflect the rename in scanned details
12693            pkg.setCodePath(afterCodeFile.getAbsolutePath());
12694            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
12695                    afterCodeFile, pkg.baseCodePath));
12696            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
12697                    afterCodeFile, pkg.splitCodePaths));
12698
12699            // Reflect the rename in app info
12700            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
12701            pkg.setApplicationInfoCodePath(pkg.codePath);
12702            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
12703            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
12704            pkg.setApplicationInfoResourcePath(pkg.codePath);
12705            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
12706            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
12707
12708            return true;
12709        }
12710
12711        private void setMountPath(String mountPath) {
12712            final File mountFile = new File(mountPath);
12713
12714            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
12715            if (monolithicFile.exists()) {
12716                packagePath = monolithicFile.getAbsolutePath();
12717                if (isFwdLocked()) {
12718                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
12719                } else {
12720                    resourcePath = packagePath;
12721                }
12722            } else {
12723                packagePath = mountFile.getAbsolutePath();
12724                resourcePath = packagePath;
12725            }
12726        }
12727
12728        int doPostInstall(int status, int uid) {
12729            if (status != PackageManager.INSTALL_SUCCEEDED) {
12730                cleanUp();
12731            } else {
12732                final int groupOwner;
12733                final String protectedFile;
12734                if (isFwdLocked()) {
12735                    groupOwner = UserHandle.getSharedAppGid(uid);
12736                    protectedFile = RES_FILE_NAME;
12737                } else {
12738                    groupOwner = -1;
12739                    protectedFile = null;
12740                }
12741
12742                if (uid < Process.FIRST_APPLICATION_UID
12743                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
12744                    Slog.e(TAG, "Failed to finalize " + cid);
12745                    PackageHelper.destroySdDir(cid);
12746                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12747                }
12748
12749                boolean mounted = PackageHelper.isContainerMounted(cid);
12750                if (!mounted) {
12751                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
12752                }
12753            }
12754            return status;
12755        }
12756
12757        private void cleanUp() {
12758            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
12759
12760            // Destroy secure container
12761            PackageHelper.destroySdDir(cid);
12762        }
12763
12764        private List<String> getAllCodePaths() {
12765            final File codeFile = new File(getCodePath());
12766            if (codeFile != null && codeFile.exists()) {
12767                try {
12768                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
12769                    return pkg.getAllCodePaths();
12770                } catch (PackageParserException e) {
12771                    // Ignored; we tried our best
12772                }
12773            }
12774            return Collections.EMPTY_LIST;
12775        }
12776
12777        void cleanUpResourcesLI() {
12778            // Enumerate all code paths before deleting
12779            cleanUpResourcesLI(getAllCodePaths());
12780        }
12781
12782        private void cleanUpResourcesLI(List<String> allCodePaths) {
12783            cleanUp();
12784            removeDexFiles(allCodePaths, instructionSets);
12785        }
12786
12787        String getPackageName() {
12788            return getAsecPackageName(cid);
12789        }
12790
12791        boolean doPostDeleteLI(boolean delete) {
12792            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
12793            final List<String> allCodePaths = getAllCodePaths();
12794            boolean mounted = PackageHelper.isContainerMounted(cid);
12795            if (mounted) {
12796                // Unmount first
12797                if (PackageHelper.unMountSdDir(cid)) {
12798                    mounted = false;
12799                }
12800            }
12801            if (!mounted && delete) {
12802                cleanUpResourcesLI(allCodePaths);
12803            }
12804            return !mounted;
12805        }
12806
12807        @Override
12808        int doPreCopy() {
12809            if (isFwdLocked()) {
12810                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
12811                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
12812                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12813                }
12814            }
12815
12816            return PackageManager.INSTALL_SUCCEEDED;
12817        }
12818
12819        @Override
12820        int doPostCopy(int uid) {
12821            if (isFwdLocked()) {
12822                if (uid < Process.FIRST_APPLICATION_UID
12823                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
12824                                RES_FILE_NAME)) {
12825                    Slog.e(TAG, "Failed to finalize " + cid);
12826                    PackageHelper.destroySdDir(cid);
12827                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
12828                }
12829            }
12830
12831            return PackageManager.INSTALL_SUCCEEDED;
12832        }
12833    }
12834
12835    /**
12836     * Logic to handle movement of existing installed applications.
12837     */
12838    class MoveInstallArgs extends InstallArgs {
12839        private File codeFile;
12840        private File resourceFile;
12841
12842        /** New install */
12843        MoveInstallArgs(InstallParams params) {
12844            super(params.origin, params.move, params.observer, params.installFlags,
12845                    params.installerPackageName, params.volumeUuid,
12846                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
12847                    params.grantedRuntimePermissions,
12848                    params.traceMethod, params.traceCookie);
12849        }
12850
12851        int copyApk(IMediaContainerService imcs, boolean temp) {
12852            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
12853                    + move.fromUuid + " to " + move.toUuid);
12854            synchronized (mInstaller) {
12855                try {
12856                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
12857                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
12858                } catch (InstallerException e) {
12859                    Slog.w(TAG, "Failed to move app", e);
12860                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
12861                }
12862            }
12863
12864            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
12865            resourceFile = codeFile;
12866            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
12867
12868            return PackageManager.INSTALL_SUCCEEDED;
12869        }
12870
12871        int doPreInstall(int status) {
12872            if (status != PackageManager.INSTALL_SUCCEEDED) {
12873                cleanUp(move.toUuid);
12874            }
12875            return status;
12876        }
12877
12878        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
12879            if (status != PackageManager.INSTALL_SUCCEEDED) {
12880                cleanUp(move.toUuid);
12881                return false;
12882            }
12883
12884            // Reflect the move in app info
12885            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
12886            pkg.setApplicationInfoCodePath(pkg.codePath);
12887            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
12888            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
12889            pkg.setApplicationInfoResourcePath(pkg.codePath);
12890            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
12891            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
12892
12893            return true;
12894        }
12895
12896        int doPostInstall(int status, int uid) {
12897            if (status == PackageManager.INSTALL_SUCCEEDED) {
12898                cleanUp(move.fromUuid);
12899            } else {
12900                cleanUp(move.toUuid);
12901            }
12902            return status;
12903        }
12904
12905        @Override
12906        String getCodePath() {
12907            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
12908        }
12909
12910        @Override
12911        String getResourcePath() {
12912            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
12913        }
12914
12915        private boolean cleanUp(String volumeUuid) {
12916            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
12917                    move.dataAppName);
12918            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
12919            synchronized (mInstallLock) {
12920                // Clean up both app data and code
12921                removeDataDirsLI(volumeUuid, move.packageName);
12922                removeCodePathLI(codeFile);
12923            }
12924            return true;
12925        }
12926
12927        void cleanUpResourcesLI() {
12928            throw new UnsupportedOperationException();
12929        }
12930
12931        boolean doPostDeleteLI(boolean delete) {
12932            throw new UnsupportedOperationException();
12933        }
12934    }
12935
12936    static String getAsecPackageName(String packageCid) {
12937        int idx = packageCid.lastIndexOf("-");
12938        if (idx == -1) {
12939            return packageCid;
12940        }
12941        return packageCid.substring(0, idx);
12942    }
12943
12944    // Utility method used to create code paths based on package name and available index.
12945    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
12946        String idxStr = "";
12947        int idx = 1;
12948        // Fall back to default value of idx=1 if prefix is not
12949        // part of oldCodePath
12950        if (oldCodePath != null) {
12951            String subStr = oldCodePath;
12952            // Drop the suffix right away
12953            if (suffix != null && subStr.endsWith(suffix)) {
12954                subStr = subStr.substring(0, subStr.length() - suffix.length());
12955            }
12956            // If oldCodePath already contains prefix find out the
12957            // ending index to either increment or decrement.
12958            int sidx = subStr.lastIndexOf(prefix);
12959            if (sidx != -1) {
12960                subStr = subStr.substring(sidx + prefix.length());
12961                if (subStr != null) {
12962                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
12963                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
12964                    }
12965                    try {
12966                        idx = Integer.parseInt(subStr);
12967                        if (idx <= 1) {
12968                            idx++;
12969                        } else {
12970                            idx--;
12971                        }
12972                    } catch(NumberFormatException e) {
12973                    }
12974                }
12975            }
12976        }
12977        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
12978        return prefix + idxStr;
12979    }
12980
12981    private File getNextCodePath(File targetDir, String packageName) {
12982        int suffix = 1;
12983        File result;
12984        do {
12985            result = new File(targetDir, packageName + "-" + suffix);
12986            suffix++;
12987        } while (result.exists());
12988        return result;
12989    }
12990
12991    // Utility method that returns the relative package path with respect
12992    // to the installation directory. Like say for /data/data/com.test-1.apk
12993    // string com.test-1 is returned.
12994    static String deriveCodePathName(String codePath) {
12995        if (codePath == null) {
12996            return null;
12997        }
12998        final File codeFile = new File(codePath);
12999        final String name = codeFile.getName();
13000        if (codeFile.isDirectory()) {
13001            return name;
13002        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
13003            final int lastDot = name.lastIndexOf('.');
13004            return name.substring(0, lastDot);
13005        } else {
13006            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
13007            return null;
13008        }
13009    }
13010
13011    static class PackageInstalledInfo {
13012        String name;
13013        int uid;
13014        // The set of users that originally had this package installed.
13015        int[] origUsers;
13016        // The set of users that now have this package installed.
13017        int[] newUsers;
13018        PackageParser.Package pkg;
13019        int returnCode;
13020        String returnMsg;
13021        PackageRemovedInfo removedInfo;
13022        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
13023
13024        public void setError(int code, String msg) {
13025            setReturnCode(code);
13026            setReturnMessage(msg);
13027            Slog.w(TAG, msg);
13028        }
13029
13030        public void setError(String msg, PackageParserException e) {
13031            setReturnCode(e.error);
13032            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
13033            Slog.w(TAG, msg, e);
13034        }
13035
13036        public void setError(String msg, PackageManagerException e) {
13037            returnCode = e.error;
13038            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
13039            Slog.w(TAG, msg, e);
13040        }
13041
13042        public void setReturnCode(int returnCode) {
13043            this.returnCode = returnCode;
13044            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
13045            for (int i = 0; i < childCount; i++) {
13046                addedChildPackages.valueAt(i).returnCode = returnCode;
13047            }
13048        }
13049
13050        private void setReturnMessage(String returnMsg) {
13051            this.returnMsg = returnMsg;
13052            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
13053            for (int i = 0; i < childCount; i++) {
13054                addedChildPackages.valueAt(i).returnMsg = returnMsg;
13055            }
13056        }
13057
13058        // In some error cases we want to convey more info back to the observer
13059        String origPackage;
13060        String origPermission;
13061    }
13062
13063    /*
13064     * Install a non-existing package.
13065     */
13066    private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
13067            UserHandle user, String installerPackageName, String volumeUuid,
13068            PackageInstalledInfo res) {
13069        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
13070
13071        // Remember this for later, in case we need to rollback this install
13072        String pkgName = pkg.packageName;
13073
13074        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
13075
13076        synchronized(mPackages) {
13077            if (mSettings.mRenamedPackages.containsKey(pkgName)) {
13078                // A package with the same name is already installed, though
13079                // it has been renamed to an older name.  The package we
13080                // are trying to install should be installed as an update to
13081                // the existing one, but that has not been requested, so bail.
13082                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
13083                        + " without first uninstalling package running as "
13084                        + mSettings.mRenamedPackages.get(pkgName));
13085                return;
13086            }
13087            if (mPackages.containsKey(pkgName)) {
13088                // Don't allow installation over an existing package with the same name.
13089                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
13090                        + " without first uninstalling.");
13091                return;
13092            }
13093        }
13094
13095        try {
13096            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
13097                    System.currentTimeMillis(), user);
13098
13099            updateSettingsLI(newPackage, installerPackageName, null, res, user);
13100
13101            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
13102                prepareAppDataAfterInstall(newPackage);
13103
13104            } else {
13105                // Remove package from internal structures, but keep around any
13106                // data that might have already existed
13107                deletePackageLI(pkgName, UserHandle.ALL, false, null,
13108                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
13109            }
13110        } catch (PackageManagerException e) {
13111            res.setError("Package couldn't be installed in " + pkg.codePath, e);
13112        }
13113
13114        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13115    }
13116
13117    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
13118        // Can't rotate keys during boot or if sharedUser.
13119        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
13120                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
13121            return false;
13122        }
13123        // app is using upgradeKeySets; make sure all are valid
13124        KeySetManagerService ksms = mSettings.mKeySetManagerService;
13125        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
13126        for (int i = 0; i < upgradeKeySets.length; i++) {
13127            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
13128                Slog.wtf(TAG, "Package "
13129                         + (oldPs.name != null ? oldPs.name : "<null>")
13130                         + " contains upgrade-key-set reference to unknown key-set: "
13131                         + upgradeKeySets[i]
13132                         + " reverting to signatures check.");
13133                return false;
13134            }
13135        }
13136        return true;
13137    }
13138
13139    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
13140        // Upgrade keysets are being used.  Determine if new package has a superset of the
13141        // required keys.
13142        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
13143        KeySetManagerService ksms = mSettings.mKeySetManagerService;
13144        for (int i = 0; i < upgradeKeySets.length; i++) {
13145            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
13146            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
13147                return true;
13148            }
13149        }
13150        return false;
13151    }
13152
13153    private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
13154            UserHandle user, String installerPackageName, PackageInstalledInfo res) {
13155        final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
13156
13157        final PackageParser.Package oldPackage;
13158        final String pkgName = pkg.packageName;
13159        final int[] allUsers;
13160        final boolean weFroze;
13161
13162        // First find the old package info and check signatures
13163        synchronized(mPackages) {
13164            oldPackage = mPackages.get(pkgName);
13165            final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp();
13166            if (isEphemeral && !oldIsEphemeral) {
13167                // can't downgrade from full to ephemeral
13168                Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
13169                res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
13170                return;
13171            }
13172            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
13173            final PackageSetting ps = mSettings.mPackages.get(pkgName);
13174            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
13175                if (!checkUpgradeKeySetLP(ps, pkg)) {
13176                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
13177                            "New package not signed by keys specified by upgrade-keysets: "
13178                                    + pkgName);
13179                    return;
13180                }
13181            } else {
13182                // default to original signature matching
13183                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
13184                        != PackageManager.SIGNATURE_MATCH) {
13185                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
13186                            "New package has a different signature: " + pkgName);
13187                    return;
13188                }
13189            }
13190
13191            // In case of rollback, remember per-user/profile install state
13192            allUsers = sUserManager.getUserIds();
13193
13194            // Mark the app as frozen to prevent launching during the upgrade
13195            // process, and then kill all running instances
13196            if (!ps.frozen) {
13197                ps.frozen = true;
13198                weFroze = true;
13199            } else {
13200                weFroze = false;
13201            }
13202        }
13203
13204        try {
13205            replacePackageDirtyLI(pkg, oldPackage, parseFlags, scanFlags, user, allUsers,
13206                    installerPackageName, res);
13207        } finally {
13208            // Regardless of success or failure of upgrade steps above, always
13209            // unfreeze the package if we froze it
13210            if (weFroze) {
13211                unfreezePackage(pkgName);
13212            }
13213        }
13214    }
13215
13216    private void replacePackageDirtyLI(PackageParser.Package pkg, PackageParser.Package oldPackage,
13217            int parseFlags, int scanFlags, UserHandle user, int[] allUsers,
13218            String installerPackageName, PackageInstalledInfo res) {
13219        // Update what is removed
13220        res.removedInfo = new PackageRemovedInfo();
13221        res.removedInfo.uid = oldPackage.applicationInfo.uid;
13222        res.removedInfo.removedPackage = oldPackage.packageName;
13223        res.removedInfo.isUpdate = true;
13224        final int childCount = (oldPackage.childPackages != null)
13225                ? oldPackage.childPackages.size() : 0;
13226        for (int i = 0; i < childCount; i++) {
13227            boolean childPackageUpdated = false;
13228            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
13229            if (res.addedChildPackages != null) {
13230                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
13231                if (childRes != null) {
13232                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
13233                    childRes.removedInfo.removedPackage = childPkg.packageName;
13234                    childRes.removedInfo.isUpdate = true;
13235                    childPackageUpdated = true;
13236                }
13237            }
13238            if (!childPackageUpdated) {
13239                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
13240                childRemovedRes.removedPackage = childPkg.packageName;
13241                childRemovedRes.isUpdate = false;
13242                childRemovedRes.dataRemoved = true;
13243                synchronized (mPackages) {
13244                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
13245                    if (childPs != null) {
13246                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
13247                    }
13248                }
13249                if (res.removedInfo.removedChildPackages == null) {
13250                    res.removedInfo.removedChildPackages = new ArrayMap<>();
13251                }
13252                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
13253            }
13254        }
13255
13256        boolean sysPkg = (isSystemApp(oldPackage));
13257        if (sysPkg) {
13258            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
13259                    user, allUsers, installerPackageName, res);
13260        } else {
13261            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
13262                    user, allUsers, installerPackageName, res);
13263        }
13264    }
13265
13266    public List<String> getPreviousCodePaths(String packageName) {
13267        final PackageSetting ps = mSettings.mPackages.get(packageName);
13268        final List<String> result = new ArrayList<String>();
13269        if (ps != null && ps.oldCodePaths != null) {
13270            result.addAll(ps.oldCodePaths);
13271        }
13272        return result;
13273    }
13274
13275    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
13276            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
13277            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
13278        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
13279                + deletedPackage);
13280
13281        String pkgName = deletedPackage.packageName;
13282        boolean deletedPkg = true;
13283        boolean addedPkg = false;
13284        boolean updatedSettings = false;
13285        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
13286        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
13287                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
13288
13289        final long origUpdateTime = (pkg.mExtras != null)
13290                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
13291
13292        // First delete the existing package while retaining the data directory
13293        if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags,
13294                res.removedInfo, true, pkg)) {
13295            // If the existing package wasn't successfully deleted
13296            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
13297            deletedPkg = false;
13298        } else {
13299            // Successfully deleted the old package; proceed with replace.
13300
13301            // If deleted package lived in a container, give users a chance to
13302            // relinquish resources before killing.
13303            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
13304                if (DEBUG_INSTALL) {
13305                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
13306                }
13307                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
13308                final ArrayList<String> pkgList = new ArrayList<String>(1);
13309                pkgList.add(deletedPackage.applicationInfo.packageName);
13310                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
13311            }
13312
13313            deleteCodeCacheDirsLI(pkg);
13314            deleteProfilesLI(pkg, /*destroy*/ false);
13315
13316            try {
13317                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
13318                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
13319                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
13320
13321                // Update the in-memory copy of the previous code paths.
13322                PackageSetting ps = mSettings.mPackages.get(pkgName);
13323                if (!killApp) {
13324                    if (ps.oldCodePaths == null) {
13325                        ps.oldCodePaths = new ArraySet<>();
13326                    }
13327                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
13328                    if (deletedPackage.splitCodePaths != null) {
13329                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
13330                    }
13331                } else {
13332                    ps.oldCodePaths = null;
13333                }
13334                if (ps.childPackageNames != null) {
13335                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
13336                        final String childPkgName = ps.childPackageNames.get(i);
13337                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
13338                        childPs.oldCodePaths = ps.oldCodePaths;
13339                    }
13340                }
13341                prepareAppDataAfterInstall(newPackage);
13342                addedPkg = true;
13343            } catch (PackageManagerException e) {
13344                res.setError("Package couldn't be installed in " + pkg.codePath, e);
13345            }
13346        }
13347
13348        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13349            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
13350
13351            // Revert all internal state mutations and added folders for the failed install
13352            if (addedPkg) {
13353                deletePackageLI(pkgName, null, true, allUsers, deleteFlags,
13354                        res.removedInfo, true, null);
13355            }
13356
13357            // Restore the old package
13358            if (deletedPkg) {
13359                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
13360                File restoreFile = new File(deletedPackage.codePath);
13361                // Parse old package
13362                boolean oldExternal = isExternal(deletedPackage);
13363                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
13364                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
13365                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
13366                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
13367                try {
13368                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
13369                            null);
13370                } catch (PackageManagerException e) {
13371                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
13372                            + e.getMessage());
13373                    return;
13374                }
13375
13376                synchronized (mPackages) {
13377                    // Ensure the installer package name up to date
13378                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
13379
13380                    // Update permissions for restored package
13381                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
13382
13383                    mSettings.writeLPr();
13384                }
13385
13386                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
13387            }
13388        } else {
13389            synchronized (mPackages) {
13390                PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
13391                if (ps != null) {
13392                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
13393                    if (res.removedInfo.removedChildPackages != null) {
13394                        final int childCount = res.removedInfo.removedChildPackages.size();
13395                        // Iterate in reverse as we may modify the collection
13396                        for (int i = childCount - 1; i >= 0; i--) {
13397                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
13398                            if (res.addedChildPackages.containsKey(childPackageName)) {
13399                                res.removedInfo.removedChildPackages.removeAt(i);
13400                            } else {
13401                                PackageRemovedInfo childInfo = res.removedInfo
13402                                        .removedChildPackages.valueAt(i);
13403                                childInfo.removedForAllUsers = mPackages.get(
13404                                        childInfo.removedPackage) == null;
13405                            }
13406                        }
13407                    }
13408                }
13409            }
13410        }
13411    }
13412
13413    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
13414            PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
13415            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
13416        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
13417                + ", old=" + deletedPackage);
13418
13419        final boolean disabledSystem;
13420
13421        // Set the system/privileged flags as needed
13422        parseFlags |= PackageParser.PARSE_IS_SYSTEM;
13423        if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
13424                != 0) {
13425            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
13426        }
13427
13428        // Kill package processes including services, providers, etc.
13429        killPackage(deletedPackage, "replace sys pkg");
13430
13431        // Remove existing system package
13432        removePackageLI(deletedPackage, true);
13433
13434        disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
13435        if (!disabledSystem) {
13436            // We didn't need to disable the .apk as a current system package,
13437            // which means we are replacing another update that is already
13438            // installed.  We need to make sure to delete the older one's .apk.
13439            res.removedInfo.args = createInstallArgsForExisting(0,
13440                    deletedPackage.applicationInfo.getCodePath(),
13441                    deletedPackage.applicationInfo.getResourcePath(),
13442                    getAppDexInstructionSets(deletedPackage.applicationInfo));
13443        } else {
13444            res.removedInfo.args = null;
13445        }
13446
13447        // Successfully disabled the old package. Now proceed with re-installation
13448        deleteCodeCacheDirsLI(pkg);
13449        deleteProfilesLI(pkg, /*destroy*/ false);
13450
13451        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
13452        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
13453                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
13454
13455        PackageParser.Package newPackage = null;
13456        try {
13457            // Add the package to the internal data structures
13458            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
13459
13460            // Set the update and install times
13461            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
13462            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
13463                    System.currentTimeMillis());
13464
13465            // Check for shared user id changes
13466            String invalidPackageName = getParentOrChildPackageChangedSharedUser(
13467                    deletedPackage, newPackage);
13468            if (invalidPackageName != null) {
13469                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
13470                        "Forbidding shared user change from " + deletedPkgSetting.sharedUser
13471                                + " to " + invalidPackageName);
13472            }
13473
13474            // Update the package dynamic state if succeeded
13475            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
13476                // Now that the install succeeded make sure we remove data
13477                // directories for any child package the update removed.
13478                final int deletedChildCount = (deletedPackage.childPackages != null)
13479                        ? deletedPackage.childPackages.size() : 0;
13480                final int newChildCount = (newPackage.childPackages != null)
13481                        ? newPackage.childPackages.size() : 0;
13482                for (int i = 0; i < deletedChildCount; i++) {
13483                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
13484                    boolean childPackageDeleted = true;
13485                    for (int j = 0; j < newChildCount; j++) {
13486                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
13487                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
13488                            childPackageDeleted = false;
13489                            break;
13490                        }
13491                    }
13492                    if (childPackageDeleted) {
13493                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
13494                                deletedChildPkg.packageName);
13495                        if (ps != null && res.removedInfo.removedChildPackages != null) {
13496                            PackageRemovedInfo removedChildRes = res.removedInfo
13497                                    .removedChildPackages.get(deletedChildPkg.packageName);
13498                            removePackageDataLI(ps, allUsers, removedChildRes, 0, false);
13499                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
13500                        }
13501                    }
13502                }
13503
13504                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
13505                prepareAppDataAfterInstall(newPackage);
13506            }
13507        } catch (PackageManagerException e) {
13508            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
13509            res.setError("Package couldn't be installed in " + pkg.codePath, e);
13510        }
13511
13512        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
13513            // Re installation failed. Restore old information
13514            // Remove new pkg information
13515            if (newPackage != null) {
13516                removeInstalledPackageLI(newPackage, true);
13517            }
13518            // Add back the old system package
13519            try {
13520                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
13521            } catch (PackageManagerException e) {
13522                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
13523            }
13524
13525            synchronized (mPackages) {
13526                if (disabledSystem) {
13527                    enableSystemPackageLPw(deletedPackage);
13528                }
13529
13530                // Ensure the installer package name up to date
13531                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
13532
13533                // Update permissions for restored package
13534                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
13535
13536                mSettings.writeLPr();
13537            }
13538
13539            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
13540                    + " after failed upgrade");
13541        }
13542    }
13543
13544    /**
13545     * Checks whether the parent or any of the child packages have a change shared
13546     * user. For a package to be a valid update the shred users of the parent and
13547     * the children should match. We may later support changing child shared users.
13548     * @param oldPkg The updated package.
13549     * @param newPkg The update package.
13550     * @return The shared user that change between the versions.
13551     */
13552    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
13553            PackageParser.Package newPkg) {
13554        // Check parent shared user
13555        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
13556            return newPkg.packageName;
13557        }
13558        // Check child shared users
13559        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
13560        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
13561        for (int i = 0; i < newChildCount; i++) {
13562            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
13563            // If this child was present, did it have the same shared user?
13564            for (int j = 0; j < oldChildCount; j++) {
13565                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
13566                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
13567                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
13568                    return newChildPkg.packageName;
13569                }
13570            }
13571        }
13572        return null;
13573    }
13574
13575    private void removeNativeBinariesLI(PackageSetting ps) {
13576        // Remove the lib path for the parent package
13577        if (ps != null) {
13578            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
13579            // Remove the lib path for the child packages
13580            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
13581            for (int i = 0; i < childCount; i++) {
13582                PackageSetting childPs = null;
13583                synchronized (mPackages) {
13584                    childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
13585                }
13586                if (childPs != null) {
13587                    NativeLibraryHelper.removeNativeBinariesLI(childPs
13588                            .legacyNativeLibraryPathString);
13589                }
13590            }
13591        }
13592    }
13593
13594    private void enableSystemPackageLPw(PackageParser.Package pkg) {
13595        // Enable the parent package
13596        mSettings.enableSystemPackageLPw(pkg.packageName);
13597        // Enable the child packages
13598        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
13599        for (int i = 0; i < childCount; i++) {
13600            PackageParser.Package childPkg = pkg.childPackages.get(i);
13601            mSettings.enableSystemPackageLPw(childPkg.packageName);
13602        }
13603    }
13604
13605    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
13606            PackageParser.Package newPkg) {
13607        // Disable the parent package (parent always replaced)
13608        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
13609        // Disable the child packages
13610        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
13611        for (int i = 0; i < childCount; i++) {
13612            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
13613            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
13614            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
13615        }
13616        return disabled;
13617    }
13618
13619    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
13620            String installerPackageName) {
13621        // Enable the parent package
13622        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
13623        // Enable the child packages
13624        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
13625        for (int i = 0; i < childCount; i++) {
13626            PackageParser.Package childPkg = pkg.childPackages.get(i);
13627            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
13628        }
13629    }
13630
13631    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
13632        // Collect all used permissions in the UID
13633        ArraySet<String> usedPermissions = new ArraySet<>();
13634        final int packageCount = su.packages.size();
13635        for (int i = 0; i < packageCount; i++) {
13636            PackageSetting ps = su.packages.valueAt(i);
13637            if (ps.pkg == null) {
13638                continue;
13639            }
13640            final int requestedPermCount = ps.pkg.requestedPermissions.size();
13641            for (int j = 0; j < requestedPermCount; j++) {
13642                String permission = ps.pkg.requestedPermissions.get(j);
13643                BasePermission bp = mSettings.mPermissions.get(permission);
13644                if (bp != null) {
13645                    usedPermissions.add(permission);
13646                }
13647            }
13648        }
13649
13650        PermissionsState permissionsState = su.getPermissionsState();
13651        // Prune install permissions
13652        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
13653        final int installPermCount = installPermStates.size();
13654        for (int i = installPermCount - 1; i >= 0;  i--) {
13655            PermissionState permissionState = installPermStates.get(i);
13656            if (!usedPermissions.contains(permissionState.getName())) {
13657                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
13658                if (bp != null) {
13659                    permissionsState.revokeInstallPermission(bp);
13660                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
13661                            PackageManager.MASK_PERMISSION_FLAGS, 0);
13662                }
13663            }
13664        }
13665
13666        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
13667
13668        // Prune runtime permissions
13669        for (int userId : allUserIds) {
13670            List<PermissionState> runtimePermStates = permissionsState
13671                    .getRuntimePermissionStates(userId);
13672            final int runtimePermCount = runtimePermStates.size();
13673            for (int i = runtimePermCount - 1; i >= 0; i--) {
13674                PermissionState permissionState = runtimePermStates.get(i);
13675                if (!usedPermissions.contains(permissionState.getName())) {
13676                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
13677                    if (bp != null) {
13678                        permissionsState.revokeRuntimePermission(bp, userId);
13679                        permissionsState.updatePermissionFlags(bp, userId,
13680                                PackageManager.MASK_PERMISSION_FLAGS, 0);
13681                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
13682                                runtimePermissionChangedUserIds, userId);
13683                    }
13684                }
13685            }
13686        }
13687
13688        return runtimePermissionChangedUserIds;
13689    }
13690
13691    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
13692            int[] allUsers, PackageInstalledInfo res, UserHandle user) {
13693        // Update the parent package setting
13694        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
13695                res, user);
13696        // Update the child packages setting
13697        final int childCount = (newPackage.childPackages != null)
13698                ? newPackage.childPackages.size() : 0;
13699        for (int i = 0; i < childCount; i++) {
13700            PackageParser.Package childPackage = newPackage.childPackages.get(i);
13701            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
13702            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
13703                    childRes.origUsers, childRes, user);
13704        }
13705    }
13706
13707    private void updateSettingsInternalLI(PackageParser.Package newPackage,
13708            String installerPackageName, int[] allUsers, int[] installedForUsers,
13709            PackageInstalledInfo res, UserHandle user) {
13710        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
13711
13712        String pkgName = newPackage.packageName;
13713        synchronized (mPackages) {
13714            //write settings. the installStatus will be incomplete at this stage.
13715            //note that the new package setting would have already been
13716            //added to mPackages. It hasn't been persisted yet.
13717            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
13718            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
13719            mSettings.writeLPr();
13720            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13721        }
13722
13723        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
13724        synchronized (mPackages) {
13725            updatePermissionsLPw(newPackage.packageName, newPackage,
13726                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
13727                            ? UPDATE_PERMISSIONS_ALL : 0));
13728            // For system-bundled packages, we assume that installing an upgraded version
13729            // of the package implies that the user actually wants to run that new code,
13730            // so we enable the package.
13731            PackageSetting ps = mSettings.mPackages.get(pkgName);
13732            final int userId = user.getIdentifier();
13733            if (ps != null) {
13734                if (isSystemApp(newPackage)) {
13735                    if (DEBUG_INSTALL) {
13736                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
13737                    }
13738                    // Enable system package for requested users
13739                    if (res.origUsers != null) {
13740                        for (int origUserId : res.origUsers) {
13741                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
13742                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
13743                                        origUserId, installerPackageName);
13744                            }
13745                        }
13746                    }
13747                    // Also convey the prior install/uninstall state
13748                    if (allUsers != null && installedForUsers != null) {
13749                        for (int currentUserId : allUsers) {
13750                            final boolean installed = ArrayUtils.contains(
13751                                    installedForUsers, currentUserId);
13752                            if (DEBUG_INSTALL) {
13753                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
13754                            }
13755                            ps.setInstalled(installed, currentUserId);
13756                        }
13757                        // these install state changes will be persisted in the
13758                        // upcoming call to mSettings.writeLPr().
13759                    }
13760                }
13761                // It's implied that when a user requests installation, they want the app to be
13762                // installed and enabled.
13763                if (userId != UserHandle.USER_ALL) {
13764                    ps.setInstalled(true, userId);
13765                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
13766                }
13767            }
13768            res.name = pkgName;
13769            res.uid = newPackage.applicationInfo.uid;
13770            res.pkg = newPackage;
13771            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
13772            mSettings.setInstallerPackageName(pkgName, installerPackageName);
13773            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
13774            //to update install status
13775            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
13776            mSettings.writeLPr();
13777            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13778        }
13779
13780        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13781    }
13782
13783    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
13784        try {
13785            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
13786            installPackageLI(args, res);
13787        } finally {
13788            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13789        }
13790    }
13791
13792    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
13793        final int installFlags = args.installFlags;
13794        final String installerPackageName = args.installerPackageName;
13795        final String volumeUuid = args.volumeUuid;
13796        final File tmpPackageFile = new File(args.getCodePath());
13797        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
13798        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
13799                || (args.volumeUuid != null));
13800        final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
13801        boolean replace = false;
13802        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
13803        if (args.move != null) {
13804            // moving a complete application; perform an initial scan on the new install location
13805            scanFlags |= SCAN_INITIAL;
13806        }
13807        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
13808            scanFlags |= SCAN_DONT_KILL_APP;
13809        }
13810
13811        // Result object to be returned
13812        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
13813
13814        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
13815
13816        // Sanity check
13817        if (ephemeral && (forwardLocked || onExternal)) {
13818            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
13819                    + " external=" + onExternal);
13820            res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
13821            return;
13822        }
13823
13824        // Retrieve PackageSettings and parse package
13825        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
13826                | PackageParser.PARSE_ENFORCE_CODE
13827                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
13828                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
13829                | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0);
13830        PackageParser pp = new PackageParser();
13831        pp.setSeparateProcesses(mSeparateProcesses);
13832        pp.setDisplayMetrics(mMetrics);
13833
13834        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
13835        final PackageParser.Package pkg;
13836        try {
13837            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
13838        } catch (PackageParserException e) {
13839            res.setError("Failed parse during installPackageLI", e);
13840            return;
13841        } finally {
13842            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13843        }
13844
13845        // If we are installing a clustered package add results for the children
13846        if (pkg.childPackages != null) {
13847            synchronized (mPackages) {
13848                final int childCount = pkg.childPackages.size();
13849                for (int i = 0; i < childCount; i++) {
13850                    PackageParser.Package childPkg = pkg.childPackages.get(i);
13851                    PackageInstalledInfo childRes = new PackageInstalledInfo();
13852                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
13853                    childRes.pkg = childPkg;
13854                    childRes.name = childPkg.packageName;
13855                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
13856                    if (childPs != null) {
13857                        childRes.origUsers = childPs.queryInstalledUsers(
13858                                sUserManager.getUserIds(), true);
13859                    }
13860                    if ((mPackages.containsKey(childPkg.packageName))) {
13861                        childRes.removedInfo = new PackageRemovedInfo();
13862                        childRes.removedInfo.removedPackage = childPkg.packageName;
13863                    }
13864                    if (res.addedChildPackages == null) {
13865                        res.addedChildPackages = new ArrayMap<>();
13866                    }
13867                    res.addedChildPackages.put(childPkg.packageName, childRes);
13868                }
13869            }
13870        }
13871
13872        // If package doesn't declare API override, mark that we have an install
13873        // time CPU ABI override.
13874        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
13875            pkg.cpuAbiOverride = args.abiOverride;
13876        }
13877
13878        String pkgName = res.name = pkg.packageName;
13879        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
13880            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
13881                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
13882                return;
13883            }
13884        }
13885
13886        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
13887        try {
13888            PackageParser.collectCertificates(pkg, parseFlags);
13889        } catch (PackageParserException e) {
13890            res.setError("Failed collect during installPackageLI", e);
13891            return;
13892        } finally {
13893            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13894        }
13895
13896        // Get rid of all references to package scan path via parser.
13897        pp = null;
13898        String oldCodePath = null;
13899        boolean systemApp = false;
13900        synchronized (mPackages) {
13901            // Check if installing already existing package
13902            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
13903                String oldName = mSettings.mRenamedPackages.get(pkgName);
13904                if (pkg.mOriginalPackages != null
13905                        && pkg.mOriginalPackages.contains(oldName)
13906                        && mPackages.containsKey(oldName)) {
13907                    // This package is derived from an original package,
13908                    // and this device has been updating from that original
13909                    // name.  We must continue using the original name, so
13910                    // rename the new package here.
13911                    pkg.setPackageName(oldName);
13912                    pkgName = pkg.packageName;
13913                    replace = true;
13914                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
13915                            + oldName + " pkgName=" + pkgName);
13916                } else if (mPackages.containsKey(pkgName)) {
13917                    // This package, under its official name, already exists
13918                    // on the device; we should replace it.
13919                    replace = true;
13920                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
13921                }
13922
13923                // Child packages are installed through the parent package
13924                if (pkg.parentPackage != null) {
13925                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
13926                            "Package " + pkg.packageName + " is child of package "
13927                                    + pkg.parentPackage.parentPackage + ". Child packages "
13928                                    + "can be updated only through the parent package.");
13929                    return;
13930                }
13931
13932                if (replace) {
13933                    // Prevent apps opting out from runtime permissions
13934                    PackageParser.Package oldPackage = mPackages.get(pkgName);
13935                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
13936                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
13937                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
13938                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
13939                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
13940                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
13941                                        + " doesn't support runtime permissions but the old"
13942                                        + " target SDK " + oldTargetSdk + " does.");
13943                        return;
13944                    }
13945
13946                    // Prevent installing of child packages
13947                    if (oldPackage.parentPackage != null) {
13948                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
13949                                "Package " + pkg.packageName + " is child of package "
13950                                        + oldPackage.parentPackage + ". Child packages "
13951                                        + "can be updated only through the parent package.");
13952                        return;
13953                    }
13954                }
13955            }
13956
13957            PackageSetting ps = mSettings.mPackages.get(pkgName);
13958            if (ps != null) {
13959                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
13960
13961                // Quick sanity check that we're signed correctly if updating;
13962                // we'll check this again later when scanning, but we want to
13963                // bail early here before tripping over redefined permissions.
13964                if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
13965                    if (!checkUpgradeKeySetLP(ps, pkg)) {
13966                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
13967                                + pkg.packageName + " upgrade keys do not match the "
13968                                + "previously installed version");
13969                        return;
13970                    }
13971                } else {
13972                    try {
13973                        verifySignaturesLP(ps, pkg);
13974                    } catch (PackageManagerException e) {
13975                        res.setError(e.error, e.getMessage());
13976                        return;
13977                    }
13978                }
13979
13980                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
13981                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
13982                    systemApp = (ps.pkg.applicationInfo.flags &
13983                            ApplicationInfo.FLAG_SYSTEM) != 0;
13984                }
13985                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
13986            }
13987
13988            // Check whether the newly-scanned package wants to define an already-defined perm
13989            int N = pkg.permissions.size();
13990            for (int i = N-1; i >= 0; i--) {
13991                PackageParser.Permission perm = pkg.permissions.get(i);
13992                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
13993                if (bp != null) {
13994                    // If the defining package is signed with our cert, it's okay.  This
13995                    // also includes the "updating the same package" case, of course.
13996                    // "updating same package" could also involve key-rotation.
13997                    final boolean sigsOk;
13998                    if (bp.sourcePackage.equals(pkg.packageName)
13999                            && (bp.packageSetting instanceof PackageSetting)
14000                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
14001                                    scanFlags))) {
14002                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
14003                    } else {
14004                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
14005                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
14006                    }
14007                    if (!sigsOk) {
14008                        // If the owning package is the system itself, we log but allow
14009                        // install to proceed; we fail the install on all other permission
14010                        // redefinitions.
14011                        if (!bp.sourcePackage.equals("android")) {
14012                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
14013                                    + pkg.packageName + " attempting to redeclare permission "
14014                                    + perm.info.name + " already owned by " + bp.sourcePackage);
14015                            res.origPermission = perm.info.name;
14016                            res.origPackage = bp.sourcePackage;
14017                            return;
14018                        } else {
14019                            Slog.w(TAG, "Package " + pkg.packageName
14020                                    + " attempting to redeclare system permission "
14021                                    + perm.info.name + "; ignoring new declaration");
14022                            pkg.permissions.remove(i);
14023                        }
14024                    }
14025                }
14026            }
14027        }
14028
14029        if (systemApp) {
14030            if (onExternal) {
14031                // Abort update; system app can't be replaced with app on sdcard
14032                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
14033                        "Cannot install updates to system apps on sdcard");
14034                return;
14035            } else if (ephemeral) {
14036                // Abort update; system app can't be replaced with an ephemeral app
14037                res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
14038                        "Cannot update a system app with an ephemeral app");
14039                return;
14040            }
14041        }
14042
14043        if (args.move != null) {
14044            // We did an in-place move, so dex is ready to roll
14045            scanFlags |= SCAN_NO_DEX;
14046            scanFlags |= SCAN_MOVE;
14047
14048            synchronized (mPackages) {
14049                final PackageSetting ps = mSettings.mPackages.get(pkgName);
14050                if (ps == null) {
14051                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
14052                            "Missing settings for moved package " + pkgName);
14053                }
14054
14055                // We moved the entire application as-is, so bring over the
14056                // previously derived ABI information.
14057                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
14058                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
14059            }
14060
14061        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
14062            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
14063            scanFlags |= SCAN_NO_DEX;
14064
14065            try {
14066                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
14067                    args.abiOverride : pkg.cpuAbiOverride);
14068                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
14069                        true /* extract libs */);
14070            } catch (PackageManagerException pme) {
14071                Slog.e(TAG, "Error deriving application ABI", pme);
14072                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
14073                return;
14074            }
14075
14076
14077            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
14078            // Do not run PackageDexOptimizer through the local performDexOpt
14079            // method because `pkg` is not in `mPackages` yet.
14080            int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */,
14081                    false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL));
14082            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14083            if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
14084                String msg = "Extracking package failed for " + pkgName;
14085                res.setError(INSTALL_FAILED_DEXOPT, msg);
14086                return;
14087            }
14088        }
14089
14090        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
14091            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
14092            return;
14093        }
14094
14095        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
14096
14097        if (replace) {
14098            replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
14099                    installerPackageName, res);
14100        } else {
14101            installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
14102                    args.user, installerPackageName, volumeUuid, res);
14103        }
14104        synchronized (mPackages) {
14105            final PackageSetting ps = mSettings.mPackages.get(pkgName);
14106            if (ps != null) {
14107                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
14108            }
14109
14110            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14111            for (int i = 0; i < childCount; i++) {
14112                PackageParser.Package childPkg = pkg.childPackages.get(i);
14113                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
14114                PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
14115                if (childPs != null) {
14116                    childRes.newUsers = childPs.queryInstalledUsers(
14117                            sUserManager.getUserIds(), true);
14118                }
14119            }
14120        }
14121    }
14122
14123    private void startIntentFilterVerifications(int userId, boolean replacing,
14124            PackageParser.Package pkg) {
14125        if (mIntentFilterVerifierComponent == null) {
14126            Slog.w(TAG, "No IntentFilter verification will not be done as "
14127                    + "there is no IntentFilterVerifier available!");
14128            return;
14129        }
14130
14131        final int verifierUid = getPackageUid(
14132                mIntentFilterVerifierComponent.getPackageName(),
14133                MATCH_DEBUG_TRIAGED_MISSING,
14134                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
14135
14136        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
14137        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
14138        mHandler.sendMessage(msg);
14139
14140        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
14141        for (int i = 0; i < childCount; i++) {
14142            PackageParser.Package childPkg = pkg.childPackages.get(i);
14143            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
14144            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
14145            mHandler.sendMessage(msg);
14146        }
14147    }
14148
14149    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
14150            PackageParser.Package pkg) {
14151        int size = pkg.activities.size();
14152        if (size == 0) {
14153            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
14154                    "No activity, so no need to verify any IntentFilter!");
14155            return;
14156        }
14157
14158        final boolean hasDomainURLs = hasDomainURLs(pkg);
14159        if (!hasDomainURLs) {
14160            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
14161                    "No domain URLs, so no need to verify any IntentFilter!");
14162            return;
14163        }
14164
14165        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
14166                + " if any IntentFilter from the " + size
14167                + " Activities needs verification ...");
14168
14169        int count = 0;
14170        final String packageName = pkg.packageName;
14171
14172        synchronized (mPackages) {
14173            // If this is a new install and we see that we've already run verification for this
14174            // package, we have nothing to do: it means the state was restored from backup.
14175            if (!replacing) {
14176                IntentFilterVerificationInfo ivi =
14177                        mSettings.getIntentFilterVerificationLPr(packageName);
14178                if (ivi != null) {
14179                    if (DEBUG_DOMAIN_VERIFICATION) {
14180                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
14181                                + ivi.getStatusString());
14182                    }
14183                    return;
14184                }
14185            }
14186
14187            // If any filters need to be verified, then all need to be.
14188            boolean needToVerify = false;
14189            for (PackageParser.Activity a : pkg.activities) {
14190                for (ActivityIntentInfo filter : a.intents) {
14191                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
14192                        if (DEBUG_DOMAIN_VERIFICATION) {
14193                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
14194                        }
14195                        needToVerify = true;
14196                        break;
14197                    }
14198                }
14199            }
14200
14201            if (needToVerify) {
14202                final int verificationId = mIntentFilterVerificationToken++;
14203                for (PackageParser.Activity a : pkg.activities) {
14204                    for (ActivityIntentInfo filter : a.intents) {
14205                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
14206                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
14207                                    "Verification needed for IntentFilter:" + filter.toString());
14208                            mIntentFilterVerifier.addOneIntentFilterVerification(
14209                                    verifierUid, userId, verificationId, filter, packageName);
14210                            count++;
14211                        }
14212                    }
14213                }
14214            }
14215        }
14216
14217        if (count > 0) {
14218            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
14219                    + " IntentFilter verification" + (count > 1 ? "s" : "")
14220                    +  " for userId:" + userId);
14221            mIntentFilterVerifier.startVerifications(userId);
14222        } else {
14223            if (DEBUG_DOMAIN_VERIFICATION) {
14224                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
14225            }
14226        }
14227    }
14228
14229    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
14230        final ComponentName cn  = filter.activity.getComponentName();
14231        final String packageName = cn.getPackageName();
14232
14233        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
14234                packageName);
14235        if (ivi == null) {
14236            return true;
14237        }
14238        int status = ivi.getStatus();
14239        switch (status) {
14240            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
14241            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
14242                return true;
14243
14244            default:
14245                // Nothing to do
14246                return false;
14247        }
14248    }
14249
14250    private static boolean isMultiArch(ApplicationInfo info) {
14251        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
14252    }
14253
14254    private static boolean isExternal(PackageParser.Package pkg) {
14255        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
14256    }
14257
14258    private static boolean isExternal(PackageSetting ps) {
14259        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
14260    }
14261
14262    private static boolean isEphemeral(PackageParser.Package pkg) {
14263        return pkg.applicationInfo.isEphemeralApp();
14264    }
14265
14266    private static boolean isEphemeral(PackageSetting ps) {
14267        return ps.pkg != null && isEphemeral(ps.pkg);
14268    }
14269
14270    private static boolean isSystemApp(PackageParser.Package pkg) {
14271        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
14272    }
14273
14274    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
14275        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
14276    }
14277
14278    private static boolean hasDomainURLs(PackageParser.Package pkg) {
14279        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
14280    }
14281
14282    private static boolean isSystemApp(PackageSetting ps) {
14283        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
14284    }
14285
14286    private static boolean isUpdatedSystemApp(PackageSetting ps) {
14287        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
14288    }
14289
14290    private int packageFlagsToInstallFlags(PackageSetting ps) {
14291        int installFlags = 0;
14292        if (isEphemeral(ps)) {
14293            installFlags |= PackageManager.INSTALL_EPHEMERAL;
14294        }
14295        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
14296            // This existing package was an external ASEC install when we have
14297            // the external flag without a UUID
14298            installFlags |= PackageManager.INSTALL_EXTERNAL;
14299        }
14300        if (ps.isForwardLocked()) {
14301            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
14302        }
14303        return installFlags;
14304    }
14305
14306    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
14307        if (isExternal(pkg)) {
14308            if (TextUtils.isEmpty(pkg.volumeUuid)) {
14309                return StorageManager.UUID_PRIMARY_PHYSICAL;
14310            } else {
14311                return pkg.volumeUuid;
14312            }
14313        } else {
14314            return StorageManager.UUID_PRIVATE_INTERNAL;
14315        }
14316    }
14317
14318    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
14319        if (isExternal(pkg)) {
14320            if (TextUtils.isEmpty(pkg.volumeUuid)) {
14321                return mSettings.getExternalVersion();
14322            } else {
14323                return mSettings.findOrCreateVersion(pkg.volumeUuid);
14324            }
14325        } else {
14326            return mSettings.getInternalVersion();
14327        }
14328    }
14329
14330    private void deleteTempPackageFiles() {
14331        final FilenameFilter filter = new FilenameFilter() {
14332            public boolean accept(File dir, String name) {
14333                return name.startsWith("vmdl") && name.endsWith(".tmp");
14334            }
14335        };
14336        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
14337            file.delete();
14338        }
14339    }
14340
14341    @Override
14342    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
14343            int flags) {
14344        deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
14345                flags);
14346    }
14347
14348    @Override
14349    public void deletePackage(final String packageName,
14350            final IPackageDeleteObserver2 observer, final int userId, final int flags) {
14351        mContext.enforceCallingOrSelfPermission(
14352                android.Manifest.permission.DELETE_PACKAGES, null);
14353        Preconditions.checkNotNull(packageName);
14354        Preconditions.checkNotNull(observer);
14355        final int uid = Binder.getCallingUid();
14356        final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0;
14357        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
14358        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
14359            mContext.enforceCallingOrSelfPermission(
14360                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14361                    "deletePackage for user " + userId);
14362        }
14363
14364        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
14365            try {
14366                observer.onPackageDeleted(packageName,
14367                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
14368            } catch (RemoteException re) {
14369            }
14370            return;
14371        }
14372
14373        if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) {
14374            try {
14375                observer.onPackageDeleted(packageName,
14376                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
14377            } catch (RemoteException re) {
14378            }
14379            return;
14380        }
14381
14382        if (DEBUG_REMOVE) {
14383            Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId
14384                    + " deleteAllUsers: " + deleteAllUsers );
14385        }
14386        // Queue up an async operation since the package deletion may take a little while.
14387        mHandler.post(new Runnable() {
14388            public void run() {
14389                mHandler.removeCallbacks(this);
14390                int returnCode;
14391                if (!deleteAllUsers) {
14392                    returnCode = deletePackageX(packageName, userId, flags);
14393                } else {
14394                    int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users);
14395                    // If nobody is blocking uninstall, proceed with delete for all users
14396                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
14397                        returnCode = deletePackageX(packageName, userId, flags);
14398                    } else {
14399                        // Otherwise uninstall individually for users with blockUninstalls=false
14400                        final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS;
14401                        for (int userId : users) {
14402                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
14403                                returnCode = deletePackageX(packageName, userId, userFlags);
14404                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
14405                                    Slog.w(TAG, "Package delete failed for user " + userId
14406                                            + ", returnCode " + returnCode);
14407                                }
14408                            }
14409                        }
14410                        // The app has only been marked uninstalled for certain users.
14411                        // We still need to report that delete was blocked
14412                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
14413                    }
14414                }
14415                try {
14416                    observer.onPackageDeleted(packageName, returnCode, null);
14417                } catch (RemoteException e) {
14418                    Log.i(TAG, "Observer no longer exists.");
14419                } //end catch
14420            } //end run
14421        });
14422    }
14423
14424    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
14425        int[] result = EMPTY_INT_ARRAY;
14426        for (int userId : userIds) {
14427            if (getBlockUninstallForUser(packageName, userId)) {
14428                result = ArrayUtils.appendInt(result, userId);
14429            }
14430        }
14431        return result;
14432    }
14433
14434    @Override
14435    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
14436        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
14437    }
14438
14439    private boolean isPackageDeviceAdmin(String packageName, int userId) {
14440        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14441                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14442        try {
14443            if (dpm != null) {
14444                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
14445                        /* callingUserOnly =*/ false);
14446                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
14447                        : deviceOwnerComponentName.getPackageName();
14448                // Does the package contains the device owner?
14449                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
14450                // this check is probably not needed, since DO should be registered as a device
14451                // admin on some user too. (Original bug for this: b/17657954)
14452                if (packageName.equals(deviceOwnerPackageName)) {
14453                    return true;
14454                }
14455                // Does it contain a device admin for any user?
14456                int[] users;
14457                if (userId == UserHandle.USER_ALL) {
14458                    users = sUserManager.getUserIds();
14459                } else {
14460                    users = new int[]{userId};
14461                }
14462                for (int i = 0; i < users.length; ++i) {
14463                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
14464                        return true;
14465                    }
14466                }
14467            }
14468        } catch (RemoteException e) {
14469        }
14470        return false;
14471    }
14472
14473    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
14474        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
14475    }
14476
14477    /**
14478     *  This method is an internal method that could be get invoked either
14479     *  to delete an installed package or to clean up a failed installation.
14480     *  After deleting an installed package, a broadcast is sent to notify any
14481     *  listeners that the package has been installed. For cleaning up a failed
14482     *  installation, the broadcast is not necessary since the package's
14483     *  installation wouldn't have sent the initial broadcast either
14484     *  The key steps in deleting a package are
14485     *  deleting the package information in internal structures like mPackages,
14486     *  deleting the packages base directories through installd
14487     *  updating mSettings to reflect current status
14488     *  persisting settings for later use
14489     *  sending a broadcast if necessary
14490     */
14491    private int deletePackageX(String packageName, int userId, int flags) {
14492        final PackageRemovedInfo info = new PackageRemovedInfo();
14493        final boolean res;
14494
14495        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
14496                ? UserHandle.ALL : new UserHandle(userId);
14497
14498        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
14499            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
14500            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
14501        }
14502
14503        PackageSetting uninstalledPs = null;
14504
14505        // for the uninstall-updates case and restricted profiles, remember the per-
14506        // user handle installed state
14507        int[] allUsers;
14508        synchronized (mPackages) {
14509            uninstalledPs = mSettings.mPackages.get(packageName);
14510            if (uninstalledPs == null) {
14511                Slog.w(TAG, "Not removing non-existent package " + packageName);
14512                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
14513            }
14514            allUsers = sUserManager.getUserIds();
14515            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
14516        }
14517
14518        synchronized (mInstallLock) {
14519            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
14520            res = deletePackageLI(packageName, removeForUser, true, allUsers,
14521                    flags | REMOVE_CHATTY, info, true, null);
14522            synchronized (mPackages) {
14523                if (res) {
14524                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
14525                }
14526            }
14527        }
14528
14529        if (res) {
14530            final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0;
14531            info.sendPackageRemovedBroadcasts(killApp);
14532            info.sendSystemPackageUpdatedBroadcasts();
14533            info.sendSystemPackageAppearedBroadcasts();
14534        }
14535        // Force a gc here.
14536        Runtime.getRuntime().gc();
14537        // Delete the resources here after sending the broadcast to let
14538        // other processes clean up before deleting resources.
14539        if (info.args != null) {
14540            synchronized (mInstallLock) {
14541                info.args.doPostDeleteLI(true);
14542            }
14543        }
14544
14545        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
14546    }
14547
14548    class PackageRemovedInfo {
14549        String removedPackage;
14550        int uid = -1;
14551        int removedAppId = -1;
14552        int[] origUsers;
14553        int[] removedUsers = null;
14554        boolean isRemovedPackageSystemUpdate = false;
14555        boolean isUpdate;
14556        boolean dataRemoved;
14557        boolean removedForAllUsers;
14558        // Clean up resources deleted packages.
14559        InstallArgs args = null;
14560        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
14561        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
14562
14563        void sendPackageRemovedBroadcasts(boolean killApp) {
14564            sendPackageRemovedBroadcastInternal(killApp);
14565            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
14566            for (int i = 0; i < childCount; i++) {
14567                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
14568                childInfo.sendPackageRemovedBroadcastInternal(killApp);
14569            }
14570        }
14571
14572        void sendSystemPackageUpdatedBroadcasts() {
14573            if (isRemovedPackageSystemUpdate) {
14574                sendSystemPackageUpdatedBroadcastsInternal();
14575                final int childCount = (removedChildPackages != null)
14576                        ? removedChildPackages.size() : 0;
14577                for (int i = 0; i < childCount; i++) {
14578                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
14579                    if (childInfo.isRemovedPackageSystemUpdate) {
14580                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
14581                    }
14582                }
14583            }
14584        }
14585
14586        void sendSystemPackageAppearedBroadcasts() {
14587            final int packageCount = (appearedChildPackages != null)
14588                    ? appearedChildPackages.size() : 0;
14589            for (int i = 0; i < packageCount; i++) {
14590                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
14591                for (int userId : installedInfo.newUsers) {
14592                    sendPackageAddedForUser(installedInfo.name, true,
14593                            UserHandle.getAppId(installedInfo.uid), userId);
14594                }
14595            }
14596        }
14597
14598        private void sendSystemPackageUpdatedBroadcastsInternal() {
14599            Bundle extras = new Bundle(2);
14600            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
14601            extras.putBoolean(Intent.EXTRA_REPLACING, true);
14602            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
14603                    extras, 0, null, null, null);
14604            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
14605                    extras, 0, null, null, null);
14606            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
14607                    null, 0, removedPackage, null, null);
14608        }
14609
14610        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
14611            Bundle extras = new Bundle(2);
14612            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
14613            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
14614            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
14615            if (isUpdate || isRemovedPackageSystemUpdate) {
14616                extras.putBoolean(Intent.EXTRA_REPLACING, true);
14617            }
14618            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
14619            if (removedPackage != null) {
14620                sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
14621                        extras, 0, null, null, removedUsers);
14622                if (dataRemoved && !isRemovedPackageSystemUpdate) {
14623                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
14624                            removedPackage, extras, 0, null, null, removedUsers);
14625                }
14626            }
14627            if (removedAppId >= 0) {
14628                sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
14629                        removedUsers);
14630            }
14631        }
14632    }
14633
14634    /*
14635     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
14636     * flag is not set, the data directory is removed as well.
14637     * make sure this flag is set for partially installed apps. If not its meaningless to
14638     * delete a partially installed application.
14639     */
14640    private void removePackageDataLI(PackageSetting ps, int[] allUserHandles,
14641            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
14642        String packageName = ps.name;
14643        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
14644        removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
14645        // Retrieve object to delete permissions for shared user later on
14646        final PackageSetting deletedPs;
14647        // reader
14648        synchronized (mPackages) {
14649            deletedPs = mSettings.mPackages.get(packageName);
14650            if (outInfo != null) {
14651                outInfo.removedPackage = packageName;
14652                outInfo.removedUsers = deletedPs != null
14653                        ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
14654                        : null;
14655            }
14656        }
14657        if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
14658            removeDataDirsLI(ps.volumeUuid, packageName);
14659            if (outInfo != null) {
14660                outInfo.dataRemoved = true;
14661            }
14662            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
14663        }
14664        // writer
14665        synchronized (mPackages) {
14666            if (deletedPs != null) {
14667                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
14668                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
14669                    clearDefaultBrowserIfNeeded(packageName);
14670                    if (outInfo != null) {
14671                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
14672                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
14673                    }
14674                    updatePermissionsLPw(deletedPs.name, null, 0);
14675                    if (deletedPs.sharedUser != null) {
14676                        // Remove permissions associated with package. Since runtime
14677                        // permissions are per user we have to kill the removed package
14678                        // or packages running under the shared user of the removed
14679                        // package if revoking the permissions requested only by the removed
14680                        // package is successful and this causes a change in gids.
14681                        for (int userId : UserManagerService.getInstance().getUserIds()) {
14682                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
14683                                    userId);
14684                            if (userIdToKill == UserHandle.USER_ALL
14685                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
14686                                // If gids changed for this user, kill all affected packages.
14687                                mHandler.post(new Runnable() {
14688                                    @Override
14689                                    public void run() {
14690                                        // This has to happen with no lock held.
14691                                        killApplication(deletedPs.name, deletedPs.appId,
14692                                                KILL_APP_REASON_GIDS_CHANGED);
14693                                    }
14694                                });
14695                                break;
14696                            }
14697                        }
14698                    }
14699                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
14700                }
14701                // make sure to preserve per-user disabled state if this removal was just
14702                // a downgrade of a system app to the factory package
14703                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
14704                    if (DEBUG_REMOVE) {
14705                        Slog.d(TAG, "Propagating install state across downgrade");
14706                    }
14707                    for (int userId : allUserHandles) {
14708                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
14709                        if (DEBUG_REMOVE) {
14710                            Slog.d(TAG, "    user " + userId + " => " + installed);
14711                        }
14712                        ps.setInstalled(installed, userId);
14713                    }
14714                }
14715            }
14716            // can downgrade to reader
14717            if (writeSettings) {
14718                // Save settings now
14719                mSettings.writeLPr();
14720            }
14721        }
14722        if (outInfo != null) {
14723            // A user ID was deleted here. Go through all users and remove it
14724            // from KeyStore.
14725            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
14726        }
14727    }
14728
14729    static boolean locationIsPrivileged(File path) {
14730        try {
14731            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
14732                    .getCanonicalPath();
14733            return path.getCanonicalPath().startsWith(privilegedAppDir);
14734        } catch (IOException e) {
14735            Slog.e(TAG, "Unable to access code path " + path);
14736        }
14737        return false;
14738    }
14739
14740    /*
14741     * Tries to delete system package.
14742     */
14743    private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg,
14744            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
14745            boolean writeSettings) {
14746        if (deletedPs.parentPackageName != null) {
14747            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
14748            return false;
14749        }
14750
14751        final boolean applyUserRestrictions
14752                = (allUserHandles != null) && (outInfo.origUsers != null);
14753        final PackageSetting disabledPs;
14754        // Confirm if the system package has been updated
14755        // An updated system app can be deleted. This will also have to restore
14756        // the system pkg from system partition
14757        // reader
14758        synchronized (mPackages) {
14759            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
14760        }
14761
14762        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
14763                + " disabledPs=" + disabledPs);
14764
14765        if (disabledPs == null) {
14766            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
14767            return false;
14768        } else if (DEBUG_REMOVE) {
14769            Slog.d(TAG, "Deleting system pkg from data partition");
14770        }
14771
14772        if (DEBUG_REMOVE) {
14773            if (applyUserRestrictions) {
14774                Slog.d(TAG, "Remembering install states:");
14775                for (int userId : allUserHandles) {
14776                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
14777                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
14778                }
14779            }
14780        }
14781
14782        // Delete the updated package
14783        outInfo.isRemovedPackageSystemUpdate = true;
14784        if (outInfo.removedChildPackages != null) {
14785            final int childCount = (deletedPs.childPackageNames != null)
14786                    ? deletedPs.childPackageNames.size() : 0;
14787            for (int i = 0; i < childCount; i++) {
14788                String childPackageName = deletedPs.childPackageNames.get(i);
14789                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
14790                        .contains(childPackageName)) {
14791                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
14792                            childPackageName);
14793                    if (childInfo != null) {
14794                        childInfo.isRemovedPackageSystemUpdate = true;
14795                    }
14796                }
14797            }
14798        }
14799
14800        if (disabledPs.versionCode < deletedPs.versionCode) {
14801            // Delete data for downgrades
14802            flags &= ~PackageManager.DELETE_KEEP_DATA;
14803        } else {
14804            // Preserve data by setting flag
14805            flags |= PackageManager.DELETE_KEEP_DATA;
14806        }
14807
14808        boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles,
14809                outInfo, writeSettings, disabledPs.pkg);
14810        if (!ret) {
14811            return false;
14812        }
14813
14814        // writer
14815        synchronized (mPackages) {
14816            // Reinstate the old system package
14817            enableSystemPackageLPw(disabledPs.pkg);
14818            // Remove any native libraries from the upgraded package.
14819            removeNativeBinariesLI(deletedPs);
14820        }
14821
14822        // Install the system package
14823        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
14824        int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
14825        if (locationIsPrivileged(disabledPs.codePath)) {
14826            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
14827        }
14828
14829        final PackageParser.Package newPkg;
14830        try {
14831            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
14832        } catch (PackageManagerException e) {
14833            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
14834                    + e.getMessage());
14835            return false;
14836        }
14837
14838        prepareAppDataAfterInstall(newPkg);
14839
14840        // writer
14841        synchronized (mPackages) {
14842            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
14843
14844            // Propagate the permissions state as we do not want to drop on the floor
14845            // runtime permissions. The update permissions method below will take
14846            // care of removing obsolete permissions and grant install permissions.
14847            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
14848            updatePermissionsLPw(newPkg.packageName, newPkg,
14849                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
14850
14851            if (applyUserRestrictions) {
14852                if (DEBUG_REMOVE) {
14853                    Slog.d(TAG, "Propagating install state across reinstall");
14854                }
14855                for (int userId : allUserHandles) {
14856                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
14857                    if (DEBUG_REMOVE) {
14858                        Slog.d(TAG, "    user " + userId + " => " + installed);
14859                    }
14860                    ps.setInstalled(installed, userId);
14861
14862                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
14863                }
14864                // Regardless of writeSettings we need to ensure that this restriction
14865                // state propagation is persisted
14866                mSettings.writeAllUsersPackageRestrictionsLPr();
14867            }
14868            // can downgrade to reader here
14869            if (writeSettings) {
14870                mSettings.writeLPr();
14871            }
14872        }
14873        return true;
14874    }
14875
14876    private boolean deleteInstalledPackageLI(PackageSetting ps,
14877            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
14878            PackageRemovedInfo outInfo, boolean writeSettings,
14879            PackageParser.Package replacingPackage) {
14880        synchronized (mPackages) {
14881            if (outInfo != null) {
14882                outInfo.uid = ps.appId;
14883            }
14884
14885            if (outInfo != null && outInfo.removedChildPackages != null) {
14886                final int childCount = (ps.childPackageNames != null)
14887                        ? ps.childPackageNames.size() : 0;
14888                for (int i = 0; i < childCount; i++) {
14889                    String childPackageName = ps.childPackageNames.get(i);
14890                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
14891                    if (childPs == null) {
14892                        return false;
14893                    }
14894                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
14895                            childPackageName);
14896                    if (childInfo != null) {
14897                        childInfo.uid = childPs.appId;
14898                    }
14899                }
14900            }
14901        }
14902
14903        // Delete package data from internal structures and also remove data if flag is set
14904        removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings);
14905
14906        // Delete the child packages data
14907        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
14908        for (int i = 0; i < childCount; i++) {
14909            PackageSetting childPs;
14910            synchronized (mPackages) {
14911                childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i));
14912            }
14913            if (childPs != null) {
14914                PackageRemovedInfo childOutInfo = (outInfo != null
14915                        && outInfo.removedChildPackages != null)
14916                        ? outInfo.removedChildPackages.get(childPs.name) : null;
14917                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
14918                        && (replacingPackage != null
14919                        && !replacingPackage.hasChildPackage(childPs.name))
14920                        ? flags & ~DELETE_KEEP_DATA : flags;
14921                removePackageDataLI(childPs, allUserHandles, childOutInfo,
14922                        deleteFlags, writeSettings);
14923            }
14924        }
14925
14926        // Delete application code and resources only for parent packages
14927        if (ps.parentPackageName == null) {
14928            if (deleteCodeAndResources && (outInfo != null)) {
14929                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
14930                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
14931                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
14932            }
14933        }
14934
14935        return true;
14936    }
14937
14938    @Override
14939    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
14940            int userId) {
14941        mContext.enforceCallingOrSelfPermission(
14942                android.Manifest.permission.DELETE_PACKAGES, null);
14943        synchronized (mPackages) {
14944            PackageSetting ps = mSettings.mPackages.get(packageName);
14945            if (ps == null) {
14946                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
14947                return false;
14948            }
14949            if (!ps.getInstalled(userId)) {
14950                // Can't block uninstall for an app that is not installed or enabled.
14951                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
14952                return false;
14953            }
14954            ps.setBlockUninstall(blockUninstall, userId);
14955            mSettings.writePackageRestrictionsLPr(userId);
14956        }
14957        return true;
14958    }
14959
14960    @Override
14961    public boolean getBlockUninstallForUser(String packageName, int userId) {
14962        synchronized (mPackages) {
14963            PackageSetting ps = mSettings.mPackages.get(packageName);
14964            if (ps == null) {
14965                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
14966                return false;
14967            }
14968            return ps.getBlockUninstall(userId);
14969        }
14970    }
14971
14972    @Override
14973    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
14974        int callingUid = Binder.getCallingUid();
14975        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
14976            throw new SecurityException(
14977                    "setRequiredForSystemUser can only be run by the system or root");
14978        }
14979        synchronized (mPackages) {
14980            PackageSetting ps = mSettings.mPackages.get(packageName);
14981            if (ps == null) {
14982                Log.w(TAG, "Package doesn't exist: " + packageName);
14983                return false;
14984            }
14985            if (systemUserApp) {
14986                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
14987            } else {
14988                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
14989            }
14990            mSettings.writeLPr();
14991        }
14992        return true;
14993    }
14994
14995    /*
14996     * This method handles package deletion in general
14997     */
14998    private boolean deletePackageLI(String packageName, UserHandle user,
14999            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
15000            PackageRemovedInfo outInfo, boolean writeSettings,
15001            PackageParser.Package replacingPackage) {
15002        if (packageName == null) {
15003            Slog.w(TAG, "Attempt to delete null packageName.");
15004            return false;
15005        }
15006
15007        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
15008
15009        PackageSetting ps;
15010
15011        synchronized (mPackages) {
15012            ps = mSettings.mPackages.get(packageName);
15013            if (ps == null) {
15014                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
15015                return false;
15016            }
15017
15018            if (ps.parentPackageName != null && (!isSystemApp(ps)
15019                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
15020                if (DEBUG_REMOVE) {
15021                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
15022                            + ((user == null) ? UserHandle.USER_ALL : user));
15023                }
15024                final int removedUserId = (user != null) ? user.getIdentifier()
15025                        : UserHandle.USER_ALL;
15026                if (!clearPackageStateForUser(ps, removedUserId, outInfo)) {
15027                    return false;
15028                }
15029                markPackageUninstalledForUserLPw(ps, user);
15030                scheduleWritePackageRestrictionsLocked(user);
15031                return true;
15032            }
15033        }
15034
15035        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
15036                && user.getIdentifier() != UserHandle.USER_ALL)) {
15037            // The caller is asking that the package only be deleted for a single
15038            // user.  To do this, we just mark its uninstalled state and delete
15039            // its data. If this is a system app, we only allow this to happen if
15040            // they have set the special DELETE_SYSTEM_APP which requests different
15041            // semantics than normal for uninstalling system apps.
15042            markPackageUninstalledForUserLPw(ps, user);
15043
15044            if (!isSystemApp(ps)) {
15045                // Do not uninstall the APK if an app should be cached
15046                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
15047                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
15048                    // Other user still have this package installed, so all
15049                    // we need to do is clear this user's data and save that
15050                    // it is uninstalled.
15051                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
15052                    if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
15053                        return false;
15054                    }
15055                    scheduleWritePackageRestrictionsLocked(user);
15056                    return true;
15057                } else {
15058                    // We need to set it back to 'installed' so the uninstall
15059                    // broadcasts will be sent correctly.
15060                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
15061                    ps.setInstalled(true, user.getIdentifier());
15062                }
15063            } else {
15064                // This is a system app, so we assume that the
15065                // other users still have this package installed, so all
15066                // we need to do is clear this user's data and save that
15067                // it is uninstalled.
15068                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
15069                if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
15070                    return false;
15071                }
15072                scheduleWritePackageRestrictionsLocked(user);
15073                return true;
15074            }
15075        }
15076
15077        // If we are deleting a composite package for all users, keep track
15078        // of result for each child.
15079        if (ps.childPackageNames != null && outInfo != null) {
15080            synchronized (mPackages) {
15081                final int childCount = ps.childPackageNames.size();
15082                outInfo.removedChildPackages = new ArrayMap<>(childCount);
15083                for (int i = 0; i < childCount; i++) {
15084                    String childPackageName = ps.childPackageNames.get(i);
15085                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
15086                    childInfo.removedPackage = childPackageName;
15087                    outInfo.removedChildPackages.put(childPackageName, childInfo);
15088                    PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
15089                    if (childPs != null) {
15090                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
15091                    }
15092                }
15093            }
15094        }
15095
15096        boolean ret = false;
15097        if (isSystemApp(ps)) {
15098            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
15099            // When an updated system application is deleted we delete the existing resources
15100            // as well and fall back to existing code in system partition
15101            ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
15102        } else {
15103            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
15104            // Kill application pre-emptively especially for apps on sd.
15105            final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0;
15106            if (killApp) {
15107                killApplication(packageName, ps.appId, "uninstall pkg");
15108            }
15109            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles,
15110                    outInfo, writeSettings, replacingPackage);
15111        }
15112
15113        // Take a note whether we deleted the package for all users
15114        if (outInfo != null) {
15115            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
15116            if (outInfo.removedChildPackages != null) {
15117                synchronized (mPackages) {
15118                    final int childCount = outInfo.removedChildPackages.size();
15119                    for (int i = 0; i < childCount; i++) {
15120                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
15121                        if (childInfo != null) {
15122                            childInfo.removedForAllUsers = mPackages.get(
15123                                    childInfo.removedPackage) == null;
15124                        }
15125                    }
15126                }
15127            }
15128            // If we uninstalled an update to a system app there may be some
15129            // child packages that appeared as they are declared in the system
15130            // app but were not declared in the update.
15131            if (isSystemApp(ps)) {
15132                synchronized (mPackages) {
15133                    PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
15134                    final int childCount = (updatedPs.childPackageNames != null)
15135                            ? updatedPs.childPackageNames.size() : 0;
15136                    for (int i = 0; i < childCount; i++) {
15137                        String childPackageName = updatedPs.childPackageNames.get(i);
15138                        if (outInfo.removedChildPackages == null
15139                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
15140                            PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
15141                            if (childPs == null) {
15142                                continue;
15143                            }
15144                            PackageInstalledInfo installRes = new PackageInstalledInfo();
15145                            installRes.name = childPackageName;
15146                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
15147                            installRes.pkg = mPackages.get(childPackageName);
15148                            installRes.uid = childPs.pkg.applicationInfo.uid;
15149                            if (outInfo.appearedChildPackages == null) {
15150                                outInfo.appearedChildPackages = new ArrayMap<>();
15151                            }
15152                            outInfo.appearedChildPackages.put(childPackageName, installRes);
15153                        }
15154                    }
15155                }
15156            }
15157        }
15158
15159        return ret;
15160    }
15161
15162    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
15163        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
15164                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
15165        for (int nextUserId : userIds) {
15166            if (DEBUG_REMOVE) {
15167                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
15168            }
15169            ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT,
15170                    false /*installed*/, true /*stopped*/, true /*notLaunched*/,
15171                    false /*hidden*/, false /*suspended*/, null, null, null,
15172                    false /*blockUninstall*/,
15173                    ps.readUserState(nextUserId).domainVerificationStatus, 0);
15174        }
15175    }
15176
15177    private boolean clearPackageStateForUser(PackageSetting ps, int userId,
15178            PackageRemovedInfo outInfo) {
15179        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
15180                : new int[] {userId};
15181        for (int nextUserId : userIds) {
15182            if (DEBUG_REMOVE) {
15183                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
15184                        + nextUserId);
15185            }
15186            final int flags =  StorageManager.FLAG_STORAGE_CE|  StorageManager.FLAG_STORAGE_DE;
15187            try {
15188                mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags);
15189            } catch (InstallerException e) {
15190                Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e);
15191                return false;
15192            }
15193            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
15194            schedulePackageCleaning(ps.name, nextUserId, false);
15195            synchronized (mPackages) {
15196                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
15197                    scheduleWritePackageRestrictionsLocked(nextUserId);
15198                }
15199                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
15200            }
15201        }
15202
15203        if (outInfo != null) {
15204            outInfo.removedPackage = ps.name;
15205            outInfo.removedAppId = ps.appId;
15206            outInfo.removedUsers = userIds;
15207        }
15208
15209        return true;
15210    }
15211
15212    private final class ClearStorageConnection implements ServiceConnection {
15213        IMediaContainerService mContainerService;
15214
15215        @Override
15216        public void onServiceConnected(ComponentName name, IBinder service) {
15217            synchronized (this) {
15218                mContainerService = IMediaContainerService.Stub.asInterface(service);
15219                notifyAll();
15220            }
15221        }
15222
15223        @Override
15224        public void onServiceDisconnected(ComponentName name) {
15225        }
15226    }
15227
15228    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
15229        final boolean mounted;
15230        if (Environment.isExternalStorageEmulated()) {
15231            mounted = true;
15232        } else {
15233            final String status = Environment.getExternalStorageState();
15234
15235            mounted = status.equals(Environment.MEDIA_MOUNTED)
15236                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
15237        }
15238
15239        if (!mounted) {
15240            return;
15241        }
15242
15243        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
15244        int[] users;
15245        if (userId == UserHandle.USER_ALL) {
15246            users = sUserManager.getUserIds();
15247        } else {
15248            users = new int[] { userId };
15249        }
15250        final ClearStorageConnection conn = new ClearStorageConnection();
15251        if (mContext.bindServiceAsUser(
15252                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
15253            try {
15254                for (int curUser : users) {
15255                    long timeout = SystemClock.uptimeMillis() + 5000;
15256                    synchronized (conn) {
15257                        long now = SystemClock.uptimeMillis();
15258                        while (conn.mContainerService == null && now < timeout) {
15259                            try {
15260                                conn.wait(timeout - now);
15261                            } catch (InterruptedException e) {
15262                            }
15263                        }
15264                    }
15265                    if (conn.mContainerService == null) {
15266                        return;
15267                    }
15268
15269                    final UserEnvironment userEnv = new UserEnvironment(curUser);
15270                    clearDirectory(conn.mContainerService,
15271                            userEnv.buildExternalStorageAppCacheDirs(packageName));
15272                    if (allData) {
15273                        clearDirectory(conn.mContainerService,
15274                                userEnv.buildExternalStorageAppDataDirs(packageName));
15275                        clearDirectory(conn.mContainerService,
15276                                userEnv.buildExternalStorageAppMediaDirs(packageName));
15277                    }
15278                }
15279            } finally {
15280                mContext.unbindService(conn);
15281            }
15282        }
15283    }
15284
15285    @Override
15286    public void clearApplicationProfileData(String packageName) {
15287        enforceSystemOrRoot("Only the system can clear all profile data");
15288        try {
15289            mInstaller.clearAppProfiles(packageName);
15290        } catch (InstallerException ex) {
15291            Log.e(TAG, "Could not clear profile data of package " + packageName);
15292        }
15293    }
15294
15295    @Override
15296    public void clearApplicationUserData(final String packageName,
15297            final IPackageDataObserver observer, final int userId) {
15298        mContext.enforceCallingOrSelfPermission(
15299                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
15300
15301        enforceCrossUserPermission(Binder.getCallingUid(), userId,
15302                true /* requireFullPermission */, false /* checkShell */, "clear application data");
15303
15304        final DevicePolicyManagerInternal dpmi = LocalServices
15305                .getService(DevicePolicyManagerInternal.class);
15306        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
15307            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
15308        }
15309        // Queue up an async operation since the package deletion may take a little while.
15310        mHandler.post(new Runnable() {
15311            public void run() {
15312                mHandler.removeCallbacks(this);
15313                final boolean succeeded;
15314                synchronized (mInstallLock) {
15315                    succeeded = clearApplicationUserDataLI(packageName, userId);
15316                }
15317                clearExternalStorageDataSync(packageName, userId, true);
15318                if (succeeded) {
15319                    // invoke DeviceStorageMonitor's update method to clear any notifications
15320                    DeviceStorageMonitorInternal dsm = LocalServices
15321                            .getService(DeviceStorageMonitorInternal.class);
15322                    if (dsm != null) {
15323                        dsm.checkMemory();
15324                    }
15325                }
15326                if(observer != null) {
15327                    try {
15328                        observer.onRemoveCompleted(packageName, succeeded);
15329                    } catch (RemoteException e) {
15330                        Log.i(TAG, "Observer no longer exists.");
15331                    }
15332                } //end if observer
15333            } //end run
15334        });
15335    }
15336
15337    private boolean clearApplicationUserDataLI(String packageName, int userId) {
15338        if (packageName == null) {
15339            Slog.w(TAG, "Attempt to delete null packageName.");
15340            return false;
15341        }
15342
15343        // Try finding details about the requested package
15344        PackageParser.Package pkg;
15345        synchronized (mPackages) {
15346            pkg = mPackages.get(packageName);
15347            if (pkg == null) {
15348                final PackageSetting ps = mSettings.mPackages.get(packageName);
15349                if (ps != null) {
15350                    pkg = ps.pkg;
15351                }
15352            }
15353
15354            if (pkg == null) {
15355                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
15356                return false;
15357            }
15358
15359            PackageSetting ps = (PackageSetting) pkg.mExtras;
15360            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
15361        }
15362
15363        // Always delete data directories for package, even if we found no other
15364        // record of app. This helps users recover from UID mismatches without
15365        // resorting to a full data wipe.
15366        // TODO: triage flags as part of 26466827
15367        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
15368        try {
15369            mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags);
15370        } catch (InstallerException e) {
15371            Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e);
15372            return false;
15373        }
15374
15375        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
15376        removeKeystoreDataIfNeeded(userId, appId);
15377
15378        // Create a native library symlink only if we have native libraries
15379        // and if the native libraries are 32 bit libraries. We do not provide
15380        // this symlink for 64 bit libraries.
15381        if (pkg.applicationInfo.primaryCpuAbi != null &&
15382                !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
15383            final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
15384            try {
15385                mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName,
15386                        nativeLibPath, userId);
15387            } catch (InstallerException e) {
15388                Slog.w(TAG, "Failed linking native library dir", e);
15389                return false;
15390            }
15391        }
15392
15393        return true;
15394    }
15395
15396    /**
15397     * Reverts user permission state changes (permissions and flags) in
15398     * all packages for a given user.
15399     *
15400     * @param userId The device user for which to do a reset.
15401     */
15402    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
15403        final int packageCount = mPackages.size();
15404        for (int i = 0; i < packageCount; i++) {
15405            PackageParser.Package pkg = mPackages.valueAt(i);
15406            PackageSetting ps = (PackageSetting) pkg.mExtras;
15407            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
15408        }
15409    }
15410
15411    /**
15412     * Reverts user permission state changes (permissions and flags).
15413     *
15414     * @param ps The package for which to reset.
15415     * @param userId The device user for which to do a reset.
15416     */
15417    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
15418            final PackageSetting ps, final int userId) {
15419        if (ps.pkg == null) {
15420            return;
15421        }
15422
15423        // These are flags that can change base on user actions.
15424        final int userSettableMask = FLAG_PERMISSION_USER_SET
15425                | FLAG_PERMISSION_USER_FIXED
15426                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
15427                | FLAG_PERMISSION_REVIEW_REQUIRED;
15428
15429        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
15430                | FLAG_PERMISSION_POLICY_FIXED;
15431
15432        boolean writeInstallPermissions = false;
15433        boolean writeRuntimePermissions = false;
15434
15435        final int permissionCount = ps.pkg.requestedPermissions.size();
15436        for (int i = 0; i < permissionCount; i++) {
15437            String permission = ps.pkg.requestedPermissions.get(i);
15438
15439            BasePermission bp = mSettings.mPermissions.get(permission);
15440            if (bp == null) {
15441                continue;
15442            }
15443
15444            // If shared user we just reset the state to which only this app contributed.
15445            if (ps.sharedUser != null) {
15446                boolean used = false;
15447                final int packageCount = ps.sharedUser.packages.size();
15448                for (int j = 0; j < packageCount; j++) {
15449                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
15450                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
15451                            && pkg.pkg.requestedPermissions.contains(permission)) {
15452                        used = true;
15453                        break;
15454                    }
15455                }
15456                if (used) {
15457                    continue;
15458                }
15459            }
15460
15461            PermissionsState permissionsState = ps.getPermissionsState();
15462
15463            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
15464
15465            // Always clear the user settable flags.
15466            final boolean hasInstallState = permissionsState.getInstallPermissionState(
15467                    bp.name) != null;
15468            // If permission review is enabled and this is a legacy app, mark the
15469            // permission as requiring a review as this is the initial state.
15470            int flags = 0;
15471            if (Build.PERMISSIONS_REVIEW_REQUIRED
15472                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
15473                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
15474            }
15475            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
15476                if (hasInstallState) {
15477                    writeInstallPermissions = true;
15478                } else {
15479                    writeRuntimePermissions = true;
15480                }
15481            }
15482
15483            // Below is only runtime permission handling.
15484            if (!bp.isRuntime()) {
15485                continue;
15486            }
15487
15488            // Never clobber system or policy.
15489            if ((oldFlags & policyOrSystemFlags) != 0) {
15490                continue;
15491            }
15492
15493            // If this permission was granted by default, make sure it is.
15494            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
15495                if (permissionsState.grantRuntimePermission(bp, userId)
15496                        != PERMISSION_OPERATION_FAILURE) {
15497                    writeRuntimePermissions = true;
15498                }
15499            // If permission review is enabled the permissions for a legacy apps
15500            // are represented as constantly granted runtime ones, so don't revoke.
15501            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
15502                // Otherwise, reset the permission.
15503                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
15504                switch (revokeResult) {
15505                    case PERMISSION_OPERATION_SUCCESS:
15506                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
15507                        writeRuntimePermissions = true;
15508                        final int appId = ps.appId;
15509                        mHandler.post(new Runnable() {
15510                            @Override
15511                            public void run() {
15512                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
15513                            }
15514                        });
15515                    } break;
15516                }
15517            }
15518        }
15519
15520        // Synchronously write as we are taking permissions away.
15521        if (writeRuntimePermissions) {
15522            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
15523        }
15524
15525        // Synchronously write as we are taking permissions away.
15526        if (writeInstallPermissions) {
15527            mSettings.writeLPr();
15528        }
15529    }
15530
15531    /**
15532     * Remove entries from the keystore daemon. Will only remove it if the
15533     * {@code appId} is valid.
15534     */
15535    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
15536        if (appId < 0) {
15537            return;
15538        }
15539
15540        final KeyStore keyStore = KeyStore.getInstance();
15541        if (keyStore != null) {
15542            if (userId == UserHandle.USER_ALL) {
15543                for (final int individual : sUserManager.getUserIds()) {
15544                    keyStore.clearUid(UserHandle.getUid(individual, appId));
15545                }
15546            } else {
15547                keyStore.clearUid(UserHandle.getUid(userId, appId));
15548            }
15549        } else {
15550            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
15551        }
15552    }
15553
15554    @Override
15555    public void deleteApplicationCacheFiles(final String packageName,
15556            final IPackageDataObserver observer) {
15557        mContext.enforceCallingOrSelfPermission(
15558                android.Manifest.permission.DELETE_CACHE_FILES, null);
15559        // Queue up an async operation since the package deletion may take a little while.
15560        final int userId = UserHandle.getCallingUserId();
15561        mHandler.post(new Runnable() {
15562            public void run() {
15563                mHandler.removeCallbacks(this);
15564                final boolean succeded;
15565                synchronized (mInstallLock) {
15566                    succeded = deleteApplicationCacheFilesLI(packageName, userId);
15567                }
15568                clearExternalStorageDataSync(packageName, userId, false);
15569                if (observer != null) {
15570                    try {
15571                        observer.onRemoveCompleted(packageName, succeded);
15572                    } catch (RemoteException e) {
15573                        Log.i(TAG, "Observer no longer exists.");
15574                    }
15575                } //end if observer
15576            } //end run
15577        });
15578    }
15579
15580    private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
15581        if (packageName == null) {
15582            Slog.w(TAG, "Attempt to delete null packageName.");
15583            return false;
15584        }
15585        PackageParser.Package p;
15586        synchronized (mPackages) {
15587            p = mPackages.get(packageName);
15588        }
15589        if (p == null) {
15590            Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
15591            return false;
15592        }
15593        final ApplicationInfo applicationInfo = p.applicationInfo;
15594        if (applicationInfo == null) {
15595            Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
15596            return false;
15597        }
15598        // TODO: triage flags as part of 26466827
15599        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
15600        try {
15601            mInstaller.clearAppData(p.volumeUuid, packageName, userId,
15602                    flags | Installer.FLAG_CLEAR_CACHE_ONLY);
15603        } catch (InstallerException e) {
15604            Slog.w(TAG, "Couldn't remove cache files for package "
15605                    + packageName + " u" + userId, e);
15606            return false;
15607        }
15608        return true;
15609    }
15610
15611    @Override
15612    public void getPackageSizeInfo(final String packageName, int userHandle,
15613            final IPackageStatsObserver observer) {
15614        mContext.enforceCallingOrSelfPermission(
15615                android.Manifest.permission.GET_PACKAGE_SIZE, null);
15616        if (packageName == null) {
15617            throw new IllegalArgumentException("Attempt to get size of null packageName");
15618        }
15619
15620        PackageStats stats = new PackageStats(packageName, userHandle);
15621
15622        /*
15623         * Queue up an async operation since the package measurement may take a
15624         * little while.
15625         */
15626        Message msg = mHandler.obtainMessage(INIT_COPY);
15627        msg.obj = new MeasureParams(stats, observer);
15628        mHandler.sendMessage(msg);
15629    }
15630
15631    private boolean getPackageSizeInfoLI(String packageName, int userHandle,
15632            PackageStats pStats) {
15633        if (packageName == null) {
15634            Slog.w(TAG, "Attempt to get size of null packageName.");
15635            return false;
15636        }
15637        PackageParser.Package p;
15638        boolean dataOnly = false;
15639        String libDirRoot = null;
15640        String asecPath = null;
15641        PackageSetting ps = null;
15642        synchronized (mPackages) {
15643            p = mPackages.get(packageName);
15644            ps = mSettings.mPackages.get(packageName);
15645            if(p == null) {
15646                dataOnly = true;
15647                if((ps == null) || (ps.pkg == null)) {
15648                    Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
15649                    return false;
15650                }
15651                p = ps.pkg;
15652            }
15653            if (ps != null) {
15654                libDirRoot = ps.legacyNativeLibraryPathString;
15655            }
15656            if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) {
15657                final long token = Binder.clearCallingIdentity();
15658                try {
15659                    String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
15660                    if (secureContainerId != null) {
15661                        asecPath = PackageHelper.getSdFilesystem(secureContainerId);
15662                    }
15663                } finally {
15664                    Binder.restoreCallingIdentity(token);
15665                }
15666            }
15667        }
15668        String publicSrcDir = null;
15669        if(!dataOnly) {
15670            final ApplicationInfo applicationInfo = p.applicationInfo;
15671            if (applicationInfo == null) {
15672                Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
15673                return false;
15674            }
15675            if (p.isForwardLocked()) {
15676                publicSrcDir = applicationInfo.getBaseResourcePath();
15677            }
15678        }
15679        // TODO: extend to measure size of split APKs
15680        // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
15681        // not just the first level.
15682        // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
15683        // just the primary.
15684        String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
15685
15686        String apkPath;
15687        File packageDir = new File(p.codePath);
15688
15689        if (packageDir.isDirectory() && p.canHaveOatDir()) {
15690            apkPath = packageDir.getAbsolutePath();
15691            // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice
15692            if (libDirRoot != null && libDirRoot.startsWith(apkPath)) {
15693                libDirRoot = null;
15694            }
15695        } else {
15696            apkPath = p.baseCodePath;
15697        }
15698
15699        // TODO: triage flags as part of 26466827
15700        final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
15701        try {
15702            mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath,
15703                    libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
15704        } catch (InstallerException e) {
15705            return false;
15706        }
15707
15708        // Fix-up for forward-locked applications in ASEC containers.
15709        if (!isExternal(p)) {
15710            pStats.codeSize += pStats.externalCodeSize;
15711            pStats.externalCodeSize = 0L;
15712        }
15713
15714        return true;
15715    }
15716
15717    private int getUidTargetSdkVersionLockedLPr(int uid) {
15718        Object obj = mSettings.getUserIdLPr(uid);
15719        if (obj instanceof SharedUserSetting) {
15720            final SharedUserSetting sus = (SharedUserSetting) obj;
15721            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
15722            final Iterator<PackageSetting> it = sus.packages.iterator();
15723            while (it.hasNext()) {
15724                final PackageSetting ps = it.next();
15725                if (ps.pkg != null) {
15726                    int v = ps.pkg.applicationInfo.targetSdkVersion;
15727                    if (v < vers) vers = v;
15728                }
15729            }
15730            return vers;
15731        } else if (obj instanceof PackageSetting) {
15732            final PackageSetting ps = (PackageSetting) obj;
15733            if (ps.pkg != null) {
15734                return ps.pkg.applicationInfo.targetSdkVersion;
15735            }
15736        }
15737        return Build.VERSION_CODES.CUR_DEVELOPMENT;
15738    }
15739
15740    @Override
15741    public void addPreferredActivity(IntentFilter filter, int match,
15742            ComponentName[] set, ComponentName activity, int userId) {
15743        addPreferredActivityInternal(filter, match, set, activity, true, userId,
15744                "Adding preferred");
15745    }
15746
15747    private void addPreferredActivityInternal(IntentFilter filter, int match,
15748            ComponentName[] set, ComponentName activity, boolean always, int userId,
15749            String opname) {
15750        // writer
15751        int callingUid = Binder.getCallingUid();
15752        enforceCrossUserPermission(callingUid, userId,
15753                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
15754        if (filter.countActions() == 0) {
15755            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
15756            return;
15757        }
15758        synchronized (mPackages) {
15759            if (mContext.checkCallingOrSelfPermission(
15760                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
15761                    != PackageManager.PERMISSION_GRANTED) {
15762                if (getUidTargetSdkVersionLockedLPr(callingUid)
15763                        < Build.VERSION_CODES.FROYO) {
15764                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
15765                            + callingUid);
15766                    return;
15767                }
15768                mContext.enforceCallingOrSelfPermission(
15769                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15770            }
15771
15772            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
15773            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
15774                    + userId + ":");
15775            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
15776            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
15777            scheduleWritePackageRestrictionsLocked(userId);
15778        }
15779    }
15780
15781    @Override
15782    public void replacePreferredActivity(IntentFilter filter, int match,
15783            ComponentName[] set, ComponentName activity, int userId) {
15784        if (filter.countActions() != 1) {
15785            throw new IllegalArgumentException(
15786                    "replacePreferredActivity expects filter to have only 1 action.");
15787        }
15788        if (filter.countDataAuthorities() != 0
15789                || filter.countDataPaths() != 0
15790                || filter.countDataSchemes() > 1
15791                || filter.countDataTypes() != 0) {
15792            throw new IllegalArgumentException(
15793                    "replacePreferredActivity expects filter to have no data authorities, " +
15794                    "paths, or types; and at most one scheme.");
15795        }
15796
15797        final int callingUid = Binder.getCallingUid();
15798        enforceCrossUserPermission(callingUid, userId,
15799                true /* requireFullPermission */, false /* checkShell */,
15800                "replace preferred activity");
15801        synchronized (mPackages) {
15802            if (mContext.checkCallingOrSelfPermission(
15803                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
15804                    != PackageManager.PERMISSION_GRANTED) {
15805                if (getUidTargetSdkVersionLockedLPr(callingUid)
15806                        < Build.VERSION_CODES.FROYO) {
15807                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
15808                            + Binder.getCallingUid());
15809                    return;
15810                }
15811                mContext.enforceCallingOrSelfPermission(
15812                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15813            }
15814
15815            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
15816            if (pir != null) {
15817                // Get all of the existing entries that exactly match this filter.
15818                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
15819                if (existing != null && existing.size() == 1) {
15820                    PreferredActivity cur = existing.get(0);
15821                    if (DEBUG_PREFERRED) {
15822                        Slog.i(TAG, "Checking replace of preferred:");
15823                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
15824                        if (!cur.mPref.mAlways) {
15825                            Slog.i(TAG, "  -- CUR; not mAlways!");
15826                        } else {
15827                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
15828                            Slog.i(TAG, "  -- CUR: mSet="
15829                                    + Arrays.toString(cur.mPref.mSetComponents));
15830                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
15831                            Slog.i(TAG, "  -- NEW: mMatch="
15832                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
15833                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
15834                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
15835                        }
15836                    }
15837                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
15838                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
15839                            && cur.mPref.sameSet(set)) {
15840                        // Setting the preferred activity to what it happens to be already
15841                        if (DEBUG_PREFERRED) {
15842                            Slog.i(TAG, "Replacing with same preferred activity "
15843                                    + cur.mPref.mShortComponent + " for user "
15844                                    + userId + ":");
15845                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
15846                        }
15847                        return;
15848                    }
15849                }
15850
15851                if (existing != null) {
15852                    if (DEBUG_PREFERRED) {
15853                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
15854                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
15855                    }
15856                    for (int i = 0; i < existing.size(); i++) {
15857                        PreferredActivity pa = existing.get(i);
15858                        if (DEBUG_PREFERRED) {
15859                            Slog.i(TAG, "Removing existing preferred activity "
15860                                    + pa.mPref.mComponent + ":");
15861                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
15862                        }
15863                        pir.removeFilter(pa);
15864                    }
15865                }
15866            }
15867            addPreferredActivityInternal(filter, match, set, activity, true, userId,
15868                    "Replacing preferred");
15869        }
15870    }
15871
15872    @Override
15873    public void clearPackagePreferredActivities(String packageName) {
15874        final int uid = Binder.getCallingUid();
15875        // writer
15876        synchronized (mPackages) {
15877            PackageParser.Package pkg = mPackages.get(packageName);
15878            if (pkg == null || pkg.applicationInfo.uid != uid) {
15879                if (mContext.checkCallingOrSelfPermission(
15880                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
15881                        != PackageManager.PERMISSION_GRANTED) {
15882                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
15883                            < Build.VERSION_CODES.FROYO) {
15884                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
15885                                + Binder.getCallingUid());
15886                        return;
15887                    }
15888                    mContext.enforceCallingOrSelfPermission(
15889                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15890                }
15891            }
15892
15893            int user = UserHandle.getCallingUserId();
15894            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
15895                scheduleWritePackageRestrictionsLocked(user);
15896            }
15897        }
15898    }
15899
15900    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
15901    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
15902        ArrayList<PreferredActivity> removed = null;
15903        boolean changed = false;
15904        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
15905            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
15906            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
15907            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
15908                continue;
15909            }
15910            Iterator<PreferredActivity> it = pir.filterIterator();
15911            while (it.hasNext()) {
15912                PreferredActivity pa = it.next();
15913                // Mark entry for removal only if it matches the package name
15914                // and the entry is of type "always".
15915                if (packageName == null ||
15916                        (pa.mPref.mComponent.getPackageName().equals(packageName)
15917                                && pa.mPref.mAlways)) {
15918                    if (removed == null) {
15919                        removed = new ArrayList<PreferredActivity>();
15920                    }
15921                    removed.add(pa);
15922                }
15923            }
15924            if (removed != null) {
15925                for (int j=0; j<removed.size(); j++) {
15926                    PreferredActivity pa = removed.get(j);
15927                    pir.removeFilter(pa);
15928                }
15929                changed = true;
15930            }
15931        }
15932        return changed;
15933    }
15934
15935    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
15936    private void clearIntentFilterVerificationsLPw(int userId) {
15937        final int packageCount = mPackages.size();
15938        for (int i = 0; i < packageCount; i++) {
15939            PackageParser.Package pkg = mPackages.valueAt(i);
15940            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
15941        }
15942    }
15943
15944    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
15945    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
15946        if (userId == UserHandle.USER_ALL) {
15947            if (mSettings.removeIntentFilterVerificationLPw(packageName,
15948                    sUserManager.getUserIds())) {
15949                for (int oneUserId : sUserManager.getUserIds()) {
15950                    scheduleWritePackageRestrictionsLocked(oneUserId);
15951                }
15952            }
15953        } else {
15954            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
15955                scheduleWritePackageRestrictionsLocked(userId);
15956            }
15957        }
15958    }
15959
15960    void clearDefaultBrowserIfNeeded(String packageName) {
15961        for (int oneUserId : sUserManager.getUserIds()) {
15962            String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId);
15963            if (TextUtils.isEmpty(defaultBrowserPackageName)) continue;
15964            if (packageName.equals(defaultBrowserPackageName)) {
15965                setDefaultBrowserPackageName(null, oneUserId);
15966            }
15967        }
15968    }
15969
15970    @Override
15971    public void resetApplicationPreferences(int userId) {
15972        mContext.enforceCallingOrSelfPermission(
15973                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15974        // writer
15975        synchronized (mPackages) {
15976            final long identity = Binder.clearCallingIdentity();
15977            try {
15978                clearPackagePreferredActivitiesLPw(null, userId);
15979                mSettings.applyDefaultPreferredAppsLPw(this, userId);
15980                // TODO: We have to reset the default SMS and Phone. This requires
15981                // significant refactoring to keep all default apps in the package
15982                // manager (cleaner but more work) or have the services provide
15983                // callbacks to the package manager to request a default app reset.
15984                applyFactoryDefaultBrowserLPw(userId);
15985                clearIntentFilterVerificationsLPw(userId);
15986                primeDomainVerificationsLPw(userId);
15987                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
15988                scheduleWritePackageRestrictionsLocked(userId);
15989            } finally {
15990                Binder.restoreCallingIdentity(identity);
15991            }
15992        }
15993    }
15994
15995    @Override
15996    public int getPreferredActivities(List<IntentFilter> outFilters,
15997            List<ComponentName> outActivities, String packageName) {
15998
15999        int num = 0;
16000        final int userId = UserHandle.getCallingUserId();
16001        // reader
16002        synchronized (mPackages) {
16003            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
16004            if (pir != null) {
16005                final Iterator<PreferredActivity> it = pir.filterIterator();
16006                while (it.hasNext()) {
16007                    final PreferredActivity pa = it.next();
16008                    if (packageName == null
16009                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
16010                                    && pa.mPref.mAlways)) {
16011                        if (outFilters != null) {
16012                            outFilters.add(new IntentFilter(pa));
16013                        }
16014                        if (outActivities != null) {
16015                            outActivities.add(pa.mPref.mComponent);
16016                        }
16017                    }
16018                }
16019            }
16020        }
16021
16022        return num;
16023    }
16024
16025    @Override
16026    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
16027            int userId) {
16028        int callingUid = Binder.getCallingUid();
16029        if (callingUid != Process.SYSTEM_UID) {
16030            throw new SecurityException(
16031                    "addPersistentPreferredActivity can only be run by the system");
16032        }
16033        if (filter.countActions() == 0) {
16034            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
16035            return;
16036        }
16037        synchronized (mPackages) {
16038            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
16039                    ":");
16040            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
16041            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
16042                    new PersistentPreferredActivity(filter, activity));
16043            scheduleWritePackageRestrictionsLocked(userId);
16044        }
16045    }
16046
16047    @Override
16048    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
16049        int callingUid = Binder.getCallingUid();
16050        if (callingUid != Process.SYSTEM_UID) {
16051            throw new SecurityException(
16052                    "clearPackagePersistentPreferredActivities can only be run by the system");
16053        }
16054        ArrayList<PersistentPreferredActivity> removed = null;
16055        boolean changed = false;
16056        synchronized (mPackages) {
16057            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
16058                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
16059                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
16060                        .valueAt(i);
16061                if (userId != thisUserId) {
16062                    continue;
16063                }
16064                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
16065                while (it.hasNext()) {
16066                    PersistentPreferredActivity ppa = it.next();
16067                    // Mark entry for removal only if it matches the package name.
16068                    if (ppa.mComponent.getPackageName().equals(packageName)) {
16069                        if (removed == null) {
16070                            removed = new ArrayList<PersistentPreferredActivity>();
16071                        }
16072                        removed.add(ppa);
16073                    }
16074                }
16075                if (removed != null) {
16076                    for (int j=0; j<removed.size(); j++) {
16077                        PersistentPreferredActivity ppa = removed.get(j);
16078                        ppir.removeFilter(ppa);
16079                    }
16080                    changed = true;
16081                }
16082            }
16083
16084            if (changed) {
16085                scheduleWritePackageRestrictionsLocked(userId);
16086            }
16087        }
16088    }
16089
16090    /**
16091     * Common machinery for picking apart a restored XML blob and passing
16092     * it to a caller-supplied functor to be applied to the running system.
16093     */
16094    private void restoreFromXml(XmlPullParser parser, int userId,
16095            String expectedStartTag, BlobXmlRestorer functor)
16096            throws IOException, XmlPullParserException {
16097        int type;
16098        while ((type = parser.next()) != XmlPullParser.START_TAG
16099                && type != XmlPullParser.END_DOCUMENT) {
16100        }
16101        if (type != XmlPullParser.START_TAG) {
16102            // oops didn't find a start tag?!
16103            if (DEBUG_BACKUP) {
16104                Slog.e(TAG, "Didn't find start tag during restore");
16105            }
16106            return;
16107        }
16108Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
16109        // this is supposed to be TAG_PREFERRED_BACKUP
16110        if (!expectedStartTag.equals(parser.getName())) {
16111            if (DEBUG_BACKUP) {
16112                Slog.e(TAG, "Found unexpected tag " + parser.getName());
16113            }
16114            return;
16115        }
16116
16117        // skip interfering stuff, then we're aligned with the backing implementation
16118        while ((type = parser.next()) == XmlPullParser.TEXT) { }
16119Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
16120        functor.apply(parser, userId);
16121    }
16122
16123    private interface BlobXmlRestorer {
16124        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
16125    }
16126
16127    /**
16128     * Non-Binder method, support for the backup/restore mechanism: write the
16129     * full set of preferred activities in its canonical XML format.  Returns the
16130     * XML output as a byte array, or null if there is none.
16131     */
16132    @Override
16133    public byte[] getPreferredActivityBackup(int userId) {
16134        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16135            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
16136        }
16137
16138        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
16139        try {
16140            final XmlSerializer serializer = new FastXmlSerializer();
16141            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
16142            serializer.startDocument(null, true);
16143            serializer.startTag(null, TAG_PREFERRED_BACKUP);
16144
16145            synchronized (mPackages) {
16146                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
16147            }
16148
16149            serializer.endTag(null, TAG_PREFERRED_BACKUP);
16150            serializer.endDocument();
16151            serializer.flush();
16152        } catch (Exception e) {
16153            if (DEBUG_BACKUP) {
16154                Slog.e(TAG, "Unable to write preferred activities for backup", e);
16155            }
16156            return null;
16157        }
16158
16159        return dataStream.toByteArray();
16160    }
16161
16162    @Override
16163    public void restorePreferredActivities(byte[] backup, int userId) {
16164        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16165            throw new SecurityException("Only the system may call restorePreferredActivities()");
16166        }
16167
16168        try {
16169            final XmlPullParser parser = Xml.newPullParser();
16170            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
16171            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
16172                    new BlobXmlRestorer() {
16173                        @Override
16174                        public void apply(XmlPullParser parser, int userId)
16175                                throws XmlPullParserException, IOException {
16176                            synchronized (mPackages) {
16177                                mSettings.readPreferredActivitiesLPw(parser, userId);
16178                            }
16179                        }
16180                    } );
16181        } catch (Exception e) {
16182            if (DEBUG_BACKUP) {
16183                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
16184            }
16185        }
16186    }
16187
16188    /**
16189     * Non-Binder method, support for the backup/restore mechanism: write the
16190     * default browser (etc) settings in its canonical XML format.  Returns the default
16191     * browser XML representation as a byte array, or null if there is none.
16192     */
16193    @Override
16194    public byte[] getDefaultAppsBackup(int userId) {
16195        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16196            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
16197        }
16198
16199        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
16200        try {
16201            final XmlSerializer serializer = new FastXmlSerializer();
16202            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
16203            serializer.startDocument(null, true);
16204            serializer.startTag(null, TAG_DEFAULT_APPS);
16205
16206            synchronized (mPackages) {
16207                mSettings.writeDefaultAppsLPr(serializer, userId);
16208            }
16209
16210            serializer.endTag(null, TAG_DEFAULT_APPS);
16211            serializer.endDocument();
16212            serializer.flush();
16213        } catch (Exception e) {
16214            if (DEBUG_BACKUP) {
16215                Slog.e(TAG, "Unable to write default apps for backup", e);
16216            }
16217            return null;
16218        }
16219
16220        return dataStream.toByteArray();
16221    }
16222
16223    @Override
16224    public void restoreDefaultApps(byte[] backup, int userId) {
16225        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16226            throw new SecurityException("Only the system may call restoreDefaultApps()");
16227        }
16228
16229        try {
16230            final XmlPullParser parser = Xml.newPullParser();
16231            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
16232            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
16233                    new BlobXmlRestorer() {
16234                        @Override
16235                        public void apply(XmlPullParser parser, int userId)
16236                                throws XmlPullParserException, IOException {
16237                            synchronized (mPackages) {
16238                                mSettings.readDefaultAppsLPw(parser, userId);
16239                            }
16240                        }
16241                    } );
16242        } catch (Exception e) {
16243            if (DEBUG_BACKUP) {
16244                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
16245            }
16246        }
16247    }
16248
16249    @Override
16250    public byte[] getIntentFilterVerificationBackup(int userId) {
16251        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16252            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
16253        }
16254
16255        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
16256        try {
16257            final XmlSerializer serializer = new FastXmlSerializer();
16258            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
16259            serializer.startDocument(null, true);
16260            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
16261
16262            synchronized (mPackages) {
16263                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
16264            }
16265
16266            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
16267            serializer.endDocument();
16268            serializer.flush();
16269        } catch (Exception e) {
16270            if (DEBUG_BACKUP) {
16271                Slog.e(TAG, "Unable to write default apps for backup", e);
16272            }
16273            return null;
16274        }
16275
16276        return dataStream.toByteArray();
16277    }
16278
16279    @Override
16280    public void restoreIntentFilterVerification(byte[] backup, int userId) {
16281        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16282            throw new SecurityException("Only the system may call restorePreferredActivities()");
16283        }
16284
16285        try {
16286            final XmlPullParser parser = Xml.newPullParser();
16287            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
16288            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
16289                    new BlobXmlRestorer() {
16290                        @Override
16291                        public void apply(XmlPullParser parser, int userId)
16292                                throws XmlPullParserException, IOException {
16293                            synchronized (mPackages) {
16294                                mSettings.readAllDomainVerificationsLPr(parser, userId);
16295                                mSettings.writeLPr();
16296                            }
16297                        }
16298                    } );
16299        } catch (Exception e) {
16300            if (DEBUG_BACKUP) {
16301                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
16302            }
16303        }
16304    }
16305
16306    @Override
16307    public byte[] getPermissionGrantBackup(int userId) {
16308        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16309            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
16310        }
16311
16312        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
16313        try {
16314            final XmlSerializer serializer = new FastXmlSerializer();
16315            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
16316            serializer.startDocument(null, true);
16317            serializer.startTag(null, TAG_PERMISSION_BACKUP);
16318
16319            synchronized (mPackages) {
16320                serializeRuntimePermissionGrantsLPr(serializer, userId);
16321            }
16322
16323            serializer.endTag(null, TAG_PERMISSION_BACKUP);
16324            serializer.endDocument();
16325            serializer.flush();
16326        } catch (Exception e) {
16327            if (DEBUG_BACKUP) {
16328                Slog.e(TAG, "Unable to write default apps for backup", e);
16329            }
16330            return null;
16331        }
16332
16333        return dataStream.toByteArray();
16334    }
16335
16336    @Override
16337    public void restorePermissionGrants(byte[] backup, int userId) {
16338        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
16339            throw new SecurityException("Only the system may call restorePermissionGrants()");
16340        }
16341
16342        try {
16343            final XmlPullParser parser = Xml.newPullParser();
16344            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
16345            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
16346                    new BlobXmlRestorer() {
16347                        @Override
16348                        public void apply(XmlPullParser parser, int userId)
16349                                throws XmlPullParserException, IOException {
16350                            synchronized (mPackages) {
16351                                processRestoredPermissionGrantsLPr(parser, userId);
16352                            }
16353                        }
16354                    } );
16355        } catch (Exception e) {
16356            if (DEBUG_BACKUP) {
16357                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
16358            }
16359        }
16360    }
16361
16362    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
16363            throws IOException {
16364        serializer.startTag(null, TAG_ALL_GRANTS);
16365
16366        final int N = mSettings.mPackages.size();
16367        for (int i = 0; i < N; i++) {
16368            final PackageSetting ps = mSettings.mPackages.valueAt(i);
16369            boolean pkgGrantsKnown = false;
16370
16371            PermissionsState packagePerms = ps.getPermissionsState();
16372
16373            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
16374                final int grantFlags = state.getFlags();
16375                // only look at grants that are not system/policy fixed
16376                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
16377                    final boolean isGranted = state.isGranted();
16378                    // And only back up the user-twiddled state bits
16379                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
16380                        final String packageName = mSettings.mPackages.keyAt(i);
16381                        if (!pkgGrantsKnown) {
16382                            serializer.startTag(null, TAG_GRANT);
16383                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
16384                            pkgGrantsKnown = true;
16385                        }
16386
16387                        final boolean userSet =
16388                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
16389                        final boolean userFixed =
16390                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
16391                        final boolean revoke =
16392                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
16393
16394                        serializer.startTag(null, TAG_PERMISSION);
16395                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
16396                        if (isGranted) {
16397                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
16398                        }
16399                        if (userSet) {
16400                            serializer.attribute(null, ATTR_USER_SET, "true");
16401                        }
16402                        if (userFixed) {
16403                            serializer.attribute(null, ATTR_USER_FIXED, "true");
16404                        }
16405                        if (revoke) {
16406                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
16407                        }
16408                        serializer.endTag(null, TAG_PERMISSION);
16409                    }
16410                }
16411            }
16412
16413            if (pkgGrantsKnown) {
16414                serializer.endTag(null, TAG_GRANT);
16415            }
16416        }
16417
16418        serializer.endTag(null, TAG_ALL_GRANTS);
16419    }
16420
16421    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
16422            throws XmlPullParserException, IOException {
16423        String pkgName = null;
16424        int outerDepth = parser.getDepth();
16425        int type;
16426        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
16427                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
16428            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
16429                continue;
16430            }
16431
16432            final String tagName = parser.getName();
16433            if (tagName.equals(TAG_GRANT)) {
16434                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
16435                if (DEBUG_BACKUP) {
16436                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
16437                }
16438            } else if (tagName.equals(TAG_PERMISSION)) {
16439
16440                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
16441                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
16442
16443                int newFlagSet = 0;
16444                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
16445                    newFlagSet |= FLAG_PERMISSION_USER_SET;
16446                }
16447                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
16448                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
16449                }
16450                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
16451                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
16452                }
16453                if (DEBUG_BACKUP) {
16454                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
16455                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
16456                }
16457                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16458                if (ps != null) {
16459                    // Already installed so we apply the grant immediately
16460                    if (DEBUG_BACKUP) {
16461                        Slog.v(TAG, "        + already installed; applying");
16462                    }
16463                    PermissionsState perms = ps.getPermissionsState();
16464                    BasePermission bp = mSettings.mPermissions.get(permName);
16465                    if (bp != null) {
16466                        if (isGranted) {
16467                            perms.grantRuntimePermission(bp, userId);
16468                        }
16469                        if (newFlagSet != 0) {
16470                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
16471                        }
16472                    }
16473                } else {
16474                    // Need to wait for post-restore install to apply the grant
16475                    if (DEBUG_BACKUP) {
16476                        Slog.v(TAG, "        - not yet installed; saving for later");
16477                    }
16478                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
16479                            isGranted, newFlagSet, userId);
16480                }
16481            } else {
16482                PackageManagerService.reportSettingsProblem(Log.WARN,
16483                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
16484                XmlUtils.skipCurrentTag(parser);
16485            }
16486        }
16487
16488        scheduleWriteSettingsLocked();
16489        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
16490    }
16491
16492    @Override
16493    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
16494            int sourceUserId, int targetUserId, int flags) {
16495        mContext.enforceCallingOrSelfPermission(
16496                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
16497        int callingUid = Binder.getCallingUid();
16498        enforceOwnerRights(ownerPackage, callingUid);
16499        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
16500        if (intentFilter.countActions() == 0) {
16501            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
16502            return;
16503        }
16504        synchronized (mPackages) {
16505            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
16506                    ownerPackage, targetUserId, flags);
16507            CrossProfileIntentResolver resolver =
16508                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
16509            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
16510            // We have all those whose filter is equal. Now checking if the rest is equal as well.
16511            if (existing != null) {
16512                int size = existing.size();
16513                for (int i = 0; i < size; i++) {
16514                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
16515                        return;
16516                    }
16517                }
16518            }
16519            resolver.addFilter(newFilter);
16520            scheduleWritePackageRestrictionsLocked(sourceUserId);
16521        }
16522    }
16523
16524    @Override
16525    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
16526        mContext.enforceCallingOrSelfPermission(
16527                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
16528        int callingUid = Binder.getCallingUid();
16529        enforceOwnerRights(ownerPackage, callingUid);
16530        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
16531        synchronized (mPackages) {
16532            CrossProfileIntentResolver resolver =
16533                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
16534            ArraySet<CrossProfileIntentFilter> set =
16535                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
16536            for (CrossProfileIntentFilter filter : set) {
16537                if (filter.getOwnerPackage().equals(ownerPackage)) {
16538                    resolver.removeFilter(filter);
16539                }
16540            }
16541            scheduleWritePackageRestrictionsLocked(sourceUserId);
16542        }
16543    }
16544
16545    // Enforcing that callingUid is owning pkg on userId
16546    private void enforceOwnerRights(String pkg, int callingUid) {
16547        // The system owns everything.
16548        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
16549            return;
16550        }
16551        int callingUserId = UserHandle.getUserId(callingUid);
16552        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
16553        if (pi == null) {
16554            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
16555                    + callingUserId);
16556        }
16557        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
16558            throw new SecurityException("Calling uid " + callingUid
16559                    + " does not own package " + pkg);
16560        }
16561    }
16562
16563    @Override
16564    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
16565        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
16566    }
16567
16568    private Intent getHomeIntent() {
16569        Intent intent = new Intent(Intent.ACTION_MAIN);
16570        intent.addCategory(Intent.CATEGORY_HOME);
16571        return intent;
16572    }
16573
16574    private IntentFilter getHomeFilter() {
16575        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
16576        filter.addCategory(Intent.CATEGORY_HOME);
16577        filter.addCategory(Intent.CATEGORY_DEFAULT);
16578        return filter;
16579    }
16580
16581    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
16582            int userId) {
16583        Intent intent  = getHomeIntent();
16584        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
16585                PackageManager.GET_META_DATA, userId);
16586        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
16587                true, false, false, userId);
16588
16589        allHomeCandidates.clear();
16590        if (list != null) {
16591            for (ResolveInfo ri : list) {
16592                allHomeCandidates.add(ri);
16593            }
16594        }
16595        return (preferred == null || preferred.activityInfo == null)
16596                ? null
16597                : new ComponentName(preferred.activityInfo.packageName,
16598                        preferred.activityInfo.name);
16599    }
16600
16601    @Override
16602    public void setHomeActivity(ComponentName comp, int userId) {
16603        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
16604        getHomeActivitiesAsUser(homeActivities, userId);
16605
16606        boolean found = false;
16607
16608        final int size = homeActivities.size();
16609        final ComponentName[] set = new ComponentName[size];
16610        for (int i = 0; i < size; i++) {
16611            final ResolveInfo candidate = homeActivities.get(i);
16612            final ActivityInfo info = candidate.activityInfo;
16613            final ComponentName activityName = new ComponentName(info.packageName, info.name);
16614            set[i] = activityName;
16615            if (!found && activityName.equals(comp)) {
16616                found = true;
16617            }
16618        }
16619        if (!found) {
16620            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
16621                    + userId);
16622        }
16623        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
16624                set, comp, userId);
16625    }
16626
16627    private @Nullable String getSetupWizardPackageName() {
16628        final Intent intent = new Intent(Intent.ACTION_MAIN);
16629        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
16630
16631        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
16632                MATCH_SYSTEM_ONLY | MATCH_DISABLED_COMPONENTS, UserHandle.myUserId());
16633        if (matches.size() == 1) {
16634            return matches.get(0).getComponentInfo().packageName;
16635        } else {
16636            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
16637                    + ": matches=" + matches);
16638            return null;
16639        }
16640    }
16641
16642    @Override
16643    public void setApplicationEnabledSetting(String appPackageName,
16644            int newState, int flags, int userId, String callingPackage) {
16645        if (!sUserManager.exists(userId)) return;
16646        if (callingPackage == null) {
16647            callingPackage = Integer.toString(Binder.getCallingUid());
16648        }
16649        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
16650    }
16651
16652    @Override
16653    public void setComponentEnabledSetting(ComponentName componentName,
16654            int newState, int flags, int userId) {
16655        if (!sUserManager.exists(userId)) return;
16656        setEnabledSetting(componentName.getPackageName(),
16657                componentName.getClassName(), newState, flags, userId, null);
16658    }
16659
16660    private void setEnabledSetting(final String packageName, String className, int newState,
16661            final int flags, int userId, String callingPackage) {
16662        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
16663              || newState == COMPONENT_ENABLED_STATE_ENABLED
16664              || newState == COMPONENT_ENABLED_STATE_DISABLED
16665              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
16666              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
16667            throw new IllegalArgumentException("Invalid new component state: "
16668                    + newState);
16669        }
16670        PackageSetting pkgSetting;
16671        final int uid = Binder.getCallingUid();
16672        final int permission = mContext.checkCallingOrSelfPermission(
16673                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
16674        enforceCrossUserPermission(uid, userId,
16675                false /* requireFullPermission */, true /* checkShell */, "set enabled");
16676        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
16677        boolean sendNow = false;
16678        boolean isApp = (className == null);
16679        String componentName = isApp ? packageName : className;
16680        int packageUid = -1;
16681        ArrayList<String> components;
16682
16683        // writer
16684        synchronized (mPackages) {
16685            pkgSetting = mSettings.mPackages.get(packageName);
16686            if (pkgSetting == null) {
16687                if (className == null) {
16688                    throw new IllegalArgumentException("Unknown package: " + packageName);
16689                }
16690                throw new IllegalArgumentException(
16691                        "Unknown component: " + packageName + "/" + className);
16692            }
16693            // Allow root and verify that userId is not being specified by a different user
16694            if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
16695                throw new SecurityException(
16696                        "Permission Denial: attempt to change component state from pid="
16697                        + Binder.getCallingPid()
16698                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
16699            }
16700            if (className == null) {
16701                // We're dealing with an application/package level state change
16702                if (pkgSetting.getEnabled(userId) == newState) {
16703                    // Nothing to do
16704                    return;
16705                }
16706                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
16707                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
16708                    // Don't care about who enables an app.
16709                    callingPackage = null;
16710                }
16711                pkgSetting.setEnabled(newState, userId, callingPackage);
16712                // pkgSetting.pkg.mSetEnabled = newState;
16713            } else {
16714                // We're dealing with a component level state change
16715                // First, verify that this is a valid class name.
16716                PackageParser.Package pkg = pkgSetting.pkg;
16717                if (pkg == null || !pkg.hasComponentClassName(className)) {
16718                    if (pkg != null &&
16719                            pkg.applicationInfo.targetSdkVersion >=
16720                                    Build.VERSION_CODES.JELLY_BEAN) {
16721                        throw new IllegalArgumentException("Component class " + className
16722                                + " does not exist in " + packageName);
16723                    } else {
16724                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
16725                                + className + " does not exist in " + packageName);
16726                    }
16727                }
16728                switch (newState) {
16729                case COMPONENT_ENABLED_STATE_ENABLED:
16730                    if (!pkgSetting.enableComponentLPw(className, userId)) {
16731                        return;
16732                    }
16733                    break;
16734                case COMPONENT_ENABLED_STATE_DISABLED:
16735                    if (!pkgSetting.disableComponentLPw(className, userId)) {
16736                        return;
16737                    }
16738                    break;
16739                case COMPONENT_ENABLED_STATE_DEFAULT:
16740                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
16741                        return;
16742                    }
16743                    break;
16744                default:
16745                    Slog.e(TAG, "Invalid new component state: " + newState);
16746                    return;
16747                }
16748            }
16749            scheduleWritePackageRestrictionsLocked(userId);
16750            components = mPendingBroadcasts.get(userId, packageName);
16751            final boolean newPackage = components == null;
16752            if (newPackage) {
16753                components = new ArrayList<String>();
16754            }
16755            if (!components.contains(componentName)) {
16756                components.add(componentName);
16757            }
16758            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
16759                sendNow = true;
16760                // Purge entry from pending broadcast list if another one exists already
16761                // since we are sending one right away.
16762                mPendingBroadcasts.remove(userId, packageName);
16763            } else {
16764                if (newPackage) {
16765                    mPendingBroadcasts.put(userId, packageName, components);
16766                }
16767                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
16768                    // Schedule a message
16769                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
16770                }
16771            }
16772        }
16773
16774        long callingId = Binder.clearCallingIdentity();
16775        try {
16776            if (sendNow) {
16777                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
16778                sendPackageChangedBroadcast(packageName,
16779                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
16780            }
16781        } finally {
16782            Binder.restoreCallingIdentity(callingId);
16783        }
16784    }
16785
16786    @Override
16787    public void flushPackageRestrictionsAsUser(int userId) {
16788        if (!sUserManager.exists(userId)) {
16789            return;
16790        }
16791        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
16792                false /* checkShell */, "flushPackageRestrictions");
16793        synchronized (mPackages) {
16794            mSettings.writePackageRestrictionsLPr(userId);
16795            mDirtyUsers.remove(userId);
16796            if (mDirtyUsers.isEmpty()) {
16797                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
16798            }
16799        }
16800    }
16801
16802    private void sendPackageChangedBroadcast(String packageName,
16803            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
16804        if (DEBUG_INSTALL)
16805            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
16806                    + componentNames);
16807        Bundle extras = new Bundle(4);
16808        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
16809        String nameList[] = new String[componentNames.size()];
16810        componentNames.toArray(nameList);
16811        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
16812        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
16813        extras.putInt(Intent.EXTRA_UID, packageUid);
16814        // If this is not reporting a change of the overall package, then only send it
16815        // to registered receivers.  We don't want to launch a swath of apps for every
16816        // little component state change.
16817        final int flags = !componentNames.contains(packageName)
16818                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
16819        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
16820                new int[] {UserHandle.getUserId(packageUid)});
16821    }
16822
16823    @Override
16824    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
16825        if (!sUserManager.exists(userId)) return;
16826        final int uid = Binder.getCallingUid();
16827        final int permission = mContext.checkCallingOrSelfPermission(
16828                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
16829        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
16830        enforceCrossUserPermission(uid, userId,
16831                true /* requireFullPermission */, true /* checkShell */, "stop package");
16832        // writer
16833        synchronized (mPackages) {
16834            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
16835                    allowedByPermission, uid, userId)) {
16836                scheduleWritePackageRestrictionsLocked(userId);
16837            }
16838        }
16839    }
16840
16841    @Override
16842    public String getInstallerPackageName(String packageName) {
16843        // reader
16844        synchronized (mPackages) {
16845            return mSettings.getInstallerPackageNameLPr(packageName);
16846        }
16847    }
16848
16849    @Override
16850    public int getApplicationEnabledSetting(String packageName, int userId) {
16851        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
16852        int uid = Binder.getCallingUid();
16853        enforceCrossUserPermission(uid, userId,
16854                false /* requireFullPermission */, false /* checkShell */, "get enabled");
16855        // reader
16856        synchronized (mPackages) {
16857            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
16858        }
16859    }
16860
16861    @Override
16862    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
16863        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
16864        int uid = Binder.getCallingUid();
16865        enforceCrossUserPermission(uid, userId,
16866                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
16867        // reader
16868        synchronized (mPackages) {
16869            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
16870        }
16871    }
16872
16873    @Override
16874    public void enterSafeMode() {
16875        enforceSystemOrRoot("Only the system can request entering safe mode");
16876
16877        if (!mSystemReady) {
16878            mSafeMode = true;
16879        }
16880    }
16881
16882    @Override
16883    public void systemReady() {
16884        mSystemReady = true;
16885
16886        // Read the compatibilty setting when the system is ready.
16887        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
16888                mContext.getContentResolver(),
16889                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
16890        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
16891        if (DEBUG_SETTINGS) {
16892            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
16893        }
16894
16895        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
16896
16897        synchronized (mPackages) {
16898            // Verify that all of the preferred activity components actually
16899            // exist.  It is possible for applications to be updated and at
16900            // that point remove a previously declared activity component that
16901            // had been set as a preferred activity.  We try to clean this up
16902            // the next time we encounter that preferred activity, but it is
16903            // possible for the user flow to never be able to return to that
16904            // situation so here we do a sanity check to make sure we haven't
16905            // left any junk around.
16906            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
16907            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
16908                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
16909                removed.clear();
16910                for (PreferredActivity pa : pir.filterSet()) {
16911                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
16912                        removed.add(pa);
16913                    }
16914                }
16915                if (removed.size() > 0) {
16916                    for (int r=0; r<removed.size(); r++) {
16917                        PreferredActivity pa = removed.get(r);
16918                        Slog.w(TAG, "Removing dangling preferred activity: "
16919                                + pa.mPref.mComponent);
16920                        pir.removeFilter(pa);
16921                    }
16922                    mSettings.writePackageRestrictionsLPr(
16923                            mSettings.mPreferredActivities.keyAt(i));
16924                }
16925            }
16926
16927            for (int userId : UserManagerService.getInstance().getUserIds()) {
16928                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
16929                    grantPermissionsUserIds = ArrayUtils.appendInt(
16930                            grantPermissionsUserIds, userId);
16931                }
16932            }
16933        }
16934        sUserManager.systemReady();
16935
16936        // If we upgraded grant all default permissions before kicking off.
16937        for (int userId : grantPermissionsUserIds) {
16938            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
16939        }
16940
16941        // Kick off any messages waiting for system ready
16942        if (mPostSystemReadyMessages != null) {
16943            for (Message msg : mPostSystemReadyMessages) {
16944                msg.sendToTarget();
16945            }
16946            mPostSystemReadyMessages = null;
16947        }
16948
16949        // Watch for external volumes that come and go over time
16950        final StorageManager storage = mContext.getSystemService(StorageManager.class);
16951        storage.registerListener(mStorageListener);
16952
16953        mInstallerService.systemReady();
16954        mPackageDexOptimizer.systemReady();
16955
16956        MountServiceInternal mountServiceInternal = LocalServices.getService(
16957                MountServiceInternal.class);
16958        mountServiceInternal.addExternalStoragePolicy(
16959                new MountServiceInternal.ExternalStorageMountPolicy() {
16960            @Override
16961            public int getMountMode(int uid, String packageName) {
16962                if (Process.isIsolated(uid)) {
16963                    return Zygote.MOUNT_EXTERNAL_NONE;
16964                }
16965                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
16966                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
16967                }
16968                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
16969                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
16970                }
16971                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
16972                    return Zygote.MOUNT_EXTERNAL_READ;
16973                }
16974                return Zygote.MOUNT_EXTERNAL_WRITE;
16975            }
16976
16977            @Override
16978            public boolean hasExternalStorage(int uid, String packageName) {
16979                return true;
16980            }
16981        });
16982    }
16983
16984    @Override
16985    public boolean isSafeMode() {
16986        return mSafeMode;
16987    }
16988
16989    @Override
16990    public boolean hasSystemUidErrors() {
16991        return mHasSystemUidErrors;
16992    }
16993
16994    static String arrayToString(int[] array) {
16995        StringBuffer buf = new StringBuffer(128);
16996        buf.append('[');
16997        if (array != null) {
16998            for (int i=0; i<array.length; i++) {
16999                if (i > 0) buf.append(", ");
17000                buf.append(array[i]);
17001            }
17002        }
17003        buf.append(']');
17004        return buf.toString();
17005    }
17006
17007    static class DumpState {
17008        public static final int DUMP_LIBS = 1 << 0;
17009        public static final int DUMP_FEATURES = 1 << 1;
17010        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
17011        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
17012        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
17013        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
17014        public static final int DUMP_PERMISSIONS = 1 << 6;
17015        public static final int DUMP_PACKAGES = 1 << 7;
17016        public static final int DUMP_SHARED_USERS = 1 << 8;
17017        public static final int DUMP_MESSAGES = 1 << 9;
17018        public static final int DUMP_PROVIDERS = 1 << 10;
17019        public static final int DUMP_VERIFIERS = 1 << 11;
17020        public static final int DUMP_PREFERRED = 1 << 12;
17021        public static final int DUMP_PREFERRED_XML = 1 << 13;
17022        public static final int DUMP_KEYSETS = 1 << 14;
17023        public static final int DUMP_VERSION = 1 << 15;
17024        public static final int DUMP_INSTALLS = 1 << 16;
17025        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
17026        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
17027
17028        public static final int OPTION_SHOW_FILTERS = 1 << 0;
17029
17030        private int mTypes;
17031
17032        private int mOptions;
17033
17034        private boolean mTitlePrinted;
17035
17036        private SharedUserSetting mSharedUser;
17037
17038        public boolean isDumping(int type) {
17039            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
17040                return true;
17041            }
17042
17043            return (mTypes & type) != 0;
17044        }
17045
17046        public void setDump(int type) {
17047            mTypes |= type;
17048        }
17049
17050        public boolean isOptionEnabled(int option) {
17051            return (mOptions & option) != 0;
17052        }
17053
17054        public void setOptionEnabled(int option) {
17055            mOptions |= option;
17056        }
17057
17058        public boolean onTitlePrinted() {
17059            final boolean printed = mTitlePrinted;
17060            mTitlePrinted = true;
17061            return printed;
17062        }
17063
17064        public boolean getTitlePrinted() {
17065            return mTitlePrinted;
17066        }
17067
17068        public void setTitlePrinted(boolean enabled) {
17069            mTitlePrinted = enabled;
17070        }
17071
17072        public SharedUserSetting getSharedUser() {
17073            return mSharedUser;
17074        }
17075
17076        public void setSharedUser(SharedUserSetting user) {
17077            mSharedUser = user;
17078        }
17079    }
17080
17081    @Override
17082    public void onShellCommand(FileDescriptor in, FileDescriptor out,
17083            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
17084        (new PackageManagerShellCommand(this)).exec(
17085                this, in, out, err, args, resultReceiver);
17086    }
17087
17088    @Override
17089    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
17090        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
17091                != PackageManager.PERMISSION_GRANTED) {
17092            pw.println("Permission Denial: can't dump ActivityManager from from pid="
17093                    + Binder.getCallingPid()
17094                    + ", uid=" + Binder.getCallingUid()
17095                    + " without permission "
17096                    + android.Manifest.permission.DUMP);
17097            return;
17098        }
17099
17100        DumpState dumpState = new DumpState();
17101        boolean fullPreferred = false;
17102        boolean checkin = false;
17103
17104        String packageName = null;
17105        ArraySet<String> permissionNames = null;
17106
17107        int opti = 0;
17108        while (opti < args.length) {
17109            String opt = args[opti];
17110            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17111                break;
17112            }
17113            opti++;
17114
17115            if ("-a".equals(opt)) {
17116                // Right now we only know how to print all.
17117            } else if ("-h".equals(opt)) {
17118                pw.println("Package manager dump options:");
17119                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
17120                pw.println("    --checkin: dump for a checkin");
17121                pw.println("    -f: print details of intent filters");
17122                pw.println("    -h: print this help");
17123                pw.println("  cmd may be one of:");
17124                pw.println("    l[ibraries]: list known shared libraries");
17125                pw.println("    f[eatures]: list device features");
17126                pw.println("    k[eysets]: print known keysets");
17127                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
17128                pw.println("    perm[issions]: dump permissions");
17129                pw.println("    permission [name ...]: dump declaration and use of given permission");
17130                pw.println("    pref[erred]: print preferred package settings");
17131                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
17132                pw.println("    prov[iders]: dump content providers");
17133                pw.println("    p[ackages]: dump installed packages");
17134                pw.println("    s[hared-users]: dump shared user IDs");
17135                pw.println("    m[essages]: print collected runtime messages");
17136                pw.println("    v[erifiers]: print package verifier info");
17137                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
17138                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
17139                pw.println("    version: print database version info");
17140                pw.println("    write: write current settings now");
17141                pw.println("    installs: details about install sessions");
17142                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
17143                pw.println("    <package.name>: info about given package");
17144                return;
17145            } else if ("--checkin".equals(opt)) {
17146                checkin = true;
17147            } else if ("-f".equals(opt)) {
17148                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
17149            } else {
17150                pw.println("Unknown argument: " + opt + "; use -h for help");
17151            }
17152        }
17153
17154        // Is the caller requesting to dump a particular piece of data?
17155        if (opti < args.length) {
17156            String cmd = args[opti];
17157            opti++;
17158            // Is this a package name?
17159            if ("android".equals(cmd) || cmd.contains(".")) {
17160                packageName = cmd;
17161                // When dumping a single package, we always dump all of its
17162                // filter information since the amount of data will be reasonable.
17163                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
17164            } else if ("check-permission".equals(cmd)) {
17165                if (opti >= args.length) {
17166                    pw.println("Error: check-permission missing permission argument");
17167                    return;
17168                }
17169                String perm = args[opti];
17170                opti++;
17171                if (opti >= args.length) {
17172                    pw.println("Error: check-permission missing package argument");
17173                    return;
17174                }
17175                String pkg = args[opti];
17176                opti++;
17177                int user = UserHandle.getUserId(Binder.getCallingUid());
17178                if (opti < args.length) {
17179                    try {
17180                        user = Integer.parseInt(args[opti]);
17181                    } catch (NumberFormatException e) {
17182                        pw.println("Error: check-permission user argument is not a number: "
17183                                + args[opti]);
17184                        return;
17185                    }
17186                }
17187                pw.println(checkPermission(perm, pkg, user));
17188                return;
17189            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
17190                dumpState.setDump(DumpState.DUMP_LIBS);
17191            } else if ("f".equals(cmd) || "features".equals(cmd)) {
17192                dumpState.setDump(DumpState.DUMP_FEATURES);
17193            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
17194                if (opti >= args.length) {
17195                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
17196                            | DumpState.DUMP_SERVICE_RESOLVERS
17197                            | DumpState.DUMP_RECEIVER_RESOLVERS
17198                            | DumpState.DUMP_CONTENT_RESOLVERS);
17199                } else {
17200                    while (opti < args.length) {
17201                        String name = args[opti];
17202                        if ("a".equals(name) || "activity".equals(name)) {
17203                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
17204                        } else if ("s".equals(name) || "service".equals(name)) {
17205                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
17206                        } else if ("r".equals(name) || "receiver".equals(name)) {
17207                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
17208                        } else if ("c".equals(name) || "content".equals(name)) {
17209                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
17210                        } else {
17211                            pw.println("Error: unknown resolver table type: " + name);
17212                            return;
17213                        }
17214                        opti++;
17215                    }
17216                }
17217            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
17218                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
17219            } else if ("permission".equals(cmd)) {
17220                if (opti >= args.length) {
17221                    pw.println("Error: permission requires permission name");
17222                    return;
17223                }
17224                permissionNames = new ArraySet<>();
17225                while (opti < args.length) {
17226                    permissionNames.add(args[opti]);
17227                    opti++;
17228                }
17229                dumpState.setDump(DumpState.DUMP_PERMISSIONS
17230                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
17231            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
17232                dumpState.setDump(DumpState.DUMP_PREFERRED);
17233            } else if ("preferred-xml".equals(cmd)) {
17234                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
17235                if (opti < args.length && "--full".equals(args[opti])) {
17236                    fullPreferred = true;
17237                    opti++;
17238                }
17239            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
17240                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
17241            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
17242                dumpState.setDump(DumpState.DUMP_PACKAGES);
17243            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
17244                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
17245            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
17246                dumpState.setDump(DumpState.DUMP_PROVIDERS);
17247            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
17248                dumpState.setDump(DumpState.DUMP_MESSAGES);
17249            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
17250                dumpState.setDump(DumpState.DUMP_VERIFIERS);
17251            } else if ("i".equals(cmd) || "ifv".equals(cmd)
17252                    || "intent-filter-verifiers".equals(cmd)) {
17253                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
17254            } else if ("version".equals(cmd)) {
17255                dumpState.setDump(DumpState.DUMP_VERSION);
17256            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
17257                dumpState.setDump(DumpState.DUMP_KEYSETS);
17258            } else if ("installs".equals(cmd)) {
17259                dumpState.setDump(DumpState.DUMP_INSTALLS);
17260            } else if ("write".equals(cmd)) {
17261                synchronized (mPackages) {
17262                    mSettings.writeLPr();
17263                    pw.println("Settings written.");
17264                    return;
17265                }
17266            }
17267        }
17268
17269        if (checkin) {
17270            pw.println("vers,1");
17271        }
17272
17273        // reader
17274        synchronized (mPackages) {
17275            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
17276                if (!checkin) {
17277                    if (dumpState.onTitlePrinted())
17278                        pw.println();
17279                    pw.println("Database versions:");
17280                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
17281                }
17282            }
17283
17284            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
17285                if (!checkin) {
17286                    if (dumpState.onTitlePrinted())
17287                        pw.println();
17288                    pw.println("Verifiers:");
17289                    pw.print("  Required: ");
17290                    pw.print(mRequiredVerifierPackage);
17291                    pw.print(" (uid=");
17292                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
17293                            UserHandle.USER_SYSTEM));
17294                    pw.println(")");
17295                } else if (mRequiredVerifierPackage != null) {
17296                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
17297                    pw.print(",");
17298                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
17299                            UserHandle.USER_SYSTEM));
17300                }
17301            }
17302
17303            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
17304                    packageName == null) {
17305                if (mIntentFilterVerifierComponent != null) {
17306                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
17307                    if (!checkin) {
17308                        if (dumpState.onTitlePrinted())
17309                            pw.println();
17310                        pw.println("Intent Filter Verifier:");
17311                        pw.print("  Using: ");
17312                        pw.print(verifierPackageName);
17313                        pw.print(" (uid=");
17314                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
17315                                UserHandle.USER_SYSTEM));
17316                        pw.println(")");
17317                    } else if (verifierPackageName != null) {
17318                        pw.print("ifv,"); pw.print(verifierPackageName);
17319                        pw.print(",");
17320                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
17321                                UserHandle.USER_SYSTEM));
17322                    }
17323                } else {
17324                    pw.println();
17325                    pw.println("No Intent Filter Verifier available!");
17326                }
17327            }
17328
17329            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
17330                boolean printedHeader = false;
17331                final Iterator<String> it = mSharedLibraries.keySet().iterator();
17332                while (it.hasNext()) {
17333                    String name = it.next();
17334                    SharedLibraryEntry ent = mSharedLibraries.get(name);
17335                    if (!checkin) {
17336                        if (!printedHeader) {
17337                            if (dumpState.onTitlePrinted())
17338                                pw.println();
17339                            pw.println("Libraries:");
17340                            printedHeader = true;
17341                        }
17342                        pw.print("  ");
17343                    } else {
17344                        pw.print("lib,");
17345                    }
17346                    pw.print(name);
17347                    if (!checkin) {
17348                        pw.print(" -> ");
17349                    }
17350                    if (ent.path != null) {
17351                        if (!checkin) {
17352                            pw.print("(jar) ");
17353                            pw.print(ent.path);
17354                        } else {
17355                            pw.print(",jar,");
17356                            pw.print(ent.path);
17357                        }
17358                    } else {
17359                        if (!checkin) {
17360                            pw.print("(apk) ");
17361                            pw.print(ent.apk);
17362                        } else {
17363                            pw.print(",apk,");
17364                            pw.print(ent.apk);
17365                        }
17366                    }
17367                    pw.println();
17368                }
17369            }
17370
17371            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
17372                if (dumpState.onTitlePrinted())
17373                    pw.println();
17374                if (!checkin) {
17375                    pw.println("Features:");
17376                }
17377
17378                for (FeatureInfo feat : mAvailableFeatures.values()) {
17379                    if (checkin) {
17380                        pw.print("feat,");
17381                        pw.print(feat.name);
17382                        pw.print(",");
17383                        pw.println(feat.version);
17384                    } else {
17385                        pw.print("  ");
17386                        pw.print(feat.name);
17387                        if (feat.version > 0) {
17388                            pw.print(" version=");
17389                            pw.print(feat.version);
17390                        }
17391                        pw.println();
17392                    }
17393                }
17394            }
17395
17396            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
17397                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
17398                        : "Activity Resolver Table:", "  ", packageName,
17399                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
17400                    dumpState.setTitlePrinted(true);
17401                }
17402            }
17403            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
17404                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
17405                        : "Receiver Resolver Table:", "  ", packageName,
17406                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
17407                    dumpState.setTitlePrinted(true);
17408                }
17409            }
17410            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
17411                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
17412                        : "Service Resolver Table:", "  ", packageName,
17413                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
17414                    dumpState.setTitlePrinted(true);
17415                }
17416            }
17417            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
17418                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
17419                        : "Provider Resolver Table:", "  ", packageName,
17420                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
17421                    dumpState.setTitlePrinted(true);
17422                }
17423            }
17424
17425            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
17426                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
17427                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
17428                    int user = mSettings.mPreferredActivities.keyAt(i);
17429                    if (pir.dump(pw,
17430                            dumpState.getTitlePrinted()
17431                                ? "\nPreferred Activities User " + user + ":"
17432                                : "Preferred Activities User " + user + ":", "  ",
17433                            packageName, true, false)) {
17434                        dumpState.setTitlePrinted(true);
17435                    }
17436                }
17437            }
17438
17439            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
17440                pw.flush();
17441                FileOutputStream fout = new FileOutputStream(fd);
17442                BufferedOutputStream str = new BufferedOutputStream(fout);
17443                XmlSerializer serializer = new FastXmlSerializer();
17444                try {
17445                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
17446                    serializer.startDocument(null, true);
17447                    serializer.setFeature(
17448                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
17449                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
17450                    serializer.endDocument();
17451                    serializer.flush();
17452                } catch (IllegalArgumentException e) {
17453                    pw.println("Failed writing: " + e);
17454                } catch (IllegalStateException e) {
17455                    pw.println("Failed writing: " + e);
17456                } catch (IOException e) {
17457                    pw.println("Failed writing: " + e);
17458                }
17459            }
17460
17461            if (!checkin
17462                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
17463                    && packageName == null) {
17464                pw.println();
17465                int count = mSettings.mPackages.size();
17466                if (count == 0) {
17467                    pw.println("No applications!");
17468                    pw.println();
17469                } else {
17470                    final String prefix = "  ";
17471                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
17472                    if (allPackageSettings.size() == 0) {
17473                        pw.println("No domain preferred apps!");
17474                        pw.println();
17475                    } else {
17476                        pw.println("App verification status:");
17477                        pw.println();
17478                        count = 0;
17479                        for (PackageSetting ps : allPackageSettings) {
17480                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
17481                            if (ivi == null || ivi.getPackageName() == null) continue;
17482                            pw.println(prefix + "Package: " + ivi.getPackageName());
17483                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
17484                            pw.println(prefix + "Status:  " + ivi.getStatusString());
17485                            pw.println();
17486                            count++;
17487                        }
17488                        if (count == 0) {
17489                            pw.println(prefix + "No app verification established.");
17490                            pw.println();
17491                        }
17492                        for (int userId : sUserManager.getUserIds()) {
17493                            pw.println("App linkages for user " + userId + ":");
17494                            pw.println();
17495                            count = 0;
17496                            for (PackageSetting ps : allPackageSettings) {
17497                                final long status = ps.getDomainVerificationStatusForUser(userId);
17498                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
17499                                    continue;
17500                                }
17501                                pw.println(prefix + "Package: " + ps.name);
17502                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
17503                                String statusStr = IntentFilterVerificationInfo.
17504                                        getStatusStringFromValue(status);
17505                                pw.println(prefix + "Status:  " + statusStr);
17506                                pw.println();
17507                                count++;
17508                            }
17509                            if (count == 0) {
17510                                pw.println(prefix + "No configured app linkages.");
17511                                pw.println();
17512                            }
17513                        }
17514                    }
17515                }
17516            }
17517
17518            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
17519                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
17520                if (packageName == null && permissionNames == null) {
17521                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
17522                        if (iperm == 0) {
17523                            if (dumpState.onTitlePrinted())
17524                                pw.println();
17525                            pw.println("AppOp Permissions:");
17526                        }
17527                        pw.print("  AppOp Permission ");
17528                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
17529                        pw.println(":");
17530                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
17531                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
17532                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
17533                        }
17534                    }
17535                }
17536            }
17537
17538            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
17539                boolean printedSomething = false;
17540                for (PackageParser.Provider p : mProviders.mProviders.values()) {
17541                    if (packageName != null && !packageName.equals(p.info.packageName)) {
17542                        continue;
17543                    }
17544                    if (!printedSomething) {
17545                        if (dumpState.onTitlePrinted())
17546                            pw.println();
17547                        pw.println("Registered ContentProviders:");
17548                        printedSomething = true;
17549                    }
17550                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
17551                    pw.print("    "); pw.println(p.toString());
17552                }
17553                printedSomething = false;
17554                for (Map.Entry<String, PackageParser.Provider> entry :
17555                        mProvidersByAuthority.entrySet()) {
17556                    PackageParser.Provider p = entry.getValue();
17557                    if (packageName != null && !packageName.equals(p.info.packageName)) {
17558                        continue;
17559                    }
17560                    if (!printedSomething) {
17561                        if (dumpState.onTitlePrinted())
17562                            pw.println();
17563                        pw.println("ContentProvider Authorities:");
17564                        printedSomething = true;
17565                    }
17566                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
17567                    pw.print("    "); pw.println(p.toString());
17568                    if (p.info != null && p.info.applicationInfo != null) {
17569                        final String appInfo = p.info.applicationInfo.toString();
17570                        pw.print("      applicationInfo="); pw.println(appInfo);
17571                    }
17572                }
17573            }
17574
17575            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
17576                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
17577            }
17578
17579            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
17580                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
17581            }
17582
17583            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
17584                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
17585            }
17586
17587            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
17588                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
17589            }
17590
17591            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
17592                // XXX should handle packageName != null by dumping only install data that
17593                // the given package is involved with.
17594                if (dumpState.onTitlePrinted()) pw.println();
17595                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
17596            }
17597
17598            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
17599                if (dumpState.onTitlePrinted()) pw.println();
17600                mSettings.dumpReadMessagesLPr(pw, dumpState);
17601
17602                pw.println();
17603                pw.println("Package warning messages:");
17604                BufferedReader in = null;
17605                String line = null;
17606                try {
17607                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
17608                    while ((line = in.readLine()) != null) {
17609                        if (line.contains("ignored: updated version")) continue;
17610                        pw.println(line);
17611                    }
17612                } catch (IOException ignored) {
17613                } finally {
17614                    IoUtils.closeQuietly(in);
17615                }
17616            }
17617
17618            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
17619                BufferedReader in = null;
17620                String line = null;
17621                try {
17622                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
17623                    while ((line = in.readLine()) != null) {
17624                        if (line.contains("ignored: updated version")) continue;
17625                        pw.print("msg,");
17626                        pw.println(line);
17627                    }
17628                } catch (IOException ignored) {
17629                } finally {
17630                    IoUtils.closeQuietly(in);
17631                }
17632            }
17633        }
17634    }
17635
17636    private String dumpDomainString(String packageName) {
17637        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
17638                .getList();
17639        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
17640
17641        ArraySet<String> result = new ArraySet<>();
17642        if (iviList.size() > 0) {
17643            for (IntentFilterVerificationInfo ivi : iviList) {
17644                for (String host : ivi.getDomains()) {
17645                    result.add(host);
17646                }
17647            }
17648        }
17649        if (filters != null && filters.size() > 0) {
17650            for (IntentFilter filter : filters) {
17651                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
17652                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
17653                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
17654                    result.addAll(filter.getHostsList());
17655                }
17656            }
17657        }
17658
17659        StringBuilder sb = new StringBuilder(result.size() * 16);
17660        for (String domain : result) {
17661            if (sb.length() > 0) sb.append(" ");
17662            sb.append(domain);
17663        }
17664        return sb.toString();
17665    }
17666
17667    // ------- apps on sdcard specific code -------
17668    static final boolean DEBUG_SD_INSTALL = false;
17669
17670    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
17671
17672    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
17673
17674    private boolean mMediaMounted = false;
17675
17676    static String getEncryptKey() {
17677        try {
17678            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
17679                    SD_ENCRYPTION_KEYSTORE_NAME);
17680            if (sdEncKey == null) {
17681                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
17682                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
17683                if (sdEncKey == null) {
17684                    Slog.e(TAG, "Failed to create encryption keys");
17685                    return null;
17686                }
17687            }
17688            return sdEncKey;
17689        } catch (NoSuchAlgorithmException nsae) {
17690            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
17691            return null;
17692        } catch (IOException ioe) {
17693            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
17694            return null;
17695        }
17696    }
17697
17698    /*
17699     * Update media status on PackageManager.
17700     */
17701    @Override
17702    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
17703        int callingUid = Binder.getCallingUid();
17704        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
17705            throw new SecurityException("Media status can only be updated by the system");
17706        }
17707        // reader; this apparently protects mMediaMounted, but should probably
17708        // be a different lock in that case.
17709        synchronized (mPackages) {
17710            Log.i(TAG, "Updating external media status from "
17711                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
17712                    + (mediaStatus ? "mounted" : "unmounted"));
17713            if (DEBUG_SD_INSTALL)
17714                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
17715                        + ", mMediaMounted=" + mMediaMounted);
17716            if (mediaStatus == mMediaMounted) {
17717                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
17718                        : 0, -1);
17719                mHandler.sendMessage(msg);
17720                return;
17721            }
17722            mMediaMounted = mediaStatus;
17723        }
17724        // Queue up an async operation since the package installation may take a
17725        // little while.
17726        mHandler.post(new Runnable() {
17727            public void run() {
17728                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
17729            }
17730        });
17731    }
17732
17733    /**
17734     * Called by MountService when the initial ASECs to scan are available.
17735     * Should block until all the ASEC containers are finished being scanned.
17736     */
17737    public void scanAvailableAsecs() {
17738        updateExternalMediaStatusInner(true, false, false);
17739    }
17740
17741    /*
17742     * Collect information of applications on external media, map them against
17743     * existing containers and update information based on current mount status.
17744     * Please note that we always have to report status if reportStatus has been
17745     * set to true especially when unloading packages.
17746     */
17747    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
17748            boolean externalStorage) {
17749        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
17750        int[] uidArr = EmptyArray.INT;
17751
17752        final String[] list = PackageHelper.getSecureContainerList();
17753        if (ArrayUtils.isEmpty(list)) {
17754            Log.i(TAG, "No secure containers found");
17755        } else {
17756            // Process list of secure containers and categorize them
17757            // as active or stale based on their package internal state.
17758
17759            // reader
17760            synchronized (mPackages) {
17761                for (String cid : list) {
17762                    // Leave stages untouched for now; installer service owns them
17763                    if (PackageInstallerService.isStageName(cid)) continue;
17764
17765                    if (DEBUG_SD_INSTALL)
17766                        Log.i(TAG, "Processing container " + cid);
17767                    String pkgName = getAsecPackageName(cid);
17768                    if (pkgName == null) {
17769                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
17770                        continue;
17771                    }
17772                    if (DEBUG_SD_INSTALL)
17773                        Log.i(TAG, "Looking for pkg : " + pkgName);
17774
17775                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
17776                    if (ps == null) {
17777                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
17778                        continue;
17779                    }
17780
17781                    /*
17782                     * Skip packages that are not external if we're unmounting
17783                     * external storage.
17784                     */
17785                    if (externalStorage && !isMounted && !isExternal(ps)) {
17786                        continue;
17787                    }
17788
17789                    final AsecInstallArgs args = new AsecInstallArgs(cid,
17790                            getAppDexInstructionSets(ps), ps.isForwardLocked());
17791                    // The package status is changed only if the code path
17792                    // matches between settings and the container id.
17793                    if (ps.codePathString != null
17794                            && ps.codePathString.startsWith(args.getCodePath())) {
17795                        if (DEBUG_SD_INSTALL) {
17796                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
17797                                    + " at code path: " + ps.codePathString);
17798                        }
17799
17800                        // We do have a valid package installed on sdcard
17801                        processCids.put(args, ps.codePathString);
17802                        final int uid = ps.appId;
17803                        if (uid != -1) {
17804                            uidArr = ArrayUtils.appendInt(uidArr, uid);
17805                        }
17806                    } else {
17807                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
17808                                + ps.codePathString);
17809                    }
17810                }
17811            }
17812
17813            Arrays.sort(uidArr);
17814        }
17815
17816        // Process packages with valid entries.
17817        if (isMounted) {
17818            if (DEBUG_SD_INSTALL)
17819                Log.i(TAG, "Loading packages");
17820            loadMediaPackages(processCids, uidArr, externalStorage);
17821            startCleaningPackages();
17822            mInstallerService.onSecureContainersAvailable();
17823        } else {
17824            if (DEBUG_SD_INSTALL)
17825                Log.i(TAG, "Unloading packages");
17826            unloadMediaPackages(processCids, uidArr, reportStatus);
17827        }
17828    }
17829
17830    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
17831            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
17832        final int size = infos.size();
17833        final String[] packageNames = new String[size];
17834        final int[] packageUids = new int[size];
17835        for (int i = 0; i < size; i++) {
17836            final ApplicationInfo info = infos.get(i);
17837            packageNames[i] = info.packageName;
17838            packageUids[i] = info.uid;
17839        }
17840        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
17841                finishedReceiver);
17842    }
17843
17844    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
17845            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
17846        sendResourcesChangedBroadcast(mediaStatus, replacing,
17847                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
17848    }
17849
17850    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
17851            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
17852        int size = pkgList.length;
17853        if (size > 0) {
17854            // Send broadcasts here
17855            Bundle extras = new Bundle();
17856            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
17857            if (uidArr != null) {
17858                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
17859            }
17860            if (replacing) {
17861                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
17862            }
17863            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
17864                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
17865            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
17866        }
17867    }
17868
17869   /*
17870     * Look at potentially valid container ids from processCids If package
17871     * information doesn't match the one on record or package scanning fails,
17872     * the cid is added to list of removeCids. We currently don't delete stale
17873     * containers.
17874     */
17875    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
17876            boolean externalStorage) {
17877        ArrayList<String> pkgList = new ArrayList<String>();
17878        Set<AsecInstallArgs> keys = processCids.keySet();
17879
17880        for (AsecInstallArgs args : keys) {
17881            String codePath = processCids.get(args);
17882            if (DEBUG_SD_INSTALL)
17883                Log.i(TAG, "Loading container : " + args.cid);
17884            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17885            try {
17886                // Make sure there are no container errors first.
17887                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
17888                    Slog.e(TAG, "Failed to mount cid : " + args.cid
17889                            + " when installing from sdcard");
17890                    continue;
17891                }
17892                // Check code path here.
17893                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
17894                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
17895                            + " does not match one in settings " + codePath);
17896                    continue;
17897                }
17898                // Parse package
17899                int parseFlags = mDefParseFlags;
17900                if (args.isExternalAsec()) {
17901                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
17902                }
17903                if (args.isFwdLocked()) {
17904                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
17905                }
17906
17907                synchronized (mInstallLock) {
17908                    PackageParser.Package pkg = null;
17909                    try {
17910                        pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null);
17911                    } catch (PackageManagerException e) {
17912                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
17913                    }
17914                    // Scan the package
17915                    if (pkg != null) {
17916                        /*
17917                         * TODO why is the lock being held? doPostInstall is
17918                         * called in other places without the lock. This needs
17919                         * to be straightened out.
17920                         */
17921                        // writer
17922                        synchronized (mPackages) {
17923                            retCode = PackageManager.INSTALL_SUCCEEDED;
17924                            pkgList.add(pkg.packageName);
17925                            // Post process args
17926                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
17927                                    pkg.applicationInfo.uid);
17928                        }
17929                    } else {
17930                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
17931                    }
17932                }
17933
17934            } finally {
17935                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
17936                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
17937                }
17938            }
17939        }
17940        // writer
17941        synchronized (mPackages) {
17942            // If the platform SDK has changed since the last time we booted,
17943            // we need to re-grant app permission to catch any new ones that
17944            // appear. This is really a hack, and means that apps can in some
17945            // cases get permissions that the user didn't initially explicitly
17946            // allow... it would be nice to have some better way to handle
17947            // this situation.
17948            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
17949                    : mSettings.getInternalVersion();
17950            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
17951                    : StorageManager.UUID_PRIVATE_INTERNAL;
17952
17953            int updateFlags = UPDATE_PERMISSIONS_ALL;
17954            if (ver.sdkVersion != mSdkVersion) {
17955                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
17956                        + mSdkVersion + "; regranting permissions for external");
17957                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
17958            }
17959            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
17960
17961            // Yay, everything is now upgraded
17962            ver.forceCurrent();
17963
17964            // can downgrade to reader
17965            // Persist settings
17966            mSettings.writeLPr();
17967        }
17968        // Send a broadcast to let everyone know we are done processing
17969        if (pkgList.size() > 0) {
17970            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
17971        }
17972    }
17973
17974   /*
17975     * Utility method to unload a list of specified containers
17976     */
17977    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
17978        // Just unmount all valid containers.
17979        for (AsecInstallArgs arg : cidArgs) {
17980            synchronized (mInstallLock) {
17981                arg.doPostDeleteLI(false);
17982           }
17983       }
17984   }
17985
17986    /*
17987     * Unload packages mounted on external media. This involves deleting package
17988     * data from internal structures, sending broadcasts about disabled packages,
17989     * gc'ing to free up references, unmounting all secure containers
17990     * corresponding to packages on external media, and posting a
17991     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
17992     * that we always have to post this message if status has been requested no
17993     * matter what.
17994     */
17995    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
17996            final boolean reportStatus) {
17997        if (DEBUG_SD_INSTALL)
17998            Log.i(TAG, "unloading media packages");
17999        ArrayList<String> pkgList = new ArrayList<String>();
18000        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
18001        final Set<AsecInstallArgs> keys = processCids.keySet();
18002        for (AsecInstallArgs args : keys) {
18003            String pkgName = args.getPackageName();
18004            if (DEBUG_SD_INSTALL)
18005                Log.i(TAG, "Trying to unload pkg : " + pkgName);
18006            // Delete package internally
18007            PackageRemovedInfo outInfo = new PackageRemovedInfo();
18008            synchronized (mInstallLock) {
18009                boolean res = deletePackageLI(pkgName, null, false, null,
18010                        PackageManager.DELETE_KEEP_DATA, outInfo, false, null);
18011                if (res) {
18012                    pkgList.add(pkgName);
18013                } else {
18014                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
18015                    failedList.add(args);
18016                }
18017            }
18018        }
18019
18020        // reader
18021        synchronized (mPackages) {
18022            // We didn't update the settings after removing each package;
18023            // write them now for all packages.
18024            mSettings.writeLPr();
18025        }
18026
18027        // We have to absolutely send UPDATED_MEDIA_STATUS only
18028        // after confirming that all the receivers processed the ordered
18029        // broadcast when packages get disabled, force a gc to clean things up.
18030        // and unload all the containers.
18031        if (pkgList.size() > 0) {
18032            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
18033                    new IIntentReceiver.Stub() {
18034                public void performReceive(Intent intent, int resultCode, String data,
18035                        Bundle extras, boolean ordered, boolean sticky,
18036                        int sendingUser) throws RemoteException {
18037                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
18038                            reportStatus ? 1 : 0, 1, keys);
18039                    mHandler.sendMessage(msg);
18040                }
18041            });
18042        } else {
18043            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
18044                    keys);
18045            mHandler.sendMessage(msg);
18046        }
18047    }
18048
18049    private void loadPrivatePackages(final VolumeInfo vol) {
18050        mHandler.post(new Runnable() {
18051            @Override
18052            public void run() {
18053                loadPrivatePackagesInner(vol);
18054            }
18055        });
18056    }
18057
18058    private void loadPrivatePackagesInner(VolumeInfo vol) {
18059        final String volumeUuid = vol.fsUuid;
18060        if (TextUtils.isEmpty(volumeUuid)) {
18061            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
18062            return;
18063        }
18064
18065        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
18066        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
18067
18068        final VersionInfo ver;
18069        final List<PackageSetting> packages;
18070        synchronized (mPackages) {
18071            ver = mSettings.findOrCreateVersion(volumeUuid);
18072            packages = mSettings.getVolumePackagesLPr(volumeUuid);
18073        }
18074
18075        // TODO: introduce a new concept similar to "frozen" to prevent these
18076        // apps from being launched until after data has been fully reconciled
18077        for (PackageSetting ps : packages) {
18078            synchronized (mInstallLock) {
18079                final PackageParser.Package pkg;
18080                try {
18081                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
18082                    loaded.add(pkg.applicationInfo);
18083
18084                } catch (PackageManagerException e) {
18085                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
18086                }
18087
18088                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
18089                    deleteCodeCacheDirsLI(ps.volumeUuid, ps.name);
18090                }
18091            }
18092        }
18093
18094        // Reconcile app data for all started/unlocked users
18095        final StorageManager sm = mContext.getSystemService(StorageManager.class);
18096        final UserManager um = mContext.getSystemService(UserManager.class);
18097        for (UserInfo user : um.getUsers()) {
18098            final int flags;
18099            if (um.isUserUnlocked(user.id)) {
18100                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18101            } else if (um.isUserRunning(user.id)) {
18102                flags = StorageManager.FLAG_STORAGE_DE;
18103            } else {
18104                continue;
18105            }
18106
18107            sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
18108            reconcileAppsData(volumeUuid, user.id, flags);
18109        }
18110
18111        synchronized (mPackages) {
18112            int updateFlags = UPDATE_PERMISSIONS_ALL;
18113            if (ver.sdkVersion != mSdkVersion) {
18114                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
18115                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
18116                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
18117            }
18118            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
18119
18120            // Yay, everything is now upgraded
18121            ver.forceCurrent();
18122
18123            mSettings.writeLPr();
18124        }
18125
18126        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
18127        sendResourcesChangedBroadcast(true, false, loaded, null);
18128    }
18129
18130    private void unloadPrivatePackages(final VolumeInfo vol) {
18131        mHandler.post(new Runnable() {
18132            @Override
18133            public void run() {
18134                unloadPrivatePackagesInner(vol);
18135            }
18136        });
18137    }
18138
18139    private void unloadPrivatePackagesInner(VolumeInfo vol) {
18140        final String volumeUuid = vol.fsUuid;
18141        if (TextUtils.isEmpty(volumeUuid)) {
18142            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
18143            return;
18144        }
18145
18146        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
18147        synchronized (mInstallLock) {
18148        synchronized (mPackages) {
18149            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
18150            for (PackageSetting ps : packages) {
18151                if (ps.pkg == null) continue;
18152
18153                final ApplicationInfo info = ps.pkg.applicationInfo;
18154                final PackageRemovedInfo outInfo = new PackageRemovedInfo();
18155                if (deletePackageLI(ps.name, null, false, null,
18156                        PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) {
18157                    unloaded.add(info);
18158                } else {
18159                    Slog.w(TAG, "Failed to unload " + ps.codePath);
18160                }
18161            }
18162
18163            mSettings.writeLPr();
18164        }
18165        }
18166
18167        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
18168        sendResourcesChangedBroadcast(false, false, unloaded, null);
18169    }
18170
18171    /**
18172     * Examine all users present on given mounted volume, and destroy data
18173     * belonging to users that are no longer valid, or whose user ID has been
18174     * recycled.
18175     */
18176    private void reconcileUsers(String volumeUuid) {
18177        // TODO: also reconcile DE directories
18178        final File[] files = FileUtils
18179                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid));
18180        for (File file : files) {
18181            if (!file.isDirectory()) continue;
18182
18183            final int userId;
18184            final UserInfo info;
18185            try {
18186                userId = Integer.parseInt(file.getName());
18187                info = sUserManager.getUserInfo(userId);
18188            } catch (NumberFormatException e) {
18189                Slog.w(TAG, "Invalid user directory " + file);
18190                continue;
18191            }
18192
18193            boolean destroyUser = false;
18194            if (info == null) {
18195                logCriticalInfo(Log.WARN, "Destroying user directory " + file
18196                        + " because no matching user was found");
18197                destroyUser = true;
18198            } else {
18199                try {
18200                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
18201                } catch (IOException e) {
18202                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
18203                            + " because we failed to enforce serial number: " + e);
18204                    destroyUser = true;
18205                }
18206            }
18207
18208            if (destroyUser) {
18209                synchronized (mInstallLock) {
18210                    try {
18211                        mInstaller.removeUserDataDirs(volumeUuid, userId);
18212                    } catch (InstallerException e) {
18213                        Slog.w(TAG, "Failed to clean up user dirs", e);
18214                    }
18215                }
18216            }
18217        }
18218    }
18219
18220    private void assertPackageKnown(String volumeUuid, String packageName)
18221            throws PackageManagerException {
18222        synchronized (mPackages) {
18223            final PackageSetting ps = mSettings.mPackages.get(packageName);
18224            if (ps == null) {
18225                throw new PackageManagerException("Package " + packageName + " is unknown");
18226            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
18227                throw new PackageManagerException(
18228                        "Package " + packageName + " found on unknown volume " + volumeUuid
18229                                + "; expected volume " + ps.volumeUuid);
18230            }
18231        }
18232    }
18233
18234    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
18235            throws PackageManagerException {
18236        synchronized (mPackages) {
18237            final PackageSetting ps = mSettings.mPackages.get(packageName);
18238            if (ps == null) {
18239                throw new PackageManagerException("Package " + packageName + " is unknown");
18240            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
18241                throw new PackageManagerException(
18242                        "Package " + packageName + " found on unknown volume " + volumeUuid
18243                                + "; expected volume " + ps.volumeUuid);
18244            } else if (!ps.getInstalled(userId)) {
18245                throw new PackageManagerException(
18246                        "Package " + packageName + " not installed for user " + userId);
18247            }
18248        }
18249    }
18250
18251    /**
18252     * Examine all apps present on given mounted volume, and destroy apps that
18253     * aren't expected, either due to uninstallation or reinstallation on
18254     * another volume.
18255     */
18256    private void reconcileApps(String volumeUuid) {
18257        final File[] files = FileUtils
18258                .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid));
18259        for (File file : files) {
18260            final boolean isPackage = (isApkFile(file) || file.isDirectory())
18261                    && !PackageInstallerService.isStageName(file.getName());
18262            if (!isPackage) {
18263                // Ignore entries which are not packages
18264                continue;
18265            }
18266
18267            try {
18268                final PackageLite pkg = PackageParser.parsePackageLite(file,
18269                        PackageParser.PARSE_MUST_BE_APK);
18270                assertPackageKnown(volumeUuid, pkg.packageName);
18271
18272            } catch (PackageParserException | PackageManagerException e) {
18273                logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
18274                synchronized (mInstallLock) {
18275                    removeCodePathLI(file);
18276                }
18277            }
18278        }
18279    }
18280
18281    /**
18282     * Reconcile all app data for the given user.
18283     * <p>
18284     * Verifies that directories exist and that ownership and labeling is
18285     * correct for all installed apps on all mounted volumes.
18286     */
18287    void reconcileAppsData(int userId, int flags) {
18288        final StorageManager storage = mContext.getSystemService(StorageManager.class);
18289        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
18290            final String volumeUuid = vol.getFsUuid();
18291            reconcileAppsData(volumeUuid, userId, flags);
18292        }
18293    }
18294
18295    /**
18296     * Reconcile all app data on given mounted volume.
18297     * <p>
18298     * Destroys app data that isn't expected, either due to uninstallation or
18299     * reinstallation on another volume.
18300     * <p>
18301     * Verifies that directories exist and that ownership and labeling is
18302     * correct for all installed apps.
18303     */
18304    private void reconcileAppsData(String volumeUuid, int userId, int flags) {
18305        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
18306                + Integer.toHexString(flags));
18307
18308        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
18309        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
18310
18311        boolean restoreconNeeded = false;
18312
18313        // First look for stale data that doesn't belong, and check if things
18314        // have changed since we did our last restorecon
18315        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
18316            if (!isUserKeyUnlocked(userId)) {
18317                throw new RuntimeException(
18318                        "Yikes, someone asked us to reconcile CE storage while " + userId
18319                                + " was still locked; this would have caused massive data loss!");
18320            }
18321
18322            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir);
18323
18324            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
18325            for (File file : files) {
18326                final String packageName = file.getName();
18327                try {
18328                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
18329                } catch (PackageManagerException e) {
18330                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
18331                    synchronized (mInstallLock) {
18332                        destroyAppDataLI(volumeUuid, packageName, userId,
18333                                StorageManager.FLAG_STORAGE_CE);
18334                    }
18335                }
18336            }
18337        }
18338        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
18339            restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir);
18340
18341            final File[] files = FileUtils.listFilesOrEmpty(deDir);
18342            for (File file : files) {
18343                final String packageName = file.getName();
18344                try {
18345                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
18346                } catch (PackageManagerException e) {
18347                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
18348                    synchronized (mInstallLock) {
18349                        destroyAppDataLI(volumeUuid, packageName, userId,
18350                                StorageManager.FLAG_STORAGE_DE);
18351                    }
18352                }
18353            }
18354        }
18355
18356        // Ensure that data directories are ready to roll for all packages
18357        // installed for this volume and user
18358        final List<PackageSetting> packages;
18359        synchronized (mPackages) {
18360            packages = mSettings.getVolumePackagesLPr(volumeUuid);
18361        }
18362        int preparedCount = 0;
18363        for (PackageSetting ps : packages) {
18364            final String packageName = ps.name;
18365            if (ps.pkg == null) {
18366                Slog.w(TAG, "Odd, missing scanned package " + packageName);
18367                // TODO: might be due to legacy ASEC apps; we should circle back
18368                // and reconcile again once they're scanned
18369                continue;
18370            }
18371
18372            if (ps.getInstalled(userId)) {
18373                prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
18374
18375                if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) {
18376                    // We may have just shuffled around app data directories, so
18377                    // prepare them one more time
18378                    prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded);
18379                }
18380
18381                preparedCount++;
18382            }
18383        }
18384
18385        if (restoreconNeeded) {
18386            if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
18387                SELinuxMMAC.setRestoreconDone(ceDir);
18388            }
18389            if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
18390                SELinuxMMAC.setRestoreconDone(deDir);
18391            }
18392        }
18393
18394        Slog.v(TAG, "reconcileAppsData finished " + preparedCount
18395                + " packages; restoreconNeeded was " + restoreconNeeded);
18396    }
18397
18398    /**
18399     * Prepare app data for the given app just after it was installed or
18400     * upgraded. This method carefully only touches users that it's installed
18401     * for, and it forces a restorecon to handle any seinfo changes.
18402     * <p>
18403     * Verifies that directories exist and that ownership and labeling is
18404     * correct for all installed apps. If there is an ownership mismatch, it
18405     * will try recovering system apps by wiping data; third-party app data is
18406     * left intact.
18407     * <p>
18408     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
18409     */
18410    private void prepareAppDataAfterInstall(PackageParser.Package pkg) {
18411        prepareAppDataAfterInstallInternal(pkg);
18412        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18413        for (int i = 0; i < childCount; i++) {
18414            PackageParser.Package childPackage = pkg.childPackages.get(i);
18415            prepareAppDataAfterInstallInternal(childPackage);
18416        }
18417    }
18418
18419    private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) {
18420        final PackageSetting ps;
18421        synchronized (mPackages) {
18422            ps = mSettings.mPackages.get(pkg.packageName);
18423            mSettings.writeKernelMappingLPr(ps);
18424        }
18425
18426        final UserManager um = mContext.getSystemService(UserManager.class);
18427        for (UserInfo user : um.getUsers()) {
18428            final int flags;
18429            if (um.isUserUnlocked(user.id)) {
18430                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18431            } else if (um.isUserRunning(user.id)) {
18432                flags = StorageManager.FLAG_STORAGE_DE;
18433            } else {
18434                continue;
18435            }
18436
18437            if (ps.getInstalled(user.id)) {
18438                // Whenever an app changes, force a restorecon of its data
18439                // TODO: when user data is locked, mark that we're still dirty
18440                prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true);
18441            }
18442        }
18443    }
18444
18445    /**
18446     * Prepare app data for the given app.
18447     * <p>
18448     * Verifies that directories exist and that ownership and labeling is
18449     * correct for all installed apps. If there is an ownership mismatch, this
18450     * will try recovering system apps by wiping data; third-party app data is
18451     * left intact.
18452     */
18453    private void prepareAppData(String volumeUuid, int userId, int flags,
18454            PackageParser.Package pkg, boolean restoreconNeeded) {
18455        if (DEBUG_APP_DATA) {
18456            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
18457                    + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : ""));
18458        }
18459
18460        final String packageName = pkg.packageName;
18461        final ApplicationInfo app = pkg.applicationInfo;
18462        final int appId = UserHandle.getAppId(app.uid);
18463
18464        Preconditions.checkNotNull(app.seinfo);
18465
18466        synchronized (mInstallLock) {
18467            try {
18468                mInstaller.createAppData(volumeUuid, packageName, userId, flags,
18469                        appId, app.seinfo, app.targetSdkVersion);
18470            } catch (InstallerException e) {
18471                if (app.isSystemApp()) {
18472                    logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
18473                            + ", but trying to recover: " + e);
18474                    destroyAppDataLI(volumeUuid, packageName, userId, flags);
18475                    try {
18476                        mInstaller.createAppData(volumeUuid, packageName, userId, flags,
18477                                appId, app.seinfo, app.targetSdkVersion);
18478                        logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
18479                    } catch (InstallerException e2) {
18480                        logCriticalInfo(Log.DEBUG, "Recovery failed!");
18481                    }
18482                } else {
18483                    Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
18484                }
18485            }
18486
18487            if (restoreconNeeded) {
18488                restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo);
18489            }
18490
18491            if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
18492                // Create a native library symlink only if we have native libraries
18493                // and if the native libraries are 32 bit libraries. We do not provide
18494                // this symlink for 64 bit libraries.
18495                if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
18496                    final String nativeLibPath = app.nativeLibraryDir;
18497                    try {
18498                        mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
18499                                nativeLibPath, userId);
18500                    } catch (InstallerException e) {
18501                        Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
18502                    }
18503                }
18504            }
18505        }
18506    }
18507
18508    /**
18509     * For system apps on non-FBE devices, this method migrates any existing
18510     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
18511     * requested by the app.
18512     */
18513    private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) {
18514        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
18515                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
18516            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
18517                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
18518            synchronized (mInstallLock) {
18519                try {
18520                    mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget);
18521                } catch (InstallerException e) {
18522                    logCriticalInfo(Log.WARN,
18523                            "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
18524                }
18525            }
18526            return true;
18527        } else {
18528            return false;
18529        }
18530    }
18531
18532    private void unfreezePackage(String packageName) {
18533        synchronized (mPackages) {
18534            final PackageSetting ps = mSettings.mPackages.get(packageName);
18535            if (ps != null) {
18536                ps.frozen = false;
18537            }
18538        }
18539    }
18540
18541    @Override
18542    public int movePackage(final String packageName, final String volumeUuid) {
18543        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
18544
18545        final int moveId = mNextMoveId.getAndIncrement();
18546        mHandler.post(new Runnable() {
18547            @Override
18548            public void run() {
18549                try {
18550                    movePackageInternal(packageName, volumeUuid, moveId);
18551                } catch (PackageManagerException e) {
18552                    Slog.w(TAG, "Failed to move " + packageName, e);
18553                    mMoveCallbacks.notifyStatusChanged(moveId,
18554                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
18555                }
18556            }
18557        });
18558        return moveId;
18559    }
18560
18561    private void movePackageInternal(final String packageName, final String volumeUuid,
18562            final int moveId) throws PackageManagerException {
18563        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
18564        final StorageManager storage = mContext.getSystemService(StorageManager.class);
18565        final PackageManager pm = mContext.getPackageManager();
18566
18567        final boolean currentAsec;
18568        final String currentVolumeUuid;
18569        final File codeFile;
18570        final String installerPackageName;
18571        final String packageAbiOverride;
18572        final int appId;
18573        final String seinfo;
18574        final String label;
18575        final int targetSdkVersion;
18576
18577        // reader
18578        synchronized (mPackages) {
18579            final PackageParser.Package pkg = mPackages.get(packageName);
18580            final PackageSetting ps = mSettings.mPackages.get(packageName);
18581            if (pkg == null || ps == null) {
18582                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
18583            }
18584
18585            if (pkg.applicationInfo.isSystemApp()) {
18586                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
18587                        "Cannot move system application");
18588            }
18589
18590            if (pkg.applicationInfo.isExternalAsec()) {
18591                currentAsec = true;
18592                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
18593            } else if (pkg.applicationInfo.isForwardLocked()) {
18594                currentAsec = true;
18595                currentVolumeUuid = "forward_locked";
18596            } else {
18597                currentAsec = false;
18598                currentVolumeUuid = ps.volumeUuid;
18599
18600                final File probe = new File(pkg.codePath);
18601                final File probeOat = new File(probe, "oat");
18602                if (!probe.isDirectory() || !probeOat.isDirectory()) {
18603                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
18604                            "Move only supported for modern cluster style installs");
18605                }
18606            }
18607
18608            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
18609                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
18610                        "Package already moved to " + volumeUuid);
18611            }
18612            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
18613                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
18614                        "Device admin cannot be moved");
18615            }
18616
18617            if (ps.frozen) {
18618                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
18619                        "Failed to move already frozen package");
18620            }
18621            ps.frozen = true;
18622
18623            codeFile = new File(pkg.codePath);
18624            installerPackageName = ps.installerPackageName;
18625            packageAbiOverride = ps.cpuAbiOverrideString;
18626            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18627            seinfo = pkg.applicationInfo.seinfo;
18628            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
18629            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
18630        }
18631
18632        // Now that we're guarded by frozen state, kill app during move
18633        final long token = Binder.clearCallingIdentity();
18634        try {
18635            killApplication(packageName, appId, "move pkg");
18636        } finally {
18637            Binder.restoreCallingIdentity(token);
18638        }
18639
18640        final Bundle extras = new Bundle();
18641        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
18642        extras.putString(Intent.EXTRA_TITLE, label);
18643        mMoveCallbacks.notifyCreated(moveId, extras);
18644
18645        int installFlags;
18646        final boolean moveCompleteApp;
18647        final File measurePath;
18648
18649        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
18650            installFlags = INSTALL_INTERNAL;
18651            moveCompleteApp = !currentAsec;
18652            measurePath = Environment.getDataAppDirectory(volumeUuid);
18653        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
18654            installFlags = INSTALL_EXTERNAL;
18655            moveCompleteApp = false;
18656            measurePath = storage.getPrimaryPhysicalVolume().getPath();
18657        } else {
18658            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
18659            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
18660                    || !volume.isMountedWritable()) {
18661                unfreezePackage(packageName);
18662                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
18663                        "Move location not mounted private volume");
18664            }
18665
18666            Preconditions.checkState(!currentAsec);
18667
18668            installFlags = INSTALL_INTERNAL;
18669            moveCompleteApp = true;
18670            measurePath = Environment.getDataAppDirectory(volumeUuid);
18671        }
18672
18673        final PackageStats stats = new PackageStats(null, -1);
18674        synchronized (mInstaller) {
18675            if (!getPackageSizeInfoLI(packageName, -1, stats)) {
18676                unfreezePackage(packageName);
18677                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
18678                        "Failed to measure package size");
18679            }
18680        }
18681
18682        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
18683                + stats.dataSize);
18684
18685        final long startFreeBytes = measurePath.getFreeSpace();
18686        final long sizeBytes;
18687        if (moveCompleteApp) {
18688            sizeBytes = stats.codeSize + stats.dataSize;
18689        } else {
18690            sizeBytes = stats.codeSize;
18691        }
18692
18693        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
18694            unfreezePackage(packageName);
18695            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
18696                    "Not enough free space to move");
18697        }
18698
18699        mMoveCallbacks.notifyStatusChanged(moveId, 10);
18700
18701        final CountDownLatch installedLatch = new CountDownLatch(1);
18702        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
18703            @Override
18704            public void onUserActionRequired(Intent intent) throws RemoteException {
18705                throw new IllegalStateException();
18706            }
18707
18708            @Override
18709            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
18710                    Bundle extras) throws RemoteException {
18711                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
18712                        + PackageManager.installStatusToString(returnCode, msg));
18713
18714                installedLatch.countDown();
18715
18716                // Regardless of success or failure of the move operation,
18717                // always unfreeze the package
18718                unfreezePackage(packageName);
18719
18720                final int status = PackageManager.installStatusToPublicStatus(returnCode);
18721                switch (status) {
18722                    case PackageInstaller.STATUS_SUCCESS:
18723                        mMoveCallbacks.notifyStatusChanged(moveId,
18724                                PackageManager.MOVE_SUCCEEDED);
18725                        break;
18726                    case PackageInstaller.STATUS_FAILURE_STORAGE:
18727                        mMoveCallbacks.notifyStatusChanged(moveId,
18728                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
18729                        break;
18730                    default:
18731                        mMoveCallbacks.notifyStatusChanged(moveId,
18732                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
18733                        break;
18734                }
18735            }
18736        };
18737
18738        final MoveInfo move;
18739        if (moveCompleteApp) {
18740            // Kick off a thread to report progress estimates
18741            new Thread() {
18742                @Override
18743                public void run() {
18744                    while (true) {
18745                        try {
18746                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
18747                                break;
18748                            }
18749                        } catch (InterruptedException ignored) {
18750                        }
18751
18752                        final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
18753                        final int progress = 10 + (int) MathUtils.constrain(
18754                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
18755                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
18756                    }
18757                }
18758            }.start();
18759
18760            final String dataAppName = codeFile.getName();
18761            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
18762                    dataAppName, appId, seinfo, targetSdkVersion);
18763        } else {
18764            move = null;
18765        }
18766
18767        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
18768
18769        final Message msg = mHandler.obtainMessage(INIT_COPY);
18770        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
18771        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
18772                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
18773                packageAbiOverride, null);
18774        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
18775        msg.obj = params;
18776
18777        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
18778                System.identityHashCode(msg.obj));
18779        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
18780                System.identityHashCode(msg.obj));
18781
18782        mHandler.sendMessage(msg);
18783    }
18784
18785    @Override
18786    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
18787        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
18788
18789        final int realMoveId = mNextMoveId.getAndIncrement();
18790        final Bundle extras = new Bundle();
18791        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
18792        mMoveCallbacks.notifyCreated(realMoveId, extras);
18793
18794        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
18795            @Override
18796            public void onCreated(int moveId, Bundle extras) {
18797                // Ignored
18798            }
18799
18800            @Override
18801            public void onStatusChanged(int moveId, int status, long estMillis) {
18802                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
18803            }
18804        };
18805
18806        final StorageManager storage = mContext.getSystemService(StorageManager.class);
18807        storage.setPrimaryStorageUuid(volumeUuid, callback);
18808        return realMoveId;
18809    }
18810
18811    @Override
18812    public int getMoveStatus(int moveId) {
18813        mContext.enforceCallingOrSelfPermission(
18814                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
18815        return mMoveCallbacks.mLastStatus.get(moveId);
18816    }
18817
18818    @Override
18819    public void registerMoveCallback(IPackageMoveObserver callback) {
18820        mContext.enforceCallingOrSelfPermission(
18821                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
18822        mMoveCallbacks.register(callback);
18823    }
18824
18825    @Override
18826    public void unregisterMoveCallback(IPackageMoveObserver callback) {
18827        mContext.enforceCallingOrSelfPermission(
18828                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
18829        mMoveCallbacks.unregister(callback);
18830    }
18831
18832    @Override
18833    public boolean setInstallLocation(int loc) {
18834        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
18835                null);
18836        if (getInstallLocation() == loc) {
18837            return true;
18838        }
18839        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
18840                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
18841            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
18842                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
18843            return true;
18844        }
18845        return false;
18846   }
18847
18848    @Override
18849    public int getInstallLocation() {
18850        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
18851                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
18852                PackageHelper.APP_INSTALL_AUTO);
18853    }
18854
18855    /** Called by UserManagerService */
18856    void cleanUpUser(UserManagerService userManager, int userHandle) {
18857        synchronized (mPackages) {
18858            mDirtyUsers.remove(userHandle);
18859            mUserNeedsBadging.delete(userHandle);
18860            mSettings.removeUserLPw(userHandle);
18861            mPendingBroadcasts.remove(userHandle);
18862            mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle);
18863        }
18864        synchronized (mInstallLock) {
18865            final StorageManager storage = mContext.getSystemService(StorageManager.class);
18866            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
18867                final String volumeUuid = vol.getFsUuid();
18868                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
18869                try {
18870                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
18871                } catch (InstallerException e) {
18872                    Slog.w(TAG, "Failed to remove user data", e);
18873                }
18874            }
18875            synchronized (mPackages) {
18876                removeUnusedPackagesLILPw(userManager, userHandle);
18877            }
18878        }
18879    }
18880
18881    /**
18882     * We're removing userHandle and would like to remove any downloaded packages
18883     * that are no longer in use by any other user.
18884     * @param userHandle the user being removed
18885     */
18886    private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
18887        final boolean DEBUG_CLEAN_APKS = false;
18888        int [] users = userManager.getUserIds();
18889        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
18890        while (psit.hasNext()) {
18891            PackageSetting ps = psit.next();
18892            if (ps.pkg == null) {
18893                continue;
18894            }
18895            final String packageName = ps.pkg.packageName;
18896            // Skip over if system app
18897            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
18898                continue;
18899            }
18900            if (DEBUG_CLEAN_APKS) {
18901                Slog.i(TAG, "Checking package " + packageName);
18902            }
18903            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
18904            if (keep) {
18905                if (DEBUG_CLEAN_APKS) {
18906                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
18907                }
18908            } else {
18909                for (int i = 0; i < users.length; i++) {
18910                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
18911                        keep = true;
18912                        if (DEBUG_CLEAN_APKS) {
18913                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
18914                                    + users[i]);
18915                        }
18916                        break;
18917                    }
18918                }
18919            }
18920            if (!keep) {
18921                if (DEBUG_CLEAN_APKS) {
18922                    Slog.i(TAG, "  Removing package " + packageName);
18923                }
18924                mHandler.post(new Runnable() {
18925                    public void run() {
18926                        deletePackageX(packageName, userHandle, 0);
18927                    } //end run
18928                });
18929            }
18930        }
18931    }
18932
18933    /** Called by UserManagerService */
18934    void createNewUser(int userHandle) {
18935        synchronized (mInstallLock) {
18936            try {
18937                mInstaller.createUserConfig(userHandle);
18938            } catch (InstallerException e) {
18939                Slog.w(TAG, "Failed to create user config", e);
18940            }
18941            mSettings.createNewUserLI(this, mInstaller, userHandle);
18942        }
18943        synchronized (mPackages) {
18944            applyFactoryDefaultBrowserLPw(userHandle);
18945            primeDomainVerificationsLPw(userHandle);
18946        }
18947    }
18948
18949    void newUserCreated(final int userHandle) {
18950        mDefaultPermissionPolicy.grantDefaultPermissions(userHandle);
18951        // If permission review for legacy apps is required, we represent
18952        // dagerous permissions for such apps as always granted runtime
18953        // permissions to keep per user flag state whether review is needed.
18954        // Hence, if a new user is added we have to propagate dangerous
18955        // permission grants for these legacy apps.
18956        if (Build.PERMISSIONS_REVIEW_REQUIRED) {
18957            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
18958                    | UPDATE_PERMISSIONS_REPLACE_ALL);
18959        }
18960    }
18961
18962    @Override
18963    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
18964        mContext.enforceCallingOrSelfPermission(
18965                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
18966                "Only package verification agents can read the verifier device identity");
18967
18968        synchronized (mPackages) {
18969            return mSettings.getVerifierDeviceIdentityLPw();
18970        }
18971    }
18972
18973    @Override
18974    public void setPermissionEnforced(String permission, boolean enforced) {
18975        // TODO: Now that we no longer change GID for storage, this should to away.
18976        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
18977                "setPermissionEnforced");
18978        if (READ_EXTERNAL_STORAGE.equals(permission)) {
18979            synchronized (mPackages) {
18980                if (mSettings.mReadExternalStorageEnforced == null
18981                        || mSettings.mReadExternalStorageEnforced != enforced) {
18982                    mSettings.mReadExternalStorageEnforced = enforced;
18983                    mSettings.writeLPr();
18984                }
18985            }
18986            // kill any non-foreground processes so we restart them and
18987            // grant/revoke the GID.
18988            final IActivityManager am = ActivityManagerNative.getDefault();
18989            if (am != null) {
18990                final long token = Binder.clearCallingIdentity();
18991                try {
18992                    am.killProcessesBelowForeground("setPermissionEnforcement");
18993                } catch (RemoteException e) {
18994                } finally {
18995                    Binder.restoreCallingIdentity(token);
18996                }
18997            }
18998        } else {
18999            throw new IllegalArgumentException("No selective enforcement for " + permission);
19000        }
19001    }
19002
19003    @Override
19004    @Deprecated
19005    public boolean isPermissionEnforced(String permission) {
19006        return true;
19007    }
19008
19009    @Override
19010    public boolean isStorageLow() {
19011        final long token = Binder.clearCallingIdentity();
19012        try {
19013            final DeviceStorageMonitorInternal
19014                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
19015            if (dsm != null) {
19016                return dsm.isMemoryLow();
19017            } else {
19018                return false;
19019            }
19020        } finally {
19021            Binder.restoreCallingIdentity(token);
19022        }
19023    }
19024
19025    @Override
19026    public IPackageInstaller getPackageInstaller() {
19027        return mInstallerService;
19028    }
19029
19030    private boolean userNeedsBadging(int userId) {
19031        int index = mUserNeedsBadging.indexOfKey(userId);
19032        if (index < 0) {
19033            final UserInfo userInfo;
19034            final long token = Binder.clearCallingIdentity();
19035            try {
19036                userInfo = sUserManager.getUserInfo(userId);
19037            } finally {
19038                Binder.restoreCallingIdentity(token);
19039            }
19040            final boolean b;
19041            if (userInfo != null && userInfo.isManagedProfile()) {
19042                b = true;
19043            } else {
19044                b = false;
19045            }
19046            mUserNeedsBadging.put(userId, b);
19047            return b;
19048        }
19049        return mUserNeedsBadging.valueAt(index);
19050    }
19051
19052    @Override
19053    public KeySet getKeySetByAlias(String packageName, String alias) {
19054        if (packageName == null || alias == null) {
19055            return null;
19056        }
19057        synchronized(mPackages) {
19058            final PackageParser.Package pkg = mPackages.get(packageName);
19059            if (pkg == null) {
19060                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
19061                throw new IllegalArgumentException("Unknown package: " + packageName);
19062            }
19063            KeySetManagerService ksms = mSettings.mKeySetManagerService;
19064            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
19065        }
19066    }
19067
19068    @Override
19069    public KeySet getSigningKeySet(String packageName) {
19070        if (packageName == null) {
19071            return null;
19072        }
19073        synchronized(mPackages) {
19074            final PackageParser.Package pkg = mPackages.get(packageName);
19075            if (pkg == null) {
19076                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
19077                throw new IllegalArgumentException("Unknown package: " + packageName);
19078            }
19079            if (pkg.applicationInfo.uid != Binder.getCallingUid()
19080                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
19081                throw new SecurityException("May not access signing KeySet of other apps.");
19082            }
19083            KeySetManagerService ksms = mSettings.mKeySetManagerService;
19084            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
19085        }
19086    }
19087
19088    @Override
19089    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
19090        if (packageName == null || ks == null) {
19091            return false;
19092        }
19093        synchronized(mPackages) {
19094            final PackageParser.Package pkg = mPackages.get(packageName);
19095            if (pkg == null) {
19096                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
19097                throw new IllegalArgumentException("Unknown package: " + packageName);
19098            }
19099            IBinder ksh = ks.getToken();
19100            if (ksh instanceof KeySetHandle) {
19101                KeySetManagerService ksms = mSettings.mKeySetManagerService;
19102                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
19103            }
19104            return false;
19105        }
19106    }
19107
19108    @Override
19109    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
19110        if (packageName == null || ks == null) {
19111            return false;
19112        }
19113        synchronized(mPackages) {
19114            final PackageParser.Package pkg = mPackages.get(packageName);
19115            if (pkg == null) {
19116                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
19117                throw new IllegalArgumentException("Unknown package: " + packageName);
19118            }
19119            IBinder ksh = ks.getToken();
19120            if (ksh instanceof KeySetHandle) {
19121                KeySetManagerService ksms = mSettings.mKeySetManagerService;
19122                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
19123            }
19124            return false;
19125        }
19126    }
19127
19128    private void deletePackageIfUnusedLPr(final String packageName) {
19129        PackageSetting ps = mSettings.mPackages.get(packageName);
19130        if (ps == null) {
19131            return;
19132        }
19133        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
19134            // TODO Implement atomic delete if package is unused
19135            // It is currently possible that the package will be deleted even if it is installed
19136            // after this method returns.
19137            mHandler.post(new Runnable() {
19138                public void run() {
19139                    deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS);
19140                }
19141            });
19142        }
19143    }
19144
19145    /**
19146     * Check and throw if the given before/after packages would be considered a
19147     * downgrade.
19148     */
19149    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
19150            throws PackageManagerException {
19151        if (after.versionCode < before.mVersionCode) {
19152            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
19153                    "Update version code " + after.versionCode + " is older than current "
19154                    + before.mVersionCode);
19155        } else if (after.versionCode == before.mVersionCode) {
19156            if (after.baseRevisionCode < before.baseRevisionCode) {
19157                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
19158                        "Update base revision code " + after.baseRevisionCode
19159                        + " is older than current " + before.baseRevisionCode);
19160            }
19161
19162            if (!ArrayUtils.isEmpty(after.splitNames)) {
19163                for (int i = 0; i < after.splitNames.length; i++) {
19164                    final String splitName = after.splitNames[i];
19165                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
19166                    if (j != -1) {
19167                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
19168                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
19169                                    "Update split " + splitName + " revision code "
19170                                    + after.splitRevisionCodes[i] + " is older than current "
19171                                    + before.splitRevisionCodes[j]);
19172                        }
19173                    }
19174                }
19175            }
19176        }
19177    }
19178
19179    private static class MoveCallbacks extends Handler {
19180        private static final int MSG_CREATED = 1;
19181        private static final int MSG_STATUS_CHANGED = 2;
19182
19183        private final RemoteCallbackList<IPackageMoveObserver>
19184                mCallbacks = new RemoteCallbackList<>();
19185
19186        private final SparseIntArray mLastStatus = new SparseIntArray();
19187
19188        public MoveCallbacks(Looper looper) {
19189            super(looper);
19190        }
19191
19192        public void register(IPackageMoveObserver callback) {
19193            mCallbacks.register(callback);
19194        }
19195
19196        public void unregister(IPackageMoveObserver callback) {
19197            mCallbacks.unregister(callback);
19198        }
19199
19200        @Override
19201        public void handleMessage(Message msg) {
19202            final SomeArgs args = (SomeArgs) msg.obj;
19203            final int n = mCallbacks.beginBroadcast();
19204            for (int i = 0; i < n; i++) {
19205                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
19206                try {
19207                    invokeCallback(callback, msg.what, args);
19208                } catch (RemoteException ignored) {
19209                }
19210            }
19211            mCallbacks.finishBroadcast();
19212            args.recycle();
19213        }
19214
19215        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
19216                throws RemoteException {
19217            switch (what) {
19218                case MSG_CREATED: {
19219                    callback.onCreated(args.argi1, (Bundle) args.arg2);
19220                    break;
19221                }
19222                case MSG_STATUS_CHANGED: {
19223                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
19224                    break;
19225                }
19226            }
19227        }
19228
19229        private void notifyCreated(int moveId, Bundle extras) {
19230            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
19231
19232            final SomeArgs args = SomeArgs.obtain();
19233            args.argi1 = moveId;
19234            args.arg2 = extras;
19235            obtainMessage(MSG_CREATED, args).sendToTarget();
19236        }
19237
19238        private void notifyStatusChanged(int moveId, int status) {
19239            notifyStatusChanged(moveId, status, -1);
19240        }
19241
19242        private void notifyStatusChanged(int moveId, int status, long estMillis) {
19243            Slog.v(TAG, "Move " + moveId + " status " + status);
19244
19245            final SomeArgs args = SomeArgs.obtain();
19246            args.argi1 = moveId;
19247            args.argi2 = status;
19248            args.arg3 = estMillis;
19249            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
19250
19251            synchronized (mLastStatus) {
19252                mLastStatus.put(moveId, status);
19253            }
19254        }
19255    }
19256
19257    private final static class OnPermissionChangeListeners extends Handler {
19258        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
19259
19260        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
19261                new RemoteCallbackList<>();
19262
19263        public OnPermissionChangeListeners(Looper looper) {
19264            super(looper);
19265        }
19266
19267        @Override
19268        public void handleMessage(Message msg) {
19269            switch (msg.what) {
19270                case MSG_ON_PERMISSIONS_CHANGED: {
19271                    final int uid = msg.arg1;
19272                    handleOnPermissionsChanged(uid);
19273                } break;
19274            }
19275        }
19276
19277        public void addListenerLocked(IOnPermissionsChangeListener listener) {
19278            mPermissionListeners.register(listener);
19279
19280        }
19281
19282        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
19283            mPermissionListeners.unregister(listener);
19284        }
19285
19286        public void onPermissionsChanged(int uid) {
19287            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
19288                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
19289            }
19290        }
19291
19292        private void handleOnPermissionsChanged(int uid) {
19293            final int count = mPermissionListeners.beginBroadcast();
19294            try {
19295                for (int i = 0; i < count; i++) {
19296                    IOnPermissionsChangeListener callback = mPermissionListeners
19297                            .getBroadcastItem(i);
19298                    try {
19299                        callback.onPermissionsChanged(uid);
19300                    } catch (RemoteException e) {
19301                        Log.e(TAG, "Permission listener is dead", e);
19302                    }
19303                }
19304            } finally {
19305                mPermissionListeners.finishBroadcast();
19306            }
19307        }
19308    }
19309
19310    private class PackageManagerInternalImpl extends PackageManagerInternal {
19311        @Override
19312        public void setLocationPackagesProvider(PackagesProvider provider) {
19313            synchronized (mPackages) {
19314                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
19315            }
19316        }
19317
19318        @Override
19319        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
19320            synchronized (mPackages) {
19321                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
19322            }
19323        }
19324
19325        @Override
19326        public void setSmsAppPackagesProvider(PackagesProvider provider) {
19327            synchronized (mPackages) {
19328                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
19329            }
19330        }
19331
19332        @Override
19333        public void setDialerAppPackagesProvider(PackagesProvider provider) {
19334            synchronized (mPackages) {
19335                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
19336            }
19337        }
19338
19339        @Override
19340        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
19341            synchronized (mPackages) {
19342                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
19343            }
19344        }
19345
19346        @Override
19347        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
19348            synchronized (mPackages) {
19349                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
19350            }
19351        }
19352
19353        @Override
19354        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
19355            synchronized (mPackages) {
19356                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
19357                        packageName, userId);
19358            }
19359        }
19360
19361        @Override
19362        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
19363            synchronized (mPackages) {
19364                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
19365                        packageName, userId);
19366            }
19367        }
19368
19369        @Override
19370        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
19371            synchronized (mPackages) {
19372                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
19373                        packageName, userId);
19374            }
19375        }
19376
19377        @Override
19378        public void setKeepUninstalledPackages(final List<String> packageList) {
19379            Preconditions.checkNotNull(packageList);
19380            List<String> removedFromList = null;
19381            synchronized (mPackages) {
19382                if (mKeepUninstalledPackages != null) {
19383                    final int packagesCount = mKeepUninstalledPackages.size();
19384                    for (int i = 0; i < packagesCount; i++) {
19385                        String oldPackage = mKeepUninstalledPackages.get(i);
19386                        if (packageList != null && packageList.contains(oldPackage)) {
19387                            continue;
19388                        }
19389                        if (removedFromList == null) {
19390                            removedFromList = new ArrayList<>();
19391                        }
19392                        removedFromList.add(oldPackage);
19393                    }
19394                }
19395                mKeepUninstalledPackages = new ArrayList<>(packageList);
19396                if (removedFromList != null) {
19397                    final int removedCount = removedFromList.size();
19398                    for (int i = 0; i < removedCount; i++) {
19399                        deletePackageIfUnusedLPr(removedFromList.get(i));
19400                    }
19401                }
19402            }
19403        }
19404
19405        @Override
19406        public boolean isPermissionsReviewRequired(String packageName, int userId) {
19407            synchronized (mPackages) {
19408                // If we do not support permission review, done.
19409                if (!Build.PERMISSIONS_REVIEW_REQUIRED) {
19410                    return false;
19411                }
19412
19413                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
19414                if (packageSetting == null) {
19415                    return false;
19416                }
19417
19418                // Permission review applies only to apps not supporting the new permission model.
19419                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
19420                    return false;
19421                }
19422
19423                // Legacy apps have the permission and get user consent on launch.
19424                PermissionsState permissionsState = packageSetting.getPermissionsState();
19425                return permissionsState.isPermissionReviewRequired(userId);
19426            }
19427        }
19428
19429        @Override
19430        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
19431            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
19432        }
19433
19434        @Override
19435        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19436                int userId) {
19437            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
19438        }
19439    }
19440
19441    @Override
19442    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
19443        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
19444        synchronized (mPackages) {
19445            final long identity = Binder.clearCallingIdentity();
19446            try {
19447                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
19448                        packageNames, userId);
19449            } finally {
19450                Binder.restoreCallingIdentity(identity);
19451            }
19452        }
19453    }
19454
19455    private static void enforceSystemOrPhoneCaller(String tag) {
19456        int callingUid = Binder.getCallingUid();
19457        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
19458            throw new SecurityException(
19459                    "Cannot call " + tag + " from UID " + callingUid);
19460        }
19461    }
19462
19463    boolean isHistoricalPackageUsageAvailable() {
19464        return mPackageUsage.isHistoricalPackageUsageAvailable();
19465    }
19466
19467    /**
19468     * Return a <b>copy</b> of the collection of packages known to the package manager.
19469     * @return A copy of the values of mPackages.
19470     */
19471    Collection<PackageParser.Package> getPackages() {
19472        synchronized (mPackages) {
19473            return new ArrayList<>(mPackages.values());
19474        }
19475    }
19476
19477    /**
19478     * Logs process start information (including base APK hash) to the security log.
19479     * @hide
19480     */
19481    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
19482            String apkFile, int pid) {
19483        if (!SecurityLog.isLoggingEnabled()) {
19484            return;
19485        }
19486        Bundle data = new Bundle();
19487        data.putLong("startTimestamp", System.currentTimeMillis());
19488        data.putString("processName", processName);
19489        data.putInt("uid", uid);
19490        data.putString("seinfo", seinfo);
19491        data.putString("apkFile", apkFile);
19492        data.putInt("pid", pid);
19493        Message msg = mProcessLoggingHandler.obtainMessage(
19494                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
19495        msg.setData(data);
19496        mProcessLoggingHandler.sendMessage(msg);
19497    }
19498}
19499