PackageManagerService.java revision 13c0104619acafbb3246362e4018256303ddd87a
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.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
22import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23import static android.Manifest.permission.REQUEST_INSTALL_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
54import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
56import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
57import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
58import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65import static android.content.pm.PackageManager.MATCH_ALL;
66import static android.content.pm.PackageManager.MATCH_ANY_USER;
67import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
80import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
81import static android.content.pm.PackageManager.PERMISSION_DENIED;
82import static android.content.pm.PackageManager.PERMISSION_GRANTED;
83import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
84import static android.content.pm.PackageParser.isApkFile;
85import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
86import static android.system.OsConstants.O_CREAT;
87import static android.system.OsConstants.O_RDWR;
88import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
89import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
90import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
91import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
92import static com.android.internal.util.ArrayUtils.appendInt;
93import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
94import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
95import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
96import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
97import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
98import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
99import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
100import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
101import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
103
104import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
105
106import android.Manifest;
107import android.annotation.NonNull;
108import android.annotation.Nullable;
109import android.app.ActivityManager;
110import android.app.AppOpsManager;
111import android.app.IActivityManager;
112import android.app.ResourcesManager;
113import android.app.admin.IDevicePolicyManager;
114import android.app.admin.SecurityLog;
115import android.app.backup.IBackupManager;
116import android.content.BroadcastReceiver;
117import android.content.ComponentName;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.IIntentReceiver;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.IntentSender.SendIntentException;
125import android.content.ServiceConnection;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.AppsQueryHelper;
129import android.content.pm.AuxiliaryResolveInfo;
130import android.content.pm.ChangedPackages;
131import android.content.pm.FallbackCategoryProvider;
132import android.content.pm.FeatureInfo;
133import android.content.pm.IDexModuleRegisterCallback;
134import android.content.pm.IOnPermissionsChangeListener;
135import android.content.pm.IPackageDataObserver;
136import android.content.pm.IPackageDeleteObserver;
137import android.content.pm.IPackageDeleteObserver2;
138import android.content.pm.IPackageInstallObserver2;
139import android.content.pm.IPackageInstaller;
140import android.content.pm.IPackageManager;
141import android.content.pm.IPackageMoveObserver;
142import android.content.pm.IPackageStatsObserver;
143import android.content.pm.InstantAppInfo;
144import android.content.pm.InstantAppRequest;
145import android.content.pm.InstantAppResolveInfo;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.IntentFilterVerificationInfo;
148import android.content.pm.KeySet;
149import android.content.pm.PackageCleanItem;
150import android.content.pm.PackageInfo;
151import android.content.pm.PackageInfoLite;
152import android.content.pm.PackageInstaller;
153import android.content.pm.PackageManager;
154import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
155import android.content.pm.PackageManagerInternal;
156import android.content.pm.PackageParser;
157import android.content.pm.PackageParser.ActivityIntentInfo;
158import android.content.pm.PackageParser.PackageLite;
159import android.content.pm.PackageParser.PackageParserException;
160import android.content.pm.PackageStats;
161import android.content.pm.PackageUserState;
162import android.content.pm.ParceledListSlice;
163import android.content.pm.PermissionGroupInfo;
164import android.content.pm.PermissionInfo;
165import android.content.pm.ProviderInfo;
166import android.content.pm.ResolveInfo;
167import android.content.pm.ServiceInfo;
168import android.content.pm.SharedLibraryInfo;
169import android.content.pm.Signature;
170import android.content.pm.UserInfo;
171import android.content.pm.VerifierDeviceIdentity;
172import android.content.pm.VerifierInfo;
173import android.content.pm.VersionedPackage;
174import android.content.res.Resources;
175import android.database.ContentObserver;
176import android.graphics.Bitmap;
177import android.hardware.display.DisplayManager;
178import android.net.Uri;
179import android.os.Binder;
180import android.os.Build;
181import android.os.Bundle;
182import android.os.Debug;
183import android.os.Environment;
184import android.os.Environment.UserEnvironment;
185import android.os.FileUtils;
186import android.os.Handler;
187import android.os.IBinder;
188import android.os.Looper;
189import android.os.Message;
190import android.os.Parcel;
191import android.os.ParcelFileDescriptor;
192import android.os.PatternMatcher;
193import android.os.Process;
194import android.os.RemoteCallbackList;
195import android.os.RemoteException;
196import android.os.ResultReceiver;
197import android.os.SELinux;
198import android.os.ServiceManager;
199import android.os.ShellCallback;
200import android.os.SystemClock;
201import android.os.SystemProperties;
202import android.os.Trace;
203import android.os.UserHandle;
204import android.os.UserManager;
205import android.os.UserManagerInternal;
206import android.os.storage.IStorageManager;
207import android.os.storage.StorageEventListener;
208import android.os.storage.StorageManager;
209import android.os.storage.StorageManagerInternal;
210import android.os.storage.VolumeInfo;
211import android.os.storage.VolumeRecord;
212import android.provider.Settings.Global;
213import android.provider.Settings.Secure;
214import android.security.KeyStore;
215import android.security.SystemKeyStore;
216import android.service.pm.PackageServiceDumpProto;
217import android.system.ErrnoException;
218import android.system.Os;
219import android.text.TextUtils;
220import android.text.format.DateUtils;
221import android.util.ArrayMap;
222import android.util.ArraySet;
223import android.util.Base64;
224import android.util.BootTimingsTraceLog;
225import android.util.DisplayMetrics;
226import android.util.EventLog;
227import android.util.ExceptionUtils;
228import android.util.Log;
229import android.util.LogPrinter;
230import android.util.MathUtils;
231import android.util.PackageUtils;
232import android.util.Pair;
233import android.util.PrintStreamPrinter;
234import android.util.Slog;
235import android.util.SparseArray;
236import android.util.SparseBooleanArray;
237import android.util.SparseIntArray;
238import android.util.Xml;
239import android.util.jar.StrictJarFile;
240import android.util.proto.ProtoOutputStream;
241import android.view.Display;
242
243import com.android.internal.R;
244import com.android.internal.annotations.GuardedBy;
245import com.android.internal.app.IMediaContainerService;
246import com.android.internal.app.ResolverActivity;
247import com.android.internal.content.NativeLibraryHelper;
248import com.android.internal.content.PackageHelper;
249import com.android.internal.logging.MetricsLogger;
250import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
251import com.android.internal.os.IParcelFileDescriptorFactory;
252import com.android.internal.os.RoSystemProperties;
253import com.android.internal.os.SomeArgs;
254import com.android.internal.os.Zygote;
255import com.android.internal.telephony.CarrierAppUtils;
256import com.android.internal.util.ArrayUtils;
257import com.android.internal.util.ConcurrentUtils;
258import com.android.internal.util.DumpUtils;
259import com.android.internal.util.FastPrintWriter;
260import com.android.internal.util.FastXmlSerializer;
261import com.android.internal.util.IndentingPrintWriter;
262import com.android.internal.util.Preconditions;
263import com.android.internal.util.XmlUtils;
264import com.android.server.AttributeCache;
265import com.android.server.DeviceIdleController;
266import com.android.server.EventLogTags;
267import com.android.server.FgThread;
268import com.android.server.IntentResolver;
269import com.android.server.LocalServices;
270import com.android.server.LockGuard;
271import com.android.server.ServiceThread;
272import com.android.server.SystemConfig;
273import com.android.server.SystemServerInitThreadPool;
274import com.android.server.Watchdog;
275import com.android.server.net.NetworkPolicyManagerInternal;
276import com.android.server.pm.Installer.InstallerException;
277import com.android.server.pm.PermissionsState.PermissionState;
278import com.android.server.pm.Settings.DatabaseVersion;
279import com.android.server.pm.Settings.VersionInfo;
280import com.android.server.pm.dex.DexManager;
281import com.android.server.storage.DeviceStorageMonitorInternal;
282
283import dalvik.system.CloseGuard;
284import dalvik.system.DexFile;
285import dalvik.system.VMRuntime;
286
287import libcore.io.IoUtils;
288import libcore.util.EmptyArray;
289
290import org.xmlpull.v1.XmlPullParser;
291import org.xmlpull.v1.XmlPullParserException;
292import org.xmlpull.v1.XmlSerializer;
293
294import java.io.BufferedOutputStream;
295import java.io.BufferedReader;
296import java.io.ByteArrayInputStream;
297import java.io.ByteArrayOutputStream;
298import java.io.File;
299import java.io.FileDescriptor;
300import java.io.FileInputStream;
301import java.io.FileOutputStream;
302import java.io.FileReader;
303import java.io.FilenameFilter;
304import java.io.IOException;
305import java.io.PrintWriter;
306import java.nio.charset.StandardCharsets;
307import java.security.DigestInputStream;
308import java.security.MessageDigest;
309import java.security.NoSuchAlgorithmException;
310import java.security.PublicKey;
311import java.security.SecureRandom;
312import java.security.cert.Certificate;
313import java.security.cert.CertificateEncodingException;
314import java.security.cert.CertificateException;
315import java.text.SimpleDateFormat;
316import java.util.ArrayList;
317import java.util.Arrays;
318import java.util.Collection;
319import java.util.Collections;
320import java.util.Comparator;
321import java.util.Date;
322import java.util.HashMap;
323import java.util.HashSet;
324import java.util.Iterator;
325import java.util.List;
326import java.util.Map;
327import java.util.Objects;
328import java.util.Set;
329import java.util.concurrent.CountDownLatch;
330import java.util.concurrent.Future;
331import java.util.concurrent.TimeUnit;
332import java.util.concurrent.atomic.AtomicBoolean;
333import java.util.concurrent.atomic.AtomicInteger;
334
335/**
336 * Keep track of all those APKs everywhere.
337 * <p>
338 * Internally there are two important locks:
339 * <ul>
340 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
341 * and other related state. It is a fine-grained lock that should only be held
342 * momentarily, as it's one of the most contended locks in the system.
343 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
344 * operations typically involve heavy lifting of application data on disk. Since
345 * {@code installd} is single-threaded, and it's operations can often be slow,
346 * this lock should never be acquired while already holding {@link #mPackages}.
347 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
348 * holding {@link #mInstallLock}.
349 * </ul>
350 * Many internal methods rely on the caller to hold the appropriate locks, and
351 * this contract is expressed through method name suffixes:
352 * <ul>
353 * <li>fooLI(): the caller must hold {@link #mInstallLock}
354 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
355 * being modified must be frozen
356 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
357 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
358 * </ul>
359 * <p>
360 * Because this class is very central to the platform's security; please run all
361 * CTS and unit tests whenever making modifications:
362 *
363 * <pre>
364 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
365 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
366 * </pre>
367 */
368public class PackageManagerService extends IPackageManager.Stub
369        implements PackageSender {
370    static final String TAG = "PackageManager";
371    static final boolean DEBUG_SETTINGS = false;
372    static final boolean DEBUG_PREFERRED = false;
373    static final boolean DEBUG_UPGRADE = false;
374    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
375    private static final boolean DEBUG_BACKUP = false;
376    private static final boolean DEBUG_INSTALL = false;
377    private static final boolean DEBUG_REMOVE = false;
378    private static final boolean DEBUG_BROADCASTS = false;
379    private static final boolean DEBUG_SHOW_INFO = false;
380    private static final boolean DEBUG_PACKAGE_INFO = false;
381    private static final boolean DEBUG_INTENT_MATCHING = false;
382    private static final boolean DEBUG_PACKAGE_SCANNING = false;
383    private static final boolean DEBUG_VERIFY = false;
384    private static final boolean DEBUG_FILTERS = false;
385    private static final boolean DEBUG_PERMISSIONS = false;
386    private static final boolean DEBUG_SHARED_LIBRARIES = false;
387
388    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
389    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
390    // user, but by default initialize to this.
391    public static final boolean DEBUG_DEXOPT = false;
392
393    private static final boolean DEBUG_ABI_SELECTION = false;
394    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
395    private static final boolean DEBUG_TRIAGED_MISSING = false;
396    private static final boolean DEBUG_APP_DATA = false;
397
398    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
399    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
400
401    private static final boolean HIDE_EPHEMERAL_APIS = false;
402
403    private static final boolean ENABLE_FREE_CACHE_V2 =
404            SystemProperties.getBoolean("fw.free_cache_v2", true);
405
406    private static final int RADIO_UID = Process.PHONE_UID;
407    private static final int LOG_UID = Process.LOG_UID;
408    private static final int NFC_UID = Process.NFC_UID;
409    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
410    private static final int SHELL_UID = Process.SHELL_UID;
411
412    // Cap the size of permission trees that 3rd party apps can define
413    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
414
415    // Suffix used during package installation when copying/moving
416    // package apks to install directory.
417    private static final String INSTALL_PACKAGE_SUFFIX = "-";
418
419    static final int SCAN_NO_DEX = 1<<1;
420    static final int SCAN_FORCE_DEX = 1<<2;
421    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
422    static final int SCAN_NEW_INSTALL = 1<<4;
423    static final int SCAN_UPDATE_TIME = 1<<5;
424    static final int SCAN_BOOTING = 1<<6;
425    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
426    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
427    static final int SCAN_REPLACING = 1<<9;
428    static final int SCAN_REQUIRE_KNOWN = 1<<10;
429    static final int SCAN_MOVE = 1<<11;
430    static final int SCAN_INITIAL = 1<<12;
431    static final int SCAN_CHECK_ONLY = 1<<13;
432    static final int SCAN_DONT_KILL_APP = 1<<14;
433    static final int SCAN_IGNORE_FROZEN = 1<<15;
434    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
435    static final int SCAN_AS_INSTANT_APP = 1<<17;
436    static final int SCAN_AS_FULL_APP = 1<<18;
437    /** Should not be with the scan flags */
438    static final int FLAGS_REMOVE_CHATTY = 1<<31;
439
440    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
441
442    private static final int[] EMPTY_INT_ARRAY = new int[0];
443
444    /**
445     * Timeout (in milliseconds) after which the watchdog should declare that
446     * our handler thread is wedged.  The usual default for such things is one
447     * minute but we sometimes do very lengthy I/O operations on this thread,
448     * such as installing multi-gigabyte applications, so ours needs to be longer.
449     */
450    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
451
452    /**
453     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
454     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
455     * settings entry if available, otherwise we use the hardcoded default.  If it's been
456     * more than this long since the last fstrim, we force one during the boot sequence.
457     *
458     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
459     * one gets run at the next available charging+idle time.  This final mandatory
460     * no-fstrim check kicks in only of the other scheduling criteria is never met.
461     */
462    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
463
464    /**
465     * Whether verification is enabled by default.
466     */
467    private static final boolean DEFAULT_VERIFY_ENABLE = true;
468
469    /**
470     * The default maximum time to wait for the verification agent to return in
471     * milliseconds.
472     */
473    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
474
475    /**
476     * The default response for package verification timeout.
477     *
478     * This can be either PackageManager.VERIFICATION_ALLOW or
479     * PackageManager.VERIFICATION_REJECT.
480     */
481    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
482
483    static final String PLATFORM_PACKAGE_NAME = "android";
484
485    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
486
487    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
488            DEFAULT_CONTAINER_PACKAGE,
489            "com.android.defcontainer.DefaultContainerService");
490
491    private static final String KILL_APP_REASON_GIDS_CHANGED =
492            "permission grant or revoke changed gids";
493
494    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
495            "permissions revoked";
496
497    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
498
499    private static final String PACKAGE_SCHEME = "package";
500
501    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
502
503    /** Permission grant: not grant the permission. */
504    private static final int GRANT_DENIED = 1;
505
506    /** Permission grant: grant the permission as an install permission. */
507    private static final int GRANT_INSTALL = 2;
508
509    /** Permission grant: grant the permission as a runtime one. */
510    private static final int GRANT_RUNTIME = 3;
511
512    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
513    private static final int GRANT_UPGRADE = 4;
514
515    /** Canonical intent used to identify what counts as a "web browser" app */
516    private static final Intent sBrowserIntent;
517    static {
518        sBrowserIntent = new Intent();
519        sBrowserIntent.setAction(Intent.ACTION_VIEW);
520        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
521        sBrowserIntent.setData(Uri.parse("http:"));
522    }
523
524    /**
525     * The set of all protected actions [i.e. those actions for which a high priority
526     * intent filter is disallowed].
527     */
528    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
529    static {
530        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
531        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
532        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
533        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
534    }
535
536    // Compilation reasons.
537    public static final int REASON_FIRST_BOOT = 0;
538    public static final int REASON_BOOT = 1;
539    public static final int REASON_INSTALL = 2;
540    public static final int REASON_BACKGROUND_DEXOPT = 3;
541    public static final int REASON_AB_OTA = 4;
542
543    public static final int REASON_LAST = REASON_AB_OTA;
544
545    /** All dangerous permission names in the same order as the events in MetricsEvent */
546    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
547            Manifest.permission.READ_CALENDAR,
548            Manifest.permission.WRITE_CALENDAR,
549            Manifest.permission.CAMERA,
550            Manifest.permission.READ_CONTACTS,
551            Manifest.permission.WRITE_CONTACTS,
552            Manifest.permission.GET_ACCOUNTS,
553            Manifest.permission.ACCESS_FINE_LOCATION,
554            Manifest.permission.ACCESS_COARSE_LOCATION,
555            Manifest.permission.RECORD_AUDIO,
556            Manifest.permission.READ_PHONE_STATE,
557            Manifest.permission.CALL_PHONE,
558            Manifest.permission.READ_CALL_LOG,
559            Manifest.permission.WRITE_CALL_LOG,
560            Manifest.permission.ADD_VOICEMAIL,
561            Manifest.permission.USE_SIP,
562            Manifest.permission.PROCESS_OUTGOING_CALLS,
563            Manifest.permission.READ_CELL_BROADCASTS,
564            Manifest.permission.BODY_SENSORS,
565            Manifest.permission.SEND_SMS,
566            Manifest.permission.RECEIVE_SMS,
567            Manifest.permission.READ_SMS,
568            Manifest.permission.RECEIVE_WAP_PUSH,
569            Manifest.permission.RECEIVE_MMS,
570            Manifest.permission.READ_EXTERNAL_STORAGE,
571            Manifest.permission.WRITE_EXTERNAL_STORAGE,
572            Manifest.permission.READ_PHONE_NUMBERS,
573            Manifest.permission.ANSWER_PHONE_CALLS);
574
575
576    /**
577     * Version number for the package parser cache. Increment this whenever the format or
578     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
579     */
580    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
581
582    /**
583     * Whether the package parser cache is enabled.
584     */
585    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
586
587    final ServiceThread mHandlerThread;
588
589    final PackageHandler mHandler;
590
591    private final ProcessLoggingHandler mProcessLoggingHandler;
592
593    /**
594     * Messages for {@link #mHandler} that need to wait for system ready before
595     * being dispatched.
596     */
597    private ArrayList<Message> mPostSystemReadyMessages;
598
599    final int mSdkVersion = Build.VERSION.SDK_INT;
600
601    final Context mContext;
602    final boolean mFactoryTest;
603    final boolean mOnlyCore;
604    final DisplayMetrics mMetrics;
605    final int mDefParseFlags;
606    final String[] mSeparateProcesses;
607    final boolean mIsUpgrade;
608    final boolean mIsPreNUpgrade;
609    final boolean mIsPreNMR1Upgrade;
610
611    // Have we told the Activity Manager to whitelist the default container service by uid yet?
612    @GuardedBy("mPackages")
613    boolean mDefaultContainerWhitelisted = false;
614
615    @GuardedBy("mPackages")
616    private boolean mDexOptDialogShown;
617
618    /** The location for ASEC container files on internal storage. */
619    final String mAsecInternalPath;
620
621    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
622    // LOCK HELD.  Can be called with mInstallLock held.
623    @GuardedBy("mInstallLock")
624    final Installer mInstaller;
625
626    /** Directory where installed third-party apps stored */
627    final File mAppInstallDir;
628
629    /**
630     * Directory to which applications installed internally have their
631     * 32 bit native libraries copied.
632     */
633    private File mAppLib32InstallDir;
634
635    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
636    // apps.
637    final File mDrmAppPrivateInstallDir;
638
639    // ----------------------------------------------------------------
640
641    // Lock for state used when installing and doing other long running
642    // operations.  Methods that must be called with this lock held have
643    // the suffix "LI".
644    final Object mInstallLock = new Object();
645
646    // ----------------------------------------------------------------
647
648    // Keys are String (package name), values are Package.  This also serves
649    // as the lock for the global state.  Methods that must be called with
650    // this lock held have the prefix "LP".
651    @GuardedBy("mPackages")
652    final ArrayMap<String, PackageParser.Package> mPackages =
653            new ArrayMap<String, PackageParser.Package>();
654
655    final ArrayMap<String, Set<String>> mKnownCodebase =
656            new ArrayMap<String, Set<String>>();
657
658    // Keys are isolated uids and values are the uid of the application
659    // that created the isolated proccess.
660    @GuardedBy("mPackages")
661    final SparseIntArray mIsolatedOwners = new SparseIntArray();
662
663    // List of APK paths to load for each user and package. This data is never
664    // persisted by the package manager. Instead, the overlay manager will
665    // ensure the data is up-to-date in runtime.
666    @GuardedBy("mPackages")
667    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
668        new SparseArray<ArrayMap<String, ArrayList<String>>>();
669
670    /**
671     * Tracks new system packages [received in an OTA] that we expect to
672     * find updated user-installed versions. Keys are package name, values
673     * are package location.
674     */
675    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
676    /**
677     * Tracks high priority intent filters for protected actions. During boot, certain
678     * filter actions are protected and should never be allowed to have a high priority
679     * intent filter for them. However, there is one, and only one exception -- the
680     * setup wizard. It must be able to define a high priority intent filter for these
681     * actions to ensure there are no escapes from the wizard. We need to delay processing
682     * of these during boot as we need to look at all of the system packages in order
683     * to know which component is the setup wizard.
684     */
685    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
686    /**
687     * Whether or not processing protected filters should be deferred.
688     */
689    private boolean mDeferProtectedFilters = true;
690
691    /**
692     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
693     */
694    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
695    /**
696     * Whether or not system app permissions should be promoted from install to runtime.
697     */
698    boolean mPromoteSystemApps;
699
700    @GuardedBy("mPackages")
701    final Settings mSettings;
702
703    /**
704     * Set of package names that are currently "frozen", which means active
705     * surgery is being done on the code/data for that package. The platform
706     * will refuse to launch frozen packages to avoid race conditions.
707     *
708     * @see PackageFreezer
709     */
710    @GuardedBy("mPackages")
711    final ArraySet<String> mFrozenPackages = new ArraySet<>();
712
713    final ProtectedPackages mProtectedPackages;
714
715    boolean mFirstBoot;
716
717    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
718
719    // System configuration read by SystemConfig.
720    final int[] mGlobalGids;
721    final SparseArray<ArraySet<String>> mSystemPermissions;
722    @GuardedBy("mAvailableFeatures")
723    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
724
725    // If mac_permissions.xml was found for seinfo labeling.
726    boolean mFoundPolicyFile;
727
728    private final InstantAppRegistry mInstantAppRegistry;
729
730    @GuardedBy("mPackages")
731    int mChangedPackagesSequenceNumber;
732    /**
733     * List of changed [installed, removed or updated] packages.
734     * mapping from user id -> sequence number -> package name
735     */
736    @GuardedBy("mPackages")
737    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
738    /**
739     * The sequence number of the last change to a package.
740     * mapping from user id -> package name -> sequence number
741     */
742    @GuardedBy("mPackages")
743    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
744
745    class PackageParserCallback implements PackageParser.Callback {
746        @Override public final boolean hasFeature(String feature) {
747            return PackageManagerService.this.hasSystemFeature(feature, 0);
748        }
749
750        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
751                Collection<PackageParser.Package> allPackages, String targetPackageName) {
752            List<PackageParser.Package> overlayPackages = null;
753            for (PackageParser.Package p : allPackages) {
754                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
755                    if (overlayPackages == null) {
756                        overlayPackages = new ArrayList<PackageParser.Package>();
757                    }
758                    overlayPackages.add(p);
759                }
760            }
761            if (overlayPackages != null) {
762                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
763                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
764                        return p1.mOverlayPriority - p2.mOverlayPriority;
765                    }
766                };
767                Collections.sort(overlayPackages, cmp);
768            }
769            return overlayPackages;
770        }
771
772        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
773                String targetPackageName, String targetPath) {
774            if ("android".equals(targetPackageName)) {
775                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
776                // native AssetManager.
777                return null;
778            }
779            List<PackageParser.Package> overlayPackages =
780                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
781            if (overlayPackages == null || overlayPackages.isEmpty()) {
782                return null;
783            }
784            List<String> overlayPathList = null;
785            for (PackageParser.Package overlayPackage : overlayPackages) {
786                if (targetPath == null) {
787                    if (overlayPathList == null) {
788                        overlayPathList = new ArrayList<String>();
789                    }
790                    overlayPathList.add(overlayPackage.baseCodePath);
791                    continue;
792                }
793
794                try {
795                    // Creates idmaps for system to parse correctly the Android manifest of the
796                    // target package.
797                    //
798                    // OverlayManagerService will update each of them with a correct gid from its
799                    // target package app id.
800                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
801                            UserHandle.getSharedAppGid(
802                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
803                    if (overlayPathList == null) {
804                        overlayPathList = new ArrayList<String>();
805                    }
806                    overlayPathList.add(overlayPackage.baseCodePath);
807                } catch (InstallerException e) {
808                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
809                            overlayPackage.baseCodePath);
810                }
811            }
812            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
813        }
814
815        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
816            synchronized (mPackages) {
817                return getStaticOverlayPathsLocked(
818                        mPackages.values(), targetPackageName, targetPath);
819            }
820        }
821
822        @Override public final String[] getOverlayApks(String targetPackageName) {
823            return getStaticOverlayPaths(targetPackageName, null);
824        }
825
826        @Override public final String[] getOverlayPaths(String targetPackageName,
827                String targetPath) {
828            return getStaticOverlayPaths(targetPackageName, targetPath);
829        }
830    };
831
832    class ParallelPackageParserCallback extends PackageParserCallback {
833        List<PackageParser.Package> mOverlayPackages = null;
834
835        void findStaticOverlayPackages() {
836            synchronized (mPackages) {
837                for (PackageParser.Package p : mPackages.values()) {
838                    if (p.mIsStaticOverlay) {
839                        if (mOverlayPackages == null) {
840                            mOverlayPackages = new ArrayList<PackageParser.Package>();
841                        }
842                        mOverlayPackages.add(p);
843                    }
844                }
845            }
846        }
847
848        @Override
849        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
850            // We can trust mOverlayPackages without holding mPackages because package uninstall
851            // can't happen while running parallel parsing.
852            // Moreover holding mPackages on each parsing thread causes dead-lock.
853            return mOverlayPackages == null ? null :
854                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
855        }
856    }
857
858    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
859    final ParallelPackageParserCallback mParallelPackageParserCallback =
860            new ParallelPackageParserCallback();
861
862    public static final class SharedLibraryEntry {
863        public final String path;
864        public final String apk;
865        public final SharedLibraryInfo info;
866
867        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
868                String declaringPackageName, int declaringPackageVersionCode) {
869            path = _path;
870            apk = _apk;
871            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
872                    declaringPackageName, declaringPackageVersionCode), null);
873        }
874    }
875
876    // Currently known shared libraries.
877    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
878    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
879            new ArrayMap<>();
880
881    // All available activities, for your resolving pleasure.
882    final ActivityIntentResolver mActivities =
883            new ActivityIntentResolver();
884
885    // All available receivers, for your resolving pleasure.
886    final ActivityIntentResolver mReceivers =
887            new ActivityIntentResolver();
888
889    // All available services, for your resolving pleasure.
890    final ServiceIntentResolver mServices = new ServiceIntentResolver();
891
892    // All available providers, for your resolving pleasure.
893    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
894
895    // Mapping from provider base names (first directory in content URI codePath)
896    // to the provider information.
897    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
898            new ArrayMap<String, PackageParser.Provider>();
899
900    // Mapping from instrumentation class names to info about them.
901    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
902            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
903
904    // Mapping from permission names to info about them.
905    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
906            new ArrayMap<String, PackageParser.PermissionGroup>();
907
908    // Packages whose data we have transfered into another package, thus
909    // should no longer exist.
910    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
911
912    // Broadcast actions that are only available to the system.
913    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
914
915    /** List of packages waiting for verification. */
916    final SparseArray<PackageVerificationState> mPendingVerification
917            = new SparseArray<PackageVerificationState>();
918
919    /** Set of packages associated with each app op permission. */
920    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
921
922    final PackageInstallerService mInstallerService;
923
924    private final PackageDexOptimizer mPackageDexOptimizer;
925    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
926    // is used by other apps).
927    private final DexManager mDexManager;
928
929    private AtomicInteger mNextMoveId = new AtomicInteger();
930    private final MoveCallbacks mMoveCallbacks;
931
932    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
933
934    // Cache of users who need badging.
935    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
936
937    /** Token for keys in mPendingVerification. */
938    private int mPendingVerificationToken = 0;
939
940    volatile boolean mSystemReady;
941    volatile boolean mSafeMode;
942    volatile boolean mHasSystemUidErrors;
943    private volatile boolean mEphemeralAppsDisabled;
944
945    ApplicationInfo mAndroidApplication;
946    final ActivityInfo mResolveActivity = new ActivityInfo();
947    final ResolveInfo mResolveInfo = new ResolveInfo();
948    ComponentName mResolveComponentName;
949    PackageParser.Package mPlatformPackage;
950    ComponentName mCustomResolverComponentName;
951
952    boolean mResolverReplaced = false;
953
954    private final @Nullable ComponentName mIntentFilterVerifierComponent;
955    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
956
957    private int mIntentFilterVerificationToken = 0;
958
959    /** The service connection to the ephemeral resolver */
960    final EphemeralResolverConnection mInstantAppResolverConnection;
961    /** Component used to show resolver settings for Instant Apps */
962    final ComponentName mInstantAppResolverSettingsComponent;
963
964    /** Activity used to install instant applications */
965    ActivityInfo mInstantAppInstallerActivity;
966    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
967
968    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
969            = new SparseArray<IntentFilterVerificationState>();
970
971    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
972
973    // List of packages names to keep cached, even if they are uninstalled for all users
974    private List<String> mKeepUninstalledPackages;
975
976    private UserManagerInternal mUserManagerInternal;
977
978    private DeviceIdleController.LocalService mDeviceIdleController;
979
980    private File mCacheDir;
981
982    private ArraySet<String> mPrivappPermissionsViolations;
983
984    private Future<?> mPrepareAppDataFuture;
985
986    private static class IFVerificationParams {
987        PackageParser.Package pkg;
988        boolean replacing;
989        int userId;
990        int verifierUid;
991
992        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
993                int _userId, int _verifierUid) {
994            pkg = _pkg;
995            replacing = _replacing;
996            userId = _userId;
997            replacing = _replacing;
998            verifierUid = _verifierUid;
999        }
1000    }
1001
1002    private interface IntentFilterVerifier<T extends IntentFilter> {
1003        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1004                                               T filter, String packageName);
1005        void startVerifications(int userId);
1006        void receiveVerificationResponse(int verificationId);
1007    }
1008
1009    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1010        private Context mContext;
1011        private ComponentName mIntentFilterVerifierComponent;
1012        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1013
1014        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1015            mContext = context;
1016            mIntentFilterVerifierComponent = verifierComponent;
1017        }
1018
1019        private String getDefaultScheme() {
1020            return IntentFilter.SCHEME_HTTPS;
1021        }
1022
1023        @Override
1024        public void startVerifications(int userId) {
1025            // Launch verifications requests
1026            int count = mCurrentIntentFilterVerifications.size();
1027            for (int n=0; n<count; n++) {
1028                int verificationId = mCurrentIntentFilterVerifications.get(n);
1029                final IntentFilterVerificationState ivs =
1030                        mIntentFilterVerificationStates.get(verificationId);
1031
1032                String packageName = ivs.getPackageName();
1033
1034                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1035                final int filterCount = filters.size();
1036                ArraySet<String> domainsSet = new ArraySet<>();
1037                for (int m=0; m<filterCount; m++) {
1038                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1039                    domainsSet.addAll(filter.getHostsList());
1040                }
1041                synchronized (mPackages) {
1042                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1043                            packageName, domainsSet) != null) {
1044                        scheduleWriteSettingsLocked();
1045                    }
1046                }
1047                sendVerificationRequest(userId, verificationId, ivs);
1048            }
1049            mCurrentIntentFilterVerifications.clear();
1050        }
1051
1052        private void sendVerificationRequest(int userId, int verificationId,
1053                IntentFilterVerificationState ivs) {
1054
1055            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1056            verificationIntent.putExtra(
1057                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1058                    verificationId);
1059            verificationIntent.putExtra(
1060                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1061                    getDefaultScheme());
1062            verificationIntent.putExtra(
1063                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1064                    ivs.getHostsString());
1065            verificationIntent.putExtra(
1066                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1067                    ivs.getPackageName());
1068            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1069            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1070
1071            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1072            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1073                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1074                    userId, false, "intent filter verifier");
1075
1076            UserHandle user = new UserHandle(userId);
1077            mContext.sendBroadcastAsUser(verificationIntent, user);
1078            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1079                    "Sending IntentFilter verification broadcast");
1080        }
1081
1082        public void receiveVerificationResponse(int verificationId) {
1083            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1084
1085            final boolean verified = ivs.isVerified();
1086
1087            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1088            final int count = filters.size();
1089            if (DEBUG_DOMAIN_VERIFICATION) {
1090                Slog.i(TAG, "Received verification response " + verificationId
1091                        + " for " + count + " filters, verified=" + verified);
1092            }
1093            for (int n=0; n<count; n++) {
1094                PackageParser.ActivityIntentInfo filter = filters.get(n);
1095                filter.setVerified(verified);
1096
1097                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1098                        + " verified with result:" + verified + " and hosts:"
1099                        + ivs.getHostsString());
1100            }
1101
1102            mIntentFilterVerificationStates.remove(verificationId);
1103
1104            final String packageName = ivs.getPackageName();
1105            IntentFilterVerificationInfo ivi = null;
1106
1107            synchronized (mPackages) {
1108                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1109            }
1110            if (ivi == null) {
1111                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1112                        + verificationId + " packageName:" + packageName);
1113                return;
1114            }
1115            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1116                    "Updating IntentFilterVerificationInfo for package " + packageName
1117                            +" verificationId:" + verificationId);
1118
1119            synchronized (mPackages) {
1120                if (verified) {
1121                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1122                } else {
1123                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1124                }
1125                scheduleWriteSettingsLocked();
1126
1127                final int userId = ivs.getUserId();
1128                if (userId != UserHandle.USER_ALL) {
1129                    final int userStatus =
1130                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1131
1132                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1133                    boolean needUpdate = false;
1134
1135                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1136                    // already been set by the User thru the Disambiguation dialog
1137                    switch (userStatus) {
1138                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1139                            if (verified) {
1140                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1141                            } else {
1142                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1143                            }
1144                            needUpdate = true;
1145                            break;
1146
1147                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1148                            if (verified) {
1149                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1150                                needUpdate = true;
1151                            }
1152                            break;
1153
1154                        default:
1155                            // Nothing to do
1156                    }
1157
1158                    if (needUpdate) {
1159                        mSettings.updateIntentFilterVerificationStatusLPw(
1160                                packageName, updatedStatus, userId);
1161                        scheduleWritePackageRestrictionsLocked(userId);
1162                    }
1163                }
1164            }
1165        }
1166
1167        @Override
1168        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1169                    ActivityIntentInfo filter, String packageName) {
1170            if (!hasValidDomains(filter)) {
1171                return false;
1172            }
1173            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1174            if (ivs == null) {
1175                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1176                        packageName);
1177            }
1178            if (DEBUG_DOMAIN_VERIFICATION) {
1179                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1180            }
1181            ivs.addFilter(filter);
1182            return true;
1183        }
1184
1185        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1186                int userId, int verificationId, String packageName) {
1187            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1188                    verifierUid, userId, packageName);
1189            ivs.setPendingState();
1190            synchronized (mPackages) {
1191                mIntentFilterVerificationStates.append(verificationId, ivs);
1192                mCurrentIntentFilterVerifications.add(verificationId);
1193            }
1194            return ivs;
1195        }
1196    }
1197
1198    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1199        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1200                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1201                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1202    }
1203
1204    // Set of pending broadcasts for aggregating enable/disable of components.
1205    static class PendingPackageBroadcasts {
1206        // for each user id, a map of <package name -> components within that package>
1207        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1208
1209        public PendingPackageBroadcasts() {
1210            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1211        }
1212
1213        public ArrayList<String> get(int userId, String packageName) {
1214            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1215            return packages.get(packageName);
1216        }
1217
1218        public void put(int userId, String packageName, ArrayList<String> components) {
1219            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1220            packages.put(packageName, components);
1221        }
1222
1223        public void remove(int userId, String packageName) {
1224            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1225            if (packages != null) {
1226                packages.remove(packageName);
1227            }
1228        }
1229
1230        public void remove(int userId) {
1231            mUidMap.remove(userId);
1232        }
1233
1234        public int userIdCount() {
1235            return mUidMap.size();
1236        }
1237
1238        public int userIdAt(int n) {
1239            return mUidMap.keyAt(n);
1240        }
1241
1242        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1243            return mUidMap.get(userId);
1244        }
1245
1246        public int size() {
1247            // total number of pending broadcast entries across all userIds
1248            int num = 0;
1249            for (int i = 0; i< mUidMap.size(); i++) {
1250                num += mUidMap.valueAt(i).size();
1251            }
1252            return num;
1253        }
1254
1255        public void clear() {
1256            mUidMap.clear();
1257        }
1258
1259        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1260            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1261            if (map == null) {
1262                map = new ArrayMap<String, ArrayList<String>>();
1263                mUidMap.put(userId, map);
1264            }
1265            return map;
1266        }
1267    }
1268    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1269
1270    // Service Connection to remote media container service to copy
1271    // package uri's from external media onto secure containers
1272    // or internal storage.
1273    private IMediaContainerService mContainerService = null;
1274
1275    static final int SEND_PENDING_BROADCAST = 1;
1276    static final int MCS_BOUND = 3;
1277    static final int END_COPY = 4;
1278    static final int INIT_COPY = 5;
1279    static final int MCS_UNBIND = 6;
1280    static final int START_CLEANING_PACKAGE = 7;
1281    static final int FIND_INSTALL_LOC = 8;
1282    static final int POST_INSTALL = 9;
1283    static final int MCS_RECONNECT = 10;
1284    static final int MCS_GIVE_UP = 11;
1285    static final int UPDATED_MEDIA_STATUS = 12;
1286    static final int WRITE_SETTINGS = 13;
1287    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1288    static final int PACKAGE_VERIFIED = 15;
1289    static final int CHECK_PENDING_VERIFICATION = 16;
1290    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1291    static final int INTENT_FILTER_VERIFIED = 18;
1292    static final int WRITE_PACKAGE_LIST = 19;
1293    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1294
1295    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1296
1297    // Delay time in millisecs
1298    static final int BROADCAST_DELAY = 10 * 1000;
1299
1300    static UserManagerService sUserManager;
1301
1302    // Stores a list of users whose package restrictions file needs to be updated
1303    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1304
1305    final private DefaultContainerConnection mDefContainerConn =
1306            new DefaultContainerConnection();
1307    class DefaultContainerConnection implements ServiceConnection {
1308        public void onServiceConnected(ComponentName name, IBinder service) {
1309            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1310            final IMediaContainerService imcs = IMediaContainerService.Stub
1311                    .asInterface(Binder.allowBlocking(service));
1312            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1313        }
1314
1315        public void onServiceDisconnected(ComponentName name) {
1316            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1317        }
1318    }
1319
1320    // Recordkeeping of restore-after-install operations that are currently in flight
1321    // between the Package Manager and the Backup Manager
1322    static class PostInstallData {
1323        public InstallArgs args;
1324        public PackageInstalledInfo res;
1325
1326        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1327            args = _a;
1328            res = _r;
1329        }
1330    }
1331
1332    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1333    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1334
1335    // XML tags for backup/restore of various bits of state
1336    private static final String TAG_PREFERRED_BACKUP = "pa";
1337    private static final String TAG_DEFAULT_APPS = "da";
1338    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1339
1340    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1341    private static final String TAG_ALL_GRANTS = "rt-grants";
1342    private static final String TAG_GRANT = "grant";
1343    private static final String ATTR_PACKAGE_NAME = "pkg";
1344
1345    private static final String TAG_PERMISSION = "perm";
1346    private static final String ATTR_PERMISSION_NAME = "name";
1347    private static final String ATTR_IS_GRANTED = "g";
1348    private static final String ATTR_USER_SET = "set";
1349    private static final String ATTR_USER_FIXED = "fixed";
1350    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1351
1352    // System/policy permission grants are not backed up
1353    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1354            FLAG_PERMISSION_POLICY_FIXED
1355            | FLAG_PERMISSION_SYSTEM_FIXED
1356            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1357
1358    // And we back up these user-adjusted states
1359    private static final int USER_RUNTIME_GRANT_MASK =
1360            FLAG_PERMISSION_USER_SET
1361            | FLAG_PERMISSION_USER_FIXED
1362            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1363
1364    final @Nullable String mRequiredVerifierPackage;
1365    final @NonNull String mRequiredInstallerPackage;
1366    final @NonNull String mRequiredUninstallerPackage;
1367    final @Nullable String mSetupWizardPackage;
1368    final @Nullable String mStorageManagerPackage;
1369    final @NonNull String mServicesSystemSharedLibraryPackageName;
1370    final @NonNull String mSharedSystemSharedLibraryPackageName;
1371
1372    final boolean mPermissionReviewRequired;
1373
1374    private final PackageUsage mPackageUsage = new PackageUsage();
1375    private final CompilerStats mCompilerStats = new CompilerStats();
1376
1377    class PackageHandler extends Handler {
1378        private boolean mBound = false;
1379        final ArrayList<HandlerParams> mPendingInstalls =
1380            new ArrayList<HandlerParams>();
1381
1382        private boolean connectToService() {
1383            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1384                    " DefaultContainerService");
1385            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1386            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1387            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1388                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1389                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1390                mBound = true;
1391                return true;
1392            }
1393            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1394            return false;
1395        }
1396
1397        private void disconnectService() {
1398            mContainerService = null;
1399            mBound = false;
1400            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1401            mContext.unbindService(mDefContainerConn);
1402            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1403        }
1404
1405        PackageHandler(Looper looper) {
1406            super(looper);
1407        }
1408
1409        public void handleMessage(Message msg) {
1410            try {
1411                doHandleMessage(msg);
1412            } finally {
1413                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1414            }
1415        }
1416
1417        void doHandleMessage(Message msg) {
1418            switch (msg.what) {
1419                case INIT_COPY: {
1420                    HandlerParams params = (HandlerParams) msg.obj;
1421                    int idx = mPendingInstalls.size();
1422                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1423                    // If a bind was already initiated we dont really
1424                    // need to do anything. The pending install
1425                    // will be processed later on.
1426                    if (!mBound) {
1427                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1428                                System.identityHashCode(mHandler));
1429                        // If this is the only one pending we might
1430                        // have to bind to the service again.
1431                        if (!connectToService()) {
1432                            Slog.e(TAG, "Failed to bind to media container service");
1433                            params.serviceError();
1434                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1435                                    System.identityHashCode(mHandler));
1436                            if (params.traceMethod != null) {
1437                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1438                                        params.traceCookie);
1439                            }
1440                            return;
1441                        } else {
1442                            // Once we bind to the service, the first
1443                            // pending request will be processed.
1444                            mPendingInstalls.add(idx, params);
1445                        }
1446                    } else {
1447                        mPendingInstalls.add(idx, params);
1448                        // Already bound to the service. Just make
1449                        // sure we trigger off processing the first request.
1450                        if (idx == 0) {
1451                            mHandler.sendEmptyMessage(MCS_BOUND);
1452                        }
1453                    }
1454                    break;
1455                }
1456                case MCS_BOUND: {
1457                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1458                    if (msg.obj != null) {
1459                        mContainerService = (IMediaContainerService) msg.obj;
1460                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1461                                System.identityHashCode(mHandler));
1462                    }
1463                    if (mContainerService == null) {
1464                        if (!mBound) {
1465                            // Something seriously wrong since we are not bound and we are not
1466                            // waiting for connection. Bail out.
1467                            Slog.e(TAG, "Cannot bind to media container service");
1468                            for (HandlerParams params : mPendingInstalls) {
1469                                // Indicate service bind error
1470                                params.serviceError();
1471                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1472                                        System.identityHashCode(params));
1473                                if (params.traceMethod != null) {
1474                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1475                                            params.traceMethod, params.traceCookie);
1476                                }
1477                                return;
1478                            }
1479                            mPendingInstalls.clear();
1480                        } else {
1481                            Slog.w(TAG, "Waiting to connect to media container service");
1482                        }
1483                    } else if (mPendingInstalls.size() > 0) {
1484                        HandlerParams params = mPendingInstalls.get(0);
1485                        if (params != null) {
1486                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1487                                    System.identityHashCode(params));
1488                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1489                            if (params.startCopy()) {
1490                                // We are done...  look for more work or to
1491                                // go idle.
1492                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1493                                        "Checking for more work or unbind...");
1494                                // Delete pending install
1495                                if (mPendingInstalls.size() > 0) {
1496                                    mPendingInstalls.remove(0);
1497                                }
1498                                if (mPendingInstalls.size() == 0) {
1499                                    if (mBound) {
1500                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1501                                                "Posting delayed MCS_UNBIND");
1502                                        removeMessages(MCS_UNBIND);
1503                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1504                                        // Unbind after a little delay, to avoid
1505                                        // continual thrashing.
1506                                        sendMessageDelayed(ubmsg, 10000);
1507                                    }
1508                                } else {
1509                                    // There are more pending requests in queue.
1510                                    // Just post MCS_BOUND message to trigger processing
1511                                    // of next pending install.
1512                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1513                                            "Posting MCS_BOUND for next work");
1514                                    mHandler.sendEmptyMessage(MCS_BOUND);
1515                                }
1516                            }
1517                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1518                        }
1519                    } else {
1520                        // Should never happen ideally.
1521                        Slog.w(TAG, "Empty queue");
1522                    }
1523                    break;
1524                }
1525                case MCS_RECONNECT: {
1526                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1527                    if (mPendingInstalls.size() > 0) {
1528                        if (mBound) {
1529                            disconnectService();
1530                        }
1531                        if (!connectToService()) {
1532                            Slog.e(TAG, "Failed to bind to media container service");
1533                            for (HandlerParams params : mPendingInstalls) {
1534                                // Indicate service bind error
1535                                params.serviceError();
1536                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1537                                        System.identityHashCode(params));
1538                            }
1539                            mPendingInstalls.clear();
1540                        }
1541                    }
1542                    break;
1543                }
1544                case MCS_UNBIND: {
1545                    // If there is no actual work left, then time to unbind.
1546                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1547
1548                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1549                        if (mBound) {
1550                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1551
1552                            disconnectService();
1553                        }
1554                    } else if (mPendingInstalls.size() > 0) {
1555                        // There are more pending requests in queue.
1556                        // Just post MCS_BOUND message to trigger processing
1557                        // of next pending install.
1558                        mHandler.sendEmptyMessage(MCS_BOUND);
1559                    }
1560
1561                    break;
1562                }
1563                case MCS_GIVE_UP: {
1564                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1565                    HandlerParams params = mPendingInstalls.remove(0);
1566                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1567                            System.identityHashCode(params));
1568                    break;
1569                }
1570                case SEND_PENDING_BROADCAST: {
1571                    String packages[];
1572                    ArrayList<String> components[];
1573                    int size = 0;
1574                    int uids[];
1575                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1576                    synchronized (mPackages) {
1577                        if (mPendingBroadcasts == null) {
1578                            return;
1579                        }
1580                        size = mPendingBroadcasts.size();
1581                        if (size <= 0) {
1582                            // Nothing to be done. Just return
1583                            return;
1584                        }
1585                        packages = new String[size];
1586                        components = new ArrayList[size];
1587                        uids = new int[size];
1588                        int i = 0;  // filling out the above arrays
1589
1590                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1591                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1592                            Iterator<Map.Entry<String, ArrayList<String>>> it
1593                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1594                                            .entrySet().iterator();
1595                            while (it.hasNext() && i < size) {
1596                                Map.Entry<String, ArrayList<String>> ent = it.next();
1597                                packages[i] = ent.getKey();
1598                                components[i] = ent.getValue();
1599                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1600                                uids[i] = (ps != null)
1601                                        ? UserHandle.getUid(packageUserId, ps.appId)
1602                                        : -1;
1603                                i++;
1604                            }
1605                        }
1606                        size = i;
1607                        mPendingBroadcasts.clear();
1608                    }
1609                    // Send broadcasts
1610                    for (int i = 0; i < size; i++) {
1611                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1612                    }
1613                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1614                    break;
1615                }
1616                case START_CLEANING_PACKAGE: {
1617                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1618                    final String packageName = (String)msg.obj;
1619                    final int userId = msg.arg1;
1620                    final boolean andCode = msg.arg2 != 0;
1621                    synchronized (mPackages) {
1622                        if (userId == UserHandle.USER_ALL) {
1623                            int[] users = sUserManager.getUserIds();
1624                            for (int user : users) {
1625                                mSettings.addPackageToCleanLPw(
1626                                        new PackageCleanItem(user, packageName, andCode));
1627                            }
1628                        } else {
1629                            mSettings.addPackageToCleanLPw(
1630                                    new PackageCleanItem(userId, packageName, andCode));
1631                        }
1632                    }
1633                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1634                    startCleaningPackages();
1635                } break;
1636                case POST_INSTALL: {
1637                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1638
1639                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1640                    final boolean didRestore = (msg.arg2 != 0);
1641                    mRunningInstalls.delete(msg.arg1);
1642
1643                    if (data != null) {
1644                        InstallArgs args = data.args;
1645                        PackageInstalledInfo parentRes = data.res;
1646
1647                        final boolean grantPermissions = (args.installFlags
1648                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1649                        final boolean killApp = (args.installFlags
1650                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1651                        final String[] grantedPermissions = args.installGrantPermissions;
1652
1653                        // Handle the parent package
1654                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1655                                grantedPermissions, didRestore, args.installerPackageName,
1656                                args.observer);
1657
1658                        // Handle the child packages
1659                        final int childCount = (parentRes.addedChildPackages != null)
1660                                ? parentRes.addedChildPackages.size() : 0;
1661                        for (int i = 0; i < childCount; i++) {
1662                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1663                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1664                                    grantedPermissions, false, args.installerPackageName,
1665                                    args.observer);
1666                        }
1667
1668                        // Log tracing if needed
1669                        if (args.traceMethod != null) {
1670                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1671                                    args.traceCookie);
1672                        }
1673                    } else {
1674                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1675                    }
1676
1677                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1678                } break;
1679                case UPDATED_MEDIA_STATUS: {
1680                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1681                    boolean reportStatus = msg.arg1 == 1;
1682                    boolean doGc = msg.arg2 == 1;
1683                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1684                    if (doGc) {
1685                        // Force a gc to clear up stale containers.
1686                        Runtime.getRuntime().gc();
1687                    }
1688                    if (msg.obj != null) {
1689                        @SuppressWarnings("unchecked")
1690                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1691                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1692                        // Unload containers
1693                        unloadAllContainers(args);
1694                    }
1695                    if (reportStatus) {
1696                        try {
1697                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1698                                    "Invoking StorageManagerService call back");
1699                            PackageHelper.getStorageManager().finishMediaUpdate();
1700                        } catch (RemoteException e) {
1701                            Log.e(TAG, "StorageManagerService not running?");
1702                        }
1703                    }
1704                } break;
1705                case WRITE_SETTINGS: {
1706                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1707                    synchronized (mPackages) {
1708                        removeMessages(WRITE_SETTINGS);
1709                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1710                        mSettings.writeLPr();
1711                        mDirtyUsers.clear();
1712                    }
1713                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1714                } break;
1715                case WRITE_PACKAGE_RESTRICTIONS: {
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1717                    synchronized (mPackages) {
1718                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1719                        for (int userId : mDirtyUsers) {
1720                            mSettings.writePackageRestrictionsLPr(userId);
1721                        }
1722                        mDirtyUsers.clear();
1723                    }
1724                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1725                } break;
1726                case WRITE_PACKAGE_LIST: {
1727                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1728                    synchronized (mPackages) {
1729                        removeMessages(WRITE_PACKAGE_LIST);
1730                        mSettings.writePackageListLPr(msg.arg1);
1731                    }
1732                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1733                } break;
1734                case CHECK_PENDING_VERIFICATION: {
1735                    final int verificationId = msg.arg1;
1736                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1737
1738                    if ((state != null) && !state.timeoutExtended()) {
1739                        final InstallArgs args = state.getInstallArgs();
1740                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1741
1742                        Slog.i(TAG, "Verification timed out for " + originUri);
1743                        mPendingVerification.remove(verificationId);
1744
1745                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1746
1747                        final UserHandle user = args.getUser();
1748                        if (getDefaultVerificationResponse(user)
1749                                == PackageManager.VERIFICATION_ALLOW) {
1750                            Slog.i(TAG, "Continuing with installation of " + originUri);
1751                            state.setVerifierResponse(Binder.getCallingUid(),
1752                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1753                            broadcastPackageVerified(verificationId, originUri,
1754                                    PackageManager.VERIFICATION_ALLOW, user);
1755                            try {
1756                                ret = args.copyApk(mContainerService, true);
1757                            } catch (RemoteException e) {
1758                                Slog.e(TAG, "Could not contact the ContainerService");
1759                            }
1760                        } else {
1761                            broadcastPackageVerified(verificationId, originUri,
1762                                    PackageManager.VERIFICATION_REJECT, user);
1763                        }
1764
1765                        Trace.asyncTraceEnd(
1766                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1767
1768                        processPendingInstall(args, ret);
1769                        mHandler.sendEmptyMessage(MCS_UNBIND);
1770                    }
1771                    break;
1772                }
1773                case PACKAGE_VERIFIED: {
1774                    final int verificationId = msg.arg1;
1775
1776                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1777                    if (state == null) {
1778                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1779                        break;
1780                    }
1781
1782                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1783
1784                    state.setVerifierResponse(response.callerUid, response.code);
1785
1786                    if (state.isVerificationComplete()) {
1787                        mPendingVerification.remove(verificationId);
1788
1789                        final InstallArgs args = state.getInstallArgs();
1790                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1791
1792                        int ret;
1793                        if (state.isInstallAllowed()) {
1794                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1795                            broadcastPackageVerified(verificationId, originUri,
1796                                    response.code, state.getInstallArgs().getUser());
1797                            try {
1798                                ret = args.copyApk(mContainerService, true);
1799                            } catch (RemoteException e) {
1800                                Slog.e(TAG, "Could not contact the ContainerService");
1801                            }
1802                        } else {
1803                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1804                        }
1805
1806                        Trace.asyncTraceEnd(
1807                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1808
1809                        processPendingInstall(args, ret);
1810                        mHandler.sendEmptyMessage(MCS_UNBIND);
1811                    }
1812
1813                    break;
1814                }
1815                case START_INTENT_FILTER_VERIFICATIONS: {
1816                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1817                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1818                            params.replacing, params.pkg);
1819                    break;
1820                }
1821                case INTENT_FILTER_VERIFIED: {
1822                    final int verificationId = msg.arg1;
1823
1824                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1825                            verificationId);
1826                    if (state == null) {
1827                        Slog.w(TAG, "Invalid IntentFilter verification token "
1828                                + verificationId + " received");
1829                        break;
1830                    }
1831
1832                    final int userId = state.getUserId();
1833
1834                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1835                            "Processing IntentFilter verification with token:"
1836                            + verificationId + " and userId:" + userId);
1837
1838                    final IntentFilterVerificationResponse response =
1839                            (IntentFilterVerificationResponse) msg.obj;
1840
1841                    state.setVerifierResponse(response.callerUid, response.code);
1842
1843                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1844                            "IntentFilter verification with token:" + verificationId
1845                            + " and userId:" + userId
1846                            + " is settings verifier response with response code:"
1847                            + response.code);
1848
1849                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1850                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1851                                + response.getFailedDomainsString());
1852                    }
1853
1854                    if (state.isVerificationComplete()) {
1855                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1856                    } else {
1857                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1858                                "IntentFilter verification with token:" + verificationId
1859                                + " was not said to be complete");
1860                    }
1861
1862                    break;
1863                }
1864                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1865                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1866                            mInstantAppResolverConnection,
1867                            (InstantAppRequest) msg.obj,
1868                            mInstantAppInstallerActivity,
1869                            mHandler);
1870                }
1871            }
1872        }
1873    }
1874
1875    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1876            boolean killApp, String[] grantedPermissions,
1877            boolean launchedForRestore, String installerPackage,
1878            IPackageInstallObserver2 installObserver) {
1879        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1880            // Send the removed broadcasts
1881            if (res.removedInfo != null) {
1882                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1883            }
1884
1885            // Now that we successfully installed the package, grant runtime
1886            // permissions if requested before broadcasting the install. Also
1887            // for legacy apps in permission review mode we clear the permission
1888            // review flag which is used to emulate runtime permissions for
1889            // legacy apps.
1890            if (grantPermissions) {
1891                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1892            }
1893
1894            final boolean update = res.removedInfo != null
1895                    && res.removedInfo.removedPackage != null;
1896            final String origInstallerPackageName = res.removedInfo != null
1897                    ? res.removedInfo.installerPackageName : null;
1898
1899            // If this is the first time we have child packages for a disabled privileged
1900            // app that had no children, we grant requested runtime permissions to the new
1901            // children if the parent on the system image had them already granted.
1902            if (res.pkg.parentPackage != null) {
1903                synchronized (mPackages) {
1904                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1905                }
1906            }
1907
1908            synchronized (mPackages) {
1909                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1910            }
1911
1912            final String packageName = res.pkg.applicationInfo.packageName;
1913
1914            // Determine the set of users who are adding this package for
1915            // the first time vs. those who are seeing an update.
1916            int[] firstUsers = EMPTY_INT_ARRAY;
1917            int[] updateUsers = EMPTY_INT_ARRAY;
1918            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1919            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1920            for (int newUser : res.newUsers) {
1921                if (ps.getInstantApp(newUser)) {
1922                    continue;
1923                }
1924                if (allNewUsers) {
1925                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1926                    continue;
1927                }
1928                boolean isNew = true;
1929                for (int origUser : res.origUsers) {
1930                    if (origUser == newUser) {
1931                        isNew = false;
1932                        break;
1933                    }
1934                }
1935                if (isNew) {
1936                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1937                } else {
1938                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1939                }
1940            }
1941
1942            // Send installed broadcasts if the package is not a static shared lib.
1943            if (res.pkg.staticSharedLibName == null) {
1944                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1945
1946                // Send added for users that see the package for the first time
1947                // sendPackageAddedForNewUsers also deals with system apps
1948                int appId = UserHandle.getAppId(res.uid);
1949                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1950                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1951
1952                // Send added for users that don't see the package for the first time
1953                Bundle extras = new Bundle(1);
1954                extras.putInt(Intent.EXTRA_UID, res.uid);
1955                if (update) {
1956                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1957                }
1958                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1959                        extras, 0 /*flags*/,
1960                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1961                if (origInstallerPackageName != null) {
1962                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1963                            extras, 0 /*flags*/,
1964                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1965                }
1966
1967                // Send replaced for users that don't see the package for the first time
1968                if (update) {
1969                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1970                            packageName, extras, 0 /*flags*/,
1971                            null /*targetPackage*/, null /*finishedReceiver*/,
1972                            updateUsers);
1973                    if (origInstallerPackageName != null) {
1974                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1975                                extras, 0 /*flags*/,
1976                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1977                    }
1978                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1979                            null /*package*/, null /*extras*/, 0 /*flags*/,
1980                            packageName /*targetPackage*/,
1981                            null /*finishedReceiver*/, updateUsers);
1982                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1983                    // First-install and we did a restore, so we're responsible for the
1984                    // first-launch broadcast.
1985                    if (DEBUG_BACKUP) {
1986                        Slog.i(TAG, "Post-restore of " + packageName
1987                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1988                    }
1989                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1990                }
1991
1992                // Send broadcast package appeared if forward locked/external for all users
1993                // treat asec-hosted packages like removable media on upgrade
1994                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1995                    if (DEBUG_INSTALL) {
1996                        Slog.i(TAG, "upgrading pkg " + res.pkg
1997                                + " is ASEC-hosted -> AVAILABLE");
1998                    }
1999                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2000                    ArrayList<String> pkgList = new ArrayList<>(1);
2001                    pkgList.add(packageName);
2002                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2003                }
2004            }
2005
2006            // Work that needs to happen on first install within each user
2007            if (firstUsers != null && firstUsers.length > 0) {
2008                synchronized (mPackages) {
2009                    for (int userId : firstUsers) {
2010                        // If this app is a browser and it's newly-installed for some
2011                        // users, clear any default-browser state in those users. The
2012                        // app's nature doesn't depend on the user, so we can just check
2013                        // its browser nature in any user and generalize.
2014                        if (packageIsBrowser(packageName, userId)) {
2015                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2016                        }
2017
2018                        // We may also need to apply pending (restored) runtime
2019                        // permission grants within these users.
2020                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2021                    }
2022                }
2023            }
2024
2025            // Log current value of "unknown sources" setting
2026            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2027                    getUnknownSourcesSettings());
2028
2029            // Remove the replaced package's older resources safely now
2030            // We delete after a gc for applications  on sdcard.
2031            if (res.removedInfo != null && res.removedInfo.args != null) {
2032                Runtime.getRuntime().gc();
2033                synchronized (mInstallLock) {
2034                    res.removedInfo.args.doPostDeleteLI(true);
2035                }
2036            } else {
2037                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2038                // and not block here.
2039                VMRuntime.getRuntime().requestConcurrentGC();
2040            }
2041
2042            // Notify DexManager that the package was installed for new users.
2043            // The updated users should already be indexed and the package code paths
2044            // should not change.
2045            // Don't notify the manager for ephemeral apps as they are not expected to
2046            // survive long enough to benefit of background optimizations.
2047            for (int userId : firstUsers) {
2048                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2049                // There's a race currently where some install events may interleave with an uninstall.
2050                // This can lead to package info being null (b/36642664).
2051                if (info != null) {
2052                    mDexManager.notifyPackageInstalled(info, userId);
2053                }
2054            }
2055        }
2056
2057        // If someone is watching installs - notify them
2058        if (installObserver != null) {
2059            try {
2060                Bundle extras = extrasForInstallResult(res);
2061                installObserver.onPackageInstalled(res.name, res.returnCode,
2062                        res.returnMsg, extras);
2063            } catch (RemoteException e) {
2064                Slog.i(TAG, "Observer no longer exists.");
2065            }
2066        }
2067    }
2068
2069    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2070            PackageParser.Package pkg) {
2071        if (pkg.parentPackage == null) {
2072            return;
2073        }
2074        if (pkg.requestedPermissions == null) {
2075            return;
2076        }
2077        final PackageSetting disabledSysParentPs = mSettings
2078                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2079        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2080                || !disabledSysParentPs.isPrivileged()
2081                || (disabledSysParentPs.childPackageNames != null
2082                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2083            return;
2084        }
2085        final int[] allUserIds = sUserManager.getUserIds();
2086        final int permCount = pkg.requestedPermissions.size();
2087        for (int i = 0; i < permCount; i++) {
2088            String permission = pkg.requestedPermissions.get(i);
2089            BasePermission bp = mSettings.mPermissions.get(permission);
2090            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2091                continue;
2092            }
2093            for (int userId : allUserIds) {
2094                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2095                        permission, userId)) {
2096                    grantRuntimePermission(pkg.packageName, permission, userId);
2097                }
2098            }
2099        }
2100    }
2101
2102    private StorageEventListener mStorageListener = new StorageEventListener() {
2103        @Override
2104        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2105            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2106                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2107                    final String volumeUuid = vol.getFsUuid();
2108
2109                    // Clean up any users or apps that were removed or recreated
2110                    // while this volume was missing
2111                    sUserManager.reconcileUsers(volumeUuid);
2112                    reconcileApps(volumeUuid);
2113
2114                    // Clean up any install sessions that expired or were
2115                    // cancelled while this volume was missing
2116                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2117
2118                    loadPrivatePackages(vol);
2119
2120                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2121                    unloadPrivatePackages(vol);
2122                }
2123            }
2124
2125            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2126                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2127                    updateExternalMediaStatus(true, false);
2128                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2129                    updateExternalMediaStatus(false, false);
2130                }
2131            }
2132        }
2133
2134        @Override
2135        public void onVolumeForgotten(String fsUuid) {
2136            if (TextUtils.isEmpty(fsUuid)) {
2137                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2138                return;
2139            }
2140
2141            // Remove any apps installed on the forgotten volume
2142            synchronized (mPackages) {
2143                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2144                for (PackageSetting ps : packages) {
2145                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2146                    deletePackageVersioned(new VersionedPackage(ps.name,
2147                            PackageManager.VERSION_CODE_HIGHEST),
2148                            new LegacyPackageDeleteObserver(null).getBinder(),
2149                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2150                    // Try very hard to release any references to this package
2151                    // so we don't risk the system server being killed due to
2152                    // open FDs
2153                    AttributeCache.instance().removePackage(ps.name);
2154                }
2155
2156                mSettings.onVolumeForgotten(fsUuid);
2157                mSettings.writeLPr();
2158            }
2159        }
2160    };
2161
2162    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2163            String[] grantedPermissions) {
2164        for (int userId : userIds) {
2165            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2166        }
2167    }
2168
2169    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2170            String[] grantedPermissions) {
2171        SettingBase sb = (SettingBase) pkg.mExtras;
2172        if (sb == null) {
2173            return;
2174        }
2175
2176        PermissionsState permissionsState = sb.getPermissionsState();
2177
2178        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2179                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2180
2181        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2182                >= Build.VERSION_CODES.M;
2183
2184        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2185
2186        for (String permission : pkg.requestedPermissions) {
2187            final BasePermission bp;
2188            synchronized (mPackages) {
2189                bp = mSettings.mPermissions.get(permission);
2190            }
2191            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2192                    && (!instantApp || bp.isInstant())
2193                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2194                    && (grantedPermissions == null
2195                           || ArrayUtils.contains(grantedPermissions, permission))) {
2196                final int flags = permissionsState.getPermissionFlags(permission, userId);
2197                if (supportsRuntimePermissions) {
2198                    // Installer cannot change immutable permissions.
2199                    if ((flags & immutableFlags) == 0) {
2200                        grantRuntimePermission(pkg.packageName, permission, userId);
2201                    }
2202                } else if (mPermissionReviewRequired) {
2203                    // In permission review mode we clear the review flag when we
2204                    // are asked to install the app with all permissions granted.
2205                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2206                        updatePermissionFlags(permission, pkg.packageName,
2207                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2208                    }
2209                }
2210            }
2211        }
2212    }
2213
2214    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2215        Bundle extras = null;
2216        switch (res.returnCode) {
2217            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2218                extras = new Bundle();
2219                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2220                        res.origPermission);
2221                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2222                        res.origPackage);
2223                break;
2224            }
2225            case PackageManager.INSTALL_SUCCEEDED: {
2226                extras = new Bundle();
2227                extras.putBoolean(Intent.EXTRA_REPLACING,
2228                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2229                break;
2230            }
2231        }
2232        return extras;
2233    }
2234
2235    void scheduleWriteSettingsLocked() {
2236        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2237            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2238        }
2239    }
2240
2241    void scheduleWritePackageListLocked(int userId) {
2242        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2243            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2244            msg.arg1 = userId;
2245            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2246        }
2247    }
2248
2249    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2250        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2251        scheduleWritePackageRestrictionsLocked(userId);
2252    }
2253
2254    void scheduleWritePackageRestrictionsLocked(int userId) {
2255        final int[] userIds = (userId == UserHandle.USER_ALL)
2256                ? sUserManager.getUserIds() : new int[]{userId};
2257        for (int nextUserId : userIds) {
2258            if (!sUserManager.exists(nextUserId)) return;
2259            mDirtyUsers.add(nextUserId);
2260            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2261                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2262            }
2263        }
2264    }
2265
2266    public static PackageManagerService main(Context context, Installer installer,
2267            boolean factoryTest, boolean onlyCore) {
2268        // Self-check for initial settings.
2269        PackageManagerServiceCompilerMapping.checkProperties();
2270
2271        PackageManagerService m = new PackageManagerService(context, installer,
2272                factoryTest, onlyCore);
2273        m.enableSystemUserPackages();
2274        ServiceManager.addService("package", m);
2275        return m;
2276    }
2277
2278    private void enableSystemUserPackages() {
2279        if (!UserManager.isSplitSystemUser()) {
2280            return;
2281        }
2282        // For system user, enable apps based on the following conditions:
2283        // - app is whitelisted or belong to one of these groups:
2284        //   -- system app which has no launcher icons
2285        //   -- system app which has INTERACT_ACROSS_USERS permission
2286        //   -- system IME app
2287        // - app is not in the blacklist
2288        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2289        Set<String> enableApps = new ArraySet<>();
2290        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2291                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2292                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2293        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2294        enableApps.addAll(wlApps);
2295        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2296                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2297        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2298        enableApps.removeAll(blApps);
2299        Log.i(TAG, "Applications installed for system user: " + enableApps);
2300        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2301                UserHandle.SYSTEM);
2302        final int allAppsSize = allAps.size();
2303        synchronized (mPackages) {
2304            for (int i = 0; i < allAppsSize; i++) {
2305                String pName = allAps.get(i);
2306                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2307                // Should not happen, but we shouldn't be failing if it does
2308                if (pkgSetting == null) {
2309                    continue;
2310                }
2311                boolean install = enableApps.contains(pName);
2312                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2313                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2314                            + " for system user");
2315                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2316                }
2317            }
2318            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2319        }
2320    }
2321
2322    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2323        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2324                Context.DISPLAY_SERVICE);
2325        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2326    }
2327
2328    /**
2329     * Requests that files preopted on a secondary system partition be copied to the data partition
2330     * if possible.  Note that the actual copying of the files is accomplished by init for security
2331     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2332     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2333     */
2334    private static void requestCopyPreoptedFiles() {
2335        final int WAIT_TIME_MS = 100;
2336        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2337        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2338            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2339            // We will wait for up to 100 seconds.
2340            final long timeStart = SystemClock.uptimeMillis();
2341            final long timeEnd = timeStart + 100 * 1000;
2342            long timeNow = timeStart;
2343            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2344                try {
2345                    Thread.sleep(WAIT_TIME_MS);
2346                } catch (InterruptedException e) {
2347                    // Do nothing
2348                }
2349                timeNow = SystemClock.uptimeMillis();
2350                if (timeNow > timeEnd) {
2351                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2352                    Slog.wtf(TAG, "cppreopt did not finish!");
2353                    break;
2354                }
2355            }
2356
2357            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2358        }
2359    }
2360
2361    public PackageManagerService(Context context, Installer installer,
2362            boolean factoryTest, boolean onlyCore) {
2363        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2364        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2365        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2366                SystemClock.uptimeMillis());
2367
2368        if (mSdkVersion <= 0) {
2369            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2370        }
2371
2372        mContext = context;
2373
2374        mPermissionReviewRequired = context.getResources().getBoolean(
2375                R.bool.config_permissionReviewRequired);
2376
2377        mFactoryTest = factoryTest;
2378        mOnlyCore = onlyCore;
2379        mMetrics = new DisplayMetrics();
2380        mSettings = new Settings(mPackages);
2381        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2382                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2383        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2384                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2385        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2386                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2387        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2388                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2389        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2390                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2391        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2392                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2393
2394        String separateProcesses = SystemProperties.get("debug.separate_processes");
2395        if (separateProcesses != null && separateProcesses.length() > 0) {
2396            if ("*".equals(separateProcesses)) {
2397                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2398                mSeparateProcesses = null;
2399                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2400            } else {
2401                mDefParseFlags = 0;
2402                mSeparateProcesses = separateProcesses.split(",");
2403                Slog.w(TAG, "Running with debug.separate_processes: "
2404                        + separateProcesses);
2405            }
2406        } else {
2407            mDefParseFlags = 0;
2408            mSeparateProcesses = null;
2409        }
2410
2411        mInstaller = installer;
2412        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2413                "*dexopt*");
2414        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2415        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2416
2417        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2418                FgThread.get().getLooper());
2419
2420        getDefaultDisplayMetrics(context, mMetrics);
2421
2422        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2423        SystemConfig systemConfig = SystemConfig.getInstance();
2424        mGlobalGids = systemConfig.getGlobalGids();
2425        mSystemPermissions = systemConfig.getSystemPermissions();
2426        mAvailableFeatures = systemConfig.getAvailableFeatures();
2427        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2428
2429        mProtectedPackages = new ProtectedPackages(mContext);
2430
2431        synchronized (mInstallLock) {
2432        // writer
2433        synchronized (mPackages) {
2434            mHandlerThread = new ServiceThread(TAG,
2435                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2436            mHandlerThread.start();
2437            mHandler = new PackageHandler(mHandlerThread.getLooper());
2438            mProcessLoggingHandler = new ProcessLoggingHandler();
2439            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2440
2441            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2442            mInstantAppRegistry = new InstantAppRegistry(this);
2443
2444            File dataDir = Environment.getDataDirectory();
2445            mAppInstallDir = new File(dataDir, "app");
2446            mAppLib32InstallDir = new File(dataDir, "app-lib");
2447            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2448            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2449            sUserManager = new UserManagerService(context, this,
2450                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2451
2452            // Propagate permission configuration in to package manager.
2453            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2454                    = systemConfig.getPermissions();
2455            for (int i=0; i<permConfig.size(); i++) {
2456                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2457                BasePermission bp = mSettings.mPermissions.get(perm.name);
2458                if (bp == null) {
2459                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2460                    mSettings.mPermissions.put(perm.name, bp);
2461                }
2462                if (perm.gids != null) {
2463                    bp.setGids(perm.gids, perm.perUser);
2464                }
2465            }
2466
2467            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2468            final int builtInLibCount = libConfig.size();
2469            for (int i = 0; i < builtInLibCount; i++) {
2470                String name = libConfig.keyAt(i);
2471                String path = libConfig.valueAt(i);
2472                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2473                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2474            }
2475
2476            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2477
2478            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2479            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2480            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2481
2482            // Clean up orphaned packages for which the code path doesn't exist
2483            // and they are an update to a system app - caused by bug/32321269
2484            final int packageSettingCount = mSettings.mPackages.size();
2485            for (int i = packageSettingCount - 1; i >= 0; i--) {
2486                PackageSetting ps = mSettings.mPackages.valueAt(i);
2487                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2488                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2489                    mSettings.mPackages.removeAt(i);
2490                    mSettings.enableSystemPackageLPw(ps.name);
2491                }
2492            }
2493
2494            if (mFirstBoot) {
2495                requestCopyPreoptedFiles();
2496            }
2497
2498            String customResolverActivity = Resources.getSystem().getString(
2499                    R.string.config_customResolverActivity);
2500            if (TextUtils.isEmpty(customResolverActivity)) {
2501                customResolverActivity = null;
2502            } else {
2503                mCustomResolverComponentName = ComponentName.unflattenFromString(
2504                        customResolverActivity);
2505            }
2506
2507            long startTime = SystemClock.uptimeMillis();
2508
2509            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2510                    startTime);
2511
2512            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2513            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2514
2515            if (bootClassPath == null) {
2516                Slog.w(TAG, "No BOOTCLASSPATH found!");
2517            }
2518
2519            if (systemServerClassPath == null) {
2520                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2521            }
2522
2523            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2524
2525            final VersionInfo ver = mSettings.getInternalVersion();
2526            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2527            if (mIsUpgrade) {
2528                logCriticalInfo(Log.INFO,
2529                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2530            }
2531
2532            // when upgrading from pre-M, promote system app permissions from install to runtime
2533            mPromoteSystemApps =
2534                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2535
2536            // When upgrading from pre-N, we need to handle package extraction like first boot,
2537            // as there is no profiling data available.
2538            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2539
2540            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2541
2542            // save off the names of pre-existing system packages prior to scanning; we don't
2543            // want to automatically grant runtime permissions for new system apps
2544            if (mPromoteSystemApps) {
2545                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2546                while (pkgSettingIter.hasNext()) {
2547                    PackageSetting ps = pkgSettingIter.next();
2548                    if (isSystemApp(ps)) {
2549                        mExistingSystemPackages.add(ps.name);
2550                    }
2551                }
2552            }
2553
2554            mCacheDir = preparePackageParserCache(mIsUpgrade);
2555
2556            // Set flag to monitor and not change apk file paths when
2557            // scanning install directories.
2558            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2559
2560            if (mIsUpgrade || mFirstBoot) {
2561                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2562            }
2563
2564            // Collect vendor overlay packages. (Do this before scanning any apps.)
2565            // For security and version matching reason, only consider
2566            // overlay packages if they reside in the right directory.
2567            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2568                    | PackageParser.PARSE_IS_SYSTEM
2569                    | PackageParser.PARSE_IS_SYSTEM_DIR
2570                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2571
2572            mParallelPackageParserCallback.findStaticOverlayPackages();
2573
2574            // Find base frameworks (resource packages without code).
2575            scanDirTracedLI(frameworkDir, mDefParseFlags
2576                    | PackageParser.PARSE_IS_SYSTEM
2577                    | PackageParser.PARSE_IS_SYSTEM_DIR
2578                    | PackageParser.PARSE_IS_PRIVILEGED,
2579                    scanFlags | SCAN_NO_DEX, 0);
2580
2581            // Collected privileged system packages.
2582            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2583            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2584                    | PackageParser.PARSE_IS_SYSTEM
2585                    | PackageParser.PARSE_IS_SYSTEM_DIR
2586                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2587
2588            // Collect ordinary system packages.
2589            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2590            scanDirTracedLI(systemAppDir, mDefParseFlags
2591                    | PackageParser.PARSE_IS_SYSTEM
2592                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2593
2594            // Collect all vendor packages.
2595            File vendorAppDir = new File("/vendor/app");
2596            try {
2597                vendorAppDir = vendorAppDir.getCanonicalFile();
2598            } catch (IOException e) {
2599                // failed to look up canonical path, continue with original one
2600            }
2601            scanDirTracedLI(vendorAppDir, mDefParseFlags
2602                    | PackageParser.PARSE_IS_SYSTEM
2603                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2604
2605            // Collect all OEM packages.
2606            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2607            scanDirTracedLI(oemAppDir, mDefParseFlags
2608                    | PackageParser.PARSE_IS_SYSTEM
2609                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2610
2611            // Prune any system packages that no longer exist.
2612            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2613            if (!mOnlyCore) {
2614                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2615                while (psit.hasNext()) {
2616                    PackageSetting ps = psit.next();
2617
2618                    /*
2619                     * If this is not a system app, it can't be a
2620                     * disable system app.
2621                     */
2622                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2623                        continue;
2624                    }
2625
2626                    /*
2627                     * If the package is scanned, it's not erased.
2628                     */
2629                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2630                    if (scannedPkg != null) {
2631                        /*
2632                         * If the system app is both scanned and in the
2633                         * disabled packages list, then it must have been
2634                         * added via OTA. Remove it from the currently
2635                         * scanned package so the previously user-installed
2636                         * application can be scanned.
2637                         */
2638                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2639                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2640                                    + ps.name + "; removing system app.  Last known codePath="
2641                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2642                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2643                                    + scannedPkg.mVersionCode);
2644                            removePackageLI(scannedPkg, true);
2645                            mExpectingBetter.put(ps.name, ps.codePath);
2646                        }
2647
2648                        continue;
2649                    }
2650
2651                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2652                        psit.remove();
2653                        logCriticalInfo(Log.WARN, "System package " + ps.name
2654                                + " no longer exists; it's data will be wiped");
2655                        // Actual deletion of code and data will be handled by later
2656                        // reconciliation step
2657                    } else {
2658                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2659                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2660                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2661                        }
2662                    }
2663                }
2664            }
2665
2666            //look for any incomplete package installations
2667            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2668            for (int i = 0; i < deletePkgsList.size(); i++) {
2669                // Actual deletion of code and data will be handled by later
2670                // reconciliation step
2671                final String packageName = deletePkgsList.get(i).name;
2672                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2673                synchronized (mPackages) {
2674                    mSettings.removePackageLPw(packageName);
2675                }
2676            }
2677
2678            //delete tmp files
2679            deleteTempPackageFiles();
2680
2681            // Remove any shared userIDs that have no associated packages
2682            mSettings.pruneSharedUsersLPw();
2683
2684            if (!mOnlyCore) {
2685                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2686                        SystemClock.uptimeMillis());
2687                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2688
2689                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2690                        | PackageParser.PARSE_FORWARD_LOCK,
2691                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2692
2693                /**
2694                 * Remove disable package settings for any updated system
2695                 * apps that were removed via an OTA. If they're not a
2696                 * previously-updated app, remove them completely.
2697                 * Otherwise, just revoke their system-level permissions.
2698                 */
2699                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2700                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2701                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2702
2703                    String msg;
2704                    if (deletedPkg == null) {
2705                        msg = "Updated system package " + deletedAppName
2706                                + " no longer exists; it's data will be wiped";
2707                        // Actual deletion of code and data will be handled by later
2708                        // reconciliation step
2709                    } else {
2710                        msg = "Updated system app + " + deletedAppName
2711                                + " no longer present; removing system privileges for "
2712                                + deletedAppName;
2713
2714                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2715
2716                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2717                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2718                    }
2719                    logCriticalInfo(Log.WARN, msg);
2720                }
2721
2722                /**
2723                 * Make sure all system apps that we expected to appear on
2724                 * the userdata partition actually showed up. If they never
2725                 * appeared, crawl back and revive the system version.
2726                 */
2727                for (int i = 0; i < mExpectingBetter.size(); i++) {
2728                    final String packageName = mExpectingBetter.keyAt(i);
2729                    if (!mPackages.containsKey(packageName)) {
2730                        final File scanFile = mExpectingBetter.valueAt(i);
2731
2732                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2733                                + " but never showed up; reverting to system");
2734
2735                        int reparseFlags = mDefParseFlags;
2736                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2737                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2738                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2739                                    | PackageParser.PARSE_IS_PRIVILEGED;
2740                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2741                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2742                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2743                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2744                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2745                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2746                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2747                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2748                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2749                        } else {
2750                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2751                            continue;
2752                        }
2753
2754                        mSettings.enableSystemPackageLPw(packageName);
2755
2756                        try {
2757                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2758                        } catch (PackageManagerException e) {
2759                            Slog.e(TAG, "Failed to parse original system package: "
2760                                    + e.getMessage());
2761                        }
2762                    }
2763                }
2764            }
2765            mExpectingBetter.clear();
2766
2767            // Resolve the storage manager.
2768            mStorageManagerPackage = getStorageManagerPackageName();
2769
2770            // Resolve protected action filters. Only the setup wizard is allowed to
2771            // have a high priority filter for these actions.
2772            mSetupWizardPackage = getSetupWizardPackageName();
2773            if (mProtectedFilters.size() > 0) {
2774                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2775                    Slog.i(TAG, "No setup wizard;"
2776                        + " All protected intents capped to priority 0");
2777                }
2778                for (ActivityIntentInfo filter : mProtectedFilters) {
2779                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2780                        if (DEBUG_FILTERS) {
2781                            Slog.i(TAG, "Found setup wizard;"
2782                                + " allow priority " + filter.getPriority() + ";"
2783                                + " package: " + filter.activity.info.packageName
2784                                + " activity: " + filter.activity.className
2785                                + " priority: " + filter.getPriority());
2786                        }
2787                        // skip setup wizard; allow it to keep the high priority filter
2788                        continue;
2789                    }
2790                    if (DEBUG_FILTERS) {
2791                        Slog.i(TAG, "Protected action; cap priority to 0;"
2792                                + " package: " + filter.activity.info.packageName
2793                                + " activity: " + filter.activity.className
2794                                + " origPrio: " + filter.getPriority());
2795                    }
2796                    filter.setPriority(0);
2797                }
2798            }
2799            mDeferProtectedFilters = false;
2800            mProtectedFilters.clear();
2801
2802            // Now that we know all of the shared libraries, update all clients to have
2803            // the correct library paths.
2804            updateAllSharedLibrariesLPw(null);
2805
2806            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2807                // NOTE: We ignore potential failures here during a system scan (like
2808                // the rest of the commands above) because there's precious little we
2809                // can do about it. A settings error is reported, though.
2810                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2811            }
2812
2813            // Now that we know all the packages we are keeping,
2814            // read and update their last usage times.
2815            mPackageUsage.read(mPackages);
2816            mCompilerStats.read();
2817
2818            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2819                    SystemClock.uptimeMillis());
2820            Slog.i(TAG, "Time to scan packages: "
2821                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2822                    + " seconds");
2823
2824            // If the platform SDK has changed since the last time we booted,
2825            // we need to re-grant app permission to catch any new ones that
2826            // appear.  This is really a hack, and means that apps can in some
2827            // cases get permissions that the user didn't initially explicitly
2828            // allow...  it would be nice to have some better way to handle
2829            // this situation.
2830            int updateFlags = UPDATE_PERMISSIONS_ALL;
2831            if (ver.sdkVersion != mSdkVersion) {
2832                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2833                        + mSdkVersion + "; regranting permissions for internal storage");
2834                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2835            }
2836            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2837            ver.sdkVersion = mSdkVersion;
2838
2839            // If this is the first boot or an update from pre-M, and it is a normal
2840            // boot, then we need to initialize the default preferred apps across
2841            // all defined users.
2842            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2843                for (UserInfo user : sUserManager.getUsers(true)) {
2844                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2845                    applyFactoryDefaultBrowserLPw(user.id);
2846                    primeDomainVerificationsLPw(user.id);
2847                }
2848            }
2849
2850            // Prepare storage for system user really early during boot,
2851            // since core system apps like SettingsProvider and SystemUI
2852            // can't wait for user to start
2853            final int storageFlags;
2854            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2855                storageFlags = StorageManager.FLAG_STORAGE_DE;
2856            } else {
2857                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2858            }
2859            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2860                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2861                    true /* onlyCoreApps */);
2862            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2863                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2864                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2865                traceLog.traceBegin("AppDataFixup");
2866                try {
2867                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2868                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2869                } catch (InstallerException e) {
2870                    Slog.w(TAG, "Trouble fixing GIDs", e);
2871                }
2872                traceLog.traceEnd();
2873
2874                traceLog.traceBegin("AppDataPrepare");
2875                if (deferPackages == null || deferPackages.isEmpty()) {
2876                    return;
2877                }
2878                int count = 0;
2879                for (String pkgName : deferPackages) {
2880                    PackageParser.Package pkg = null;
2881                    synchronized (mPackages) {
2882                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2883                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2884                            pkg = ps.pkg;
2885                        }
2886                    }
2887                    if (pkg != null) {
2888                        synchronized (mInstallLock) {
2889                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2890                                    true /* maybeMigrateAppData */);
2891                        }
2892                        count++;
2893                    }
2894                }
2895                traceLog.traceEnd();
2896                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2897            }, "prepareAppData");
2898
2899            // If this is first boot after an OTA, and a normal boot, then
2900            // we need to clear code cache directories.
2901            // Note that we do *not* clear the application profiles. These remain valid
2902            // across OTAs and are used to drive profile verification (post OTA) and
2903            // profile compilation (without waiting to collect a fresh set of profiles).
2904            if (mIsUpgrade && !onlyCore) {
2905                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2906                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2907                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2908                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2909                        // No apps are running this early, so no need to freeze
2910                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2911                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2912                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2913                    }
2914                }
2915                ver.fingerprint = Build.FINGERPRINT;
2916            }
2917
2918            checkDefaultBrowser();
2919
2920            // clear only after permissions and other defaults have been updated
2921            mExistingSystemPackages.clear();
2922            mPromoteSystemApps = false;
2923
2924            // All the changes are done during package scanning.
2925            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2926
2927            // can downgrade to reader
2928            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2929            mSettings.writeLPr();
2930            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2931
2932            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2933                    SystemClock.uptimeMillis());
2934
2935            if (!mOnlyCore) {
2936                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2937                mRequiredInstallerPackage = getRequiredInstallerLPr();
2938                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2939                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2940                if (mIntentFilterVerifierComponent != null) {
2941                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2942                            mIntentFilterVerifierComponent);
2943                } else {
2944                    mIntentFilterVerifier = null;
2945                }
2946                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2947                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2948                        SharedLibraryInfo.VERSION_UNDEFINED);
2949                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2950                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2951                        SharedLibraryInfo.VERSION_UNDEFINED);
2952            } else {
2953                mRequiredVerifierPackage = null;
2954                mRequiredInstallerPackage = null;
2955                mRequiredUninstallerPackage = null;
2956                mIntentFilterVerifierComponent = null;
2957                mIntentFilterVerifier = null;
2958                mServicesSystemSharedLibraryPackageName = null;
2959                mSharedSystemSharedLibraryPackageName = null;
2960            }
2961
2962            mInstallerService = new PackageInstallerService(context, this);
2963            final Pair<ComponentName, String> instantAppResolverComponent =
2964                    getInstantAppResolverLPr();
2965            if (instantAppResolverComponent != null) {
2966                if (DEBUG_EPHEMERAL) {
2967                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2968                }
2969                mInstantAppResolverConnection = new EphemeralResolverConnection(
2970                        mContext, instantAppResolverComponent.first,
2971                        instantAppResolverComponent.second);
2972                mInstantAppResolverSettingsComponent =
2973                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2974            } else {
2975                mInstantAppResolverConnection = null;
2976                mInstantAppResolverSettingsComponent = null;
2977            }
2978            updateInstantAppInstallerLocked(null);
2979
2980            // Read and update the usage of dex files.
2981            // Do this at the end of PM init so that all the packages have their
2982            // data directory reconciled.
2983            // At this point we know the code paths of the packages, so we can validate
2984            // the disk file and build the internal cache.
2985            // The usage file is expected to be small so loading and verifying it
2986            // should take a fairly small time compare to the other activities (e.g. package
2987            // scanning).
2988            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2989            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2990            for (int userId : currentUserIds) {
2991                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2992            }
2993            mDexManager.load(userPackages);
2994        } // synchronized (mPackages)
2995        } // synchronized (mInstallLock)
2996
2997        // Now after opening every single application zip, make sure they
2998        // are all flushed.  Not really needed, but keeps things nice and
2999        // tidy.
3000        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3001        Runtime.getRuntime().gc();
3002        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3003
3004        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3005        FallbackCategoryProvider.loadFallbacks();
3006        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3007
3008        // The initial scanning above does many calls into installd while
3009        // holding the mPackages lock, but we're mostly interested in yelling
3010        // once we have a booted system.
3011        mInstaller.setWarnIfHeld(mPackages);
3012
3013        // Expose private service for system components to use.
3014        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3015        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3016    }
3017
3018    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3019        // we're only interested in updating the installer appliction when 1) it's not
3020        // already set or 2) the modified package is the installer
3021        if (mInstantAppInstallerActivity != null
3022                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3023                        .equals(modifiedPackage)) {
3024            return;
3025        }
3026        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3027    }
3028
3029    private static File preparePackageParserCache(boolean isUpgrade) {
3030        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3031            return null;
3032        }
3033
3034        // Disable package parsing on eng builds to allow for faster incremental development.
3035        if ("eng".equals(Build.TYPE)) {
3036            return null;
3037        }
3038
3039        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3040            Slog.i(TAG, "Disabling package parser cache due to system property.");
3041            return null;
3042        }
3043
3044        // The base directory for the package parser cache lives under /data/system/.
3045        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3046                "package_cache");
3047        if (cacheBaseDir == null) {
3048            return null;
3049        }
3050
3051        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3052        // This also serves to "GC" unused entries when the package cache version changes (which
3053        // can only happen during upgrades).
3054        if (isUpgrade) {
3055            FileUtils.deleteContents(cacheBaseDir);
3056        }
3057
3058
3059        // Return the versioned package cache directory. This is something like
3060        // "/data/system/package_cache/1"
3061        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3062
3063        // The following is a workaround to aid development on non-numbered userdebug
3064        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3065        // the system partition is newer.
3066        //
3067        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3068        // that starts with "eng." to signify that this is an engineering build and not
3069        // destined for release.
3070        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3071            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3072
3073            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3074            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3075            // in general and should not be used for production changes. In this specific case,
3076            // we know that they will work.
3077            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3078            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3079                FileUtils.deleteContents(cacheBaseDir);
3080                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3081            }
3082        }
3083
3084        return cacheDir;
3085    }
3086
3087    @Override
3088    public boolean isFirstBoot() {
3089        return mFirstBoot;
3090    }
3091
3092    @Override
3093    public boolean isOnlyCoreApps() {
3094        return mOnlyCore;
3095    }
3096
3097    @Override
3098    public boolean isUpgrade() {
3099        return mIsUpgrade;
3100    }
3101
3102    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3103        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3104
3105        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3106                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3107                UserHandle.USER_SYSTEM);
3108        if (matches.size() == 1) {
3109            return matches.get(0).getComponentInfo().packageName;
3110        } else if (matches.size() == 0) {
3111            Log.e(TAG, "There should probably be a verifier, but, none were found");
3112            return null;
3113        }
3114        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3115    }
3116
3117    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3118        synchronized (mPackages) {
3119            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3120            if (libraryEntry == null) {
3121                throw new IllegalStateException("Missing required shared library:" + name);
3122            }
3123            return libraryEntry.apk;
3124        }
3125    }
3126
3127    private @NonNull String getRequiredInstallerLPr() {
3128        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3129        intent.addCategory(Intent.CATEGORY_DEFAULT);
3130        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3131
3132        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3133                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3134                UserHandle.USER_SYSTEM);
3135        if (matches.size() == 1) {
3136            ResolveInfo resolveInfo = matches.get(0);
3137            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3138                throw new RuntimeException("The installer must be a privileged app");
3139            }
3140            return matches.get(0).getComponentInfo().packageName;
3141        } else {
3142            throw new RuntimeException("There must be exactly one installer; found " + matches);
3143        }
3144    }
3145
3146    private @NonNull String getRequiredUninstallerLPr() {
3147        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3148        intent.addCategory(Intent.CATEGORY_DEFAULT);
3149        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3150
3151        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3152                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3153                UserHandle.USER_SYSTEM);
3154        if (resolveInfo == null ||
3155                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3156            throw new RuntimeException("There must be exactly one uninstaller; found "
3157                    + resolveInfo);
3158        }
3159        return resolveInfo.getComponentInfo().packageName;
3160    }
3161
3162    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3163        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3164
3165        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3166                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3167                UserHandle.USER_SYSTEM);
3168        ResolveInfo best = null;
3169        final int N = matches.size();
3170        for (int i = 0; i < N; i++) {
3171            final ResolveInfo cur = matches.get(i);
3172            final String packageName = cur.getComponentInfo().packageName;
3173            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3174                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3175                continue;
3176            }
3177
3178            if (best == null || cur.priority > best.priority) {
3179                best = cur;
3180            }
3181        }
3182
3183        if (best != null) {
3184            return best.getComponentInfo().getComponentName();
3185        }
3186        Slog.w(TAG, "Intent filter verifier not found");
3187        return null;
3188    }
3189
3190    @Override
3191    public @Nullable ComponentName getInstantAppResolverComponent() {
3192        synchronized (mPackages) {
3193            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3194            if (instantAppResolver == null) {
3195                return null;
3196            }
3197            return instantAppResolver.first;
3198        }
3199    }
3200
3201    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3202        final String[] packageArray =
3203                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3204        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3205            if (DEBUG_EPHEMERAL) {
3206                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3207            }
3208            return null;
3209        }
3210
3211        final int callingUid = Binder.getCallingUid();
3212        final int resolveFlags =
3213                MATCH_DIRECT_BOOT_AWARE
3214                | MATCH_DIRECT_BOOT_UNAWARE
3215                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3216        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3217        final Intent resolverIntent = new Intent(actionName);
3218        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3219                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3220        // temporarily look for the old action
3221        if (resolvers.size() == 0) {
3222            if (DEBUG_EPHEMERAL) {
3223                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3224            }
3225            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3226            resolverIntent.setAction(actionName);
3227            resolvers = queryIntentServicesInternal(resolverIntent, null,
3228                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3229        }
3230        final int N = resolvers.size();
3231        if (N == 0) {
3232            if (DEBUG_EPHEMERAL) {
3233                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3234            }
3235            return null;
3236        }
3237
3238        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3239        for (int i = 0; i < N; i++) {
3240            final ResolveInfo info = resolvers.get(i);
3241
3242            if (info.serviceInfo == null) {
3243                continue;
3244            }
3245
3246            final String packageName = info.serviceInfo.packageName;
3247            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3248                if (DEBUG_EPHEMERAL) {
3249                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3250                            + " pkg: " + packageName + ", info:" + info);
3251                }
3252                continue;
3253            }
3254
3255            if (DEBUG_EPHEMERAL) {
3256                Slog.v(TAG, "Ephemeral resolver found;"
3257                        + " pkg: " + packageName + ", info:" + info);
3258            }
3259            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3260        }
3261        if (DEBUG_EPHEMERAL) {
3262            Slog.v(TAG, "Ephemeral resolver NOT found");
3263        }
3264        return null;
3265    }
3266
3267    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3268        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3269        intent.addCategory(Intent.CATEGORY_DEFAULT);
3270        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3271
3272        final int resolveFlags =
3273                MATCH_DIRECT_BOOT_AWARE
3274                | MATCH_DIRECT_BOOT_UNAWARE
3275                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3276        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3277                resolveFlags, UserHandle.USER_SYSTEM);
3278        // temporarily look for the old action
3279        if (matches.isEmpty()) {
3280            if (DEBUG_EPHEMERAL) {
3281                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3282            }
3283            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3284            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3285                    resolveFlags, UserHandle.USER_SYSTEM);
3286        }
3287        Iterator<ResolveInfo> iter = matches.iterator();
3288        while (iter.hasNext()) {
3289            final ResolveInfo rInfo = iter.next();
3290            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3291            if (ps != null) {
3292                final PermissionsState permissionsState = ps.getPermissionsState();
3293                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3294                    continue;
3295                }
3296            }
3297            iter.remove();
3298        }
3299        if (matches.size() == 0) {
3300            return null;
3301        } else if (matches.size() == 1) {
3302            return (ActivityInfo) matches.get(0).getComponentInfo();
3303        } else {
3304            throw new RuntimeException(
3305                    "There must be at most one ephemeral installer; found " + matches);
3306        }
3307    }
3308
3309    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3310            @NonNull ComponentName resolver) {
3311        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3312                .addCategory(Intent.CATEGORY_DEFAULT)
3313                .setPackage(resolver.getPackageName());
3314        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3315        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3316                UserHandle.USER_SYSTEM);
3317        // temporarily look for the old action
3318        if (matches.isEmpty()) {
3319            if (DEBUG_EPHEMERAL) {
3320                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3321            }
3322            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3323            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3324                    UserHandle.USER_SYSTEM);
3325        }
3326        if (matches.isEmpty()) {
3327            return null;
3328        }
3329        return matches.get(0).getComponentInfo().getComponentName();
3330    }
3331
3332    private void primeDomainVerificationsLPw(int userId) {
3333        if (DEBUG_DOMAIN_VERIFICATION) {
3334            Slog.d(TAG, "Priming domain verifications in user " + userId);
3335        }
3336
3337        SystemConfig systemConfig = SystemConfig.getInstance();
3338        ArraySet<String> packages = systemConfig.getLinkedApps();
3339
3340        for (String packageName : packages) {
3341            PackageParser.Package pkg = mPackages.get(packageName);
3342            if (pkg != null) {
3343                if (!pkg.isSystemApp()) {
3344                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3345                    continue;
3346                }
3347
3348                ArraySet<String> domains = null;
3349                for (PackageParser.Activity a : pkg.activities) {
3350                    for (ActivityIntentInfo filter : a.intents) {
3351                        if (hasValidDomains(filter)) {
3352                            if (domains == null) {
3353                                domains = new ArraySet<String>();
3354                            }
3355                            domains.addAll(filter.getHostsList());
3356                        }
3357                    }
3358                }
3359
3360                if (domains != null && domains.size() > 0) {
3361                    if (DEBUG_DOMAIN_VERIFICATION) {
3362                        Slog.v(TAG, "      + " + packageName);
3363                    }
3364                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3365                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3366                    // and then 'always' in the per-user state actually used for intent resolution.
3367                    final IntentFilterVerificationInfo ivi;
3368                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3369                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3370                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3371                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3372                } else {
3373                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3374                            + "' does not handle web links");
3375                }
3376            } else {
3377                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3378            }
3379        }
3380
3381        scheduleWritePackageRestrictionsLocked(userId);
3382        scheduleWriteSettingsLocked();
3383    }
3384
3385    private void applyFactoryDefaultBrowserLPw(int userId) {
3386        // The default browser app's package name is stored in a string resource,
3387        // with a product-specific overlay used for vendor customization.
3388        String browserPkg = mContext.getResources().getString(
3389                com.android.internal.R.string.default_browser);
3390        if (!TextUtils.isEmpty(browserPkg)) {
3391            // non-empty string => required to be a known package
3392            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3393            if (ps == null) {
3394                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3395                browserPkg = null;
3396            } else {
3397                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3398            }
3399        }
3400
3401        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3402        // default.  If there's more than one, just leave everything alone.
3403        if (browserPkg == null) {
3404            calculateDefaultBrowserLPw(userId);
3405        }
3406    }
3407
3408    private void calculateDefaultBrowserLPw(int userId) {
3409        List<String> allBrowsers = resolveAllBrowserApps(userId);
3410        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3411        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3412    }
3413
3414    private List<String> resolveAllBrowserApps(int userId) {
3415        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3416        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3417                PackageManager.MATCH_ALL, userId);
3418
3419        final int count = list.size();
3420        List<String> result = new ArrayList<String>(count);
3421        for (int i=0; i<count; i++) {
3422            ResolveInfo info = list.get(i);
3423            if (info.activityInfo == null
3424                    || !info.handleAllWebDataURI
3425                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3426                    || result.contains(info.activityInfo.packageName)) {
3427                continue;
3428            }
3429            result.add(info.activityInfo.packageName);
3430        }
3431
3432        return result;
3433    }
3434
3435    private boolean packageIsBrowser(String packageName, int userId) {
3436        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3437                PackageManager.MATCH_ALL, userId);
3438        final int N = list.size();
3439        for (int i = 0; i < N; i++) {
3440            ResolveInfo info = list.get(i);
3441            if (packageName.equals(info.activityInfo.packageName)) {
3442                return true;
3443            }
3444        }
3445        return false;
3446    }
3447
3448    private void checkDefaultBrowser() {
3449        final int myUserId = UserHandle.myUserId();
3450        final String packageName = getDefaultBrowserPackageName(myUserId);
3451        if (packageName != null) {
3452            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3453            if (info == null) {
3454                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3455                synchronized (mPackages) {
3456                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3457                }
3458            }
3459        }
3460    }
3461
3462    @Override
3463    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3464            throws RemoteException {
3465        try {
3466            return super.onTransact(code, data, reply, flags);
3467        } catch (RuntimeException e) {
3468            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3469                Slog.wtf(TAG, "Package Manager Crash", e);
3470            }
3471            throw e;
3472        }
3473    }
3474
3475    static int[] appendInts(int[] cur, int[] add) {
3476        if (add == null) return cur;
3477        if (cur == null) return add;
3478        final int N = add.length;
3479        for (int i=0; i<N; i++) {
3480            cur = appendInt(cur, add[i]);
3481        }
3482        return cur;
3483    }
3484
3485    /**
3486     * Returns whether or not a full application can see an instant application.
3487     * <p>
3488     * Currently, there are three cases in which this can occur:
3489     * <ol>
3490     * <li>The calling application is a "special" process. The special
3491     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3492     *     and {@code 0}</li>
3493     * <li>The calling application has the permission
3494     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3495     * <li>[TODO] The calling application is the default launcher on the
3496     *     system partition.</li>
3497     * </ol>
3498     */
3499    private boolean canAccessInstantApps(int callingUid) {
3500        final boolean isSpecialProcess =
3501                callingUid == Process.SYSTEM_UID
3502                        || callingUid == Process.SHELL_UID
3503                        || callingUid == 0;
3504        final boolean allowMatchInstant =
3505                isSpecialProcess
3506                        || mContext.checkCallingOrSelfPermission(
3507                        android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
3508        return allowMatchInstant;
3509    }
3510    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3511        if (!sUserManager.exists(userId)) return null;
3512        if (ps == null) {
3513            return null;
3514        }
3515        PackageParser.Package p = ps.pkg;
3516        if (p == null) {
3517            return null;
3518        }
3519        final int callingUid =  Binder.getCallingUid();
3520        // Filter out ephemeral app metadata:
3521        //   * The system/shell/root can see metadata for any app
3522        //   * An installed app can see metadata for 1) other installed apps
3523        //     and 2) ephemeral apps that have explicitly interacted with it
3524        //   * Ephemeral apps can only see their own data and exposed installed apps
3525        //   * Holding a signature permission allows seeing instant apps
3526        if (!canAccessInstantApps(callingUid)) {
3527            final String instantAppPackageName = getInstantAppPackageName(callingUid);
3528            if (instantAppPackageName != null) {
3529                // ephemeral apps can only get information on themselves or
3530                // installed apps that are exposed.
3531                if (!instantAppPackageName.equals(p.packageName)
3532                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3533                    return null;
3534                }
3535            } else {
3536                if (ps.getInstantApp(userId)) {
3537                    // only get access to the ephemeral app if we've been granted access
3538                    final int callingAppId = UserHandle.getAppId(callingUid);
3539                    if (!mInstantAppRegistry.isInstantAccessGranted(
3540                            userId, callingAppId, ps.appId)) {
3541                        return null;
3542                    }
3543                }
3544            }
3545        }
3546
3547        final PermissionsState permissionsState = ps.getPermissionsState();
3548
3549        // Compute GIDs only if requested
3550        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3551                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3552        // Compute granted permissions only if package has requested permissions
3553        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3554                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3555        final PackageUserState state = ps.readUserState(userId);
3556
3557        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3558                && ps.isSystem()) {
3559            flags |= MATCH_ANY_USER;
3560        }
3561
3562        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3563                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3564
3565        if (packageInfo == null) {
3566            return null;
3567        }
3568
3569        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3570
3571        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3572                resolveExternalPackageNameLPr(p);
3573
3574        return packageInfo;
3575    }
3576
3577    @Override
3578    public void checkPackageStartable(String packageName, int userId) {
3579        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3580
3581        synchronized (mPackages) {
3582            final PackageSetting ps = mSettings.mPackages.get(packageName);
3583            if (ps == null) {
3584                throw new SecurityException("Package " + packageName + " was not found!");
3585            }
3586
3587            if (!ps.getInstalled(userId)) {
3588                throw new SecurityException(
3589                        "Package " + packageName + " was not installed for user " + userId + "!");
3590            }
3591
3592            if (mSafeMode && !ps.isSystem()) {
3593                throw new SecurityException("Package " + packageName + " not a system app!");
3594            }
3595
3596            if (mFrozenPackages.contains(packageName)) {
3597                throw new SecurityException("Package " + packageName + " is currently frozen!");
3598            }
3599
3600            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3601                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3602                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3603            }
3604        }
3605    }
3606
3607    @Override
3608    public boolean isPackageAvailable(String packageName, int userId) {
3609        if (!sUserManager.exists(userId)) return false;
3610        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3611                false /* requireFullPermission */, false /* checkShell */, "is package available");
3612        synchronized (mPackages) {
3613            PackageParser.Package p = mPackages.get(packageName);
3614            if (p != null) {
3615                final PackageSetting ps = (PackageSetting) p.mExtras;
3616                if (ps != null) {
3617                    final PackageUserState state = ps.readUserState(userId);
3618                    if (state != null) {
3619                        return PackageParser.isAvailable(state);
3620                    }
3621                }
3622            }
3623        }
3624        return false;
3625    }
3626
3627    @Override
3628    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3629        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3630                flags, userId);
3631    }
3632
3633    @Override
3634    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3635            int flags, int userId) {
3636        return getPackageInfoInternal(versionedPackage.getPackageName(),
3637                versionedPackage.getVersionCode(), flags, userId);
3638    }
3639
3640    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3641            int flags, int userId) {
3642        if (!sUserManager.exists(userId)) return null;
3643        final int callingUid = Binder.getCallingUid();
3644        flags = updateFlagsForPackage(flags, userId, packageName);
3645        enforceCrossUserPermission(callingUid, userId,
3646                false /* requireFullPermission */, false /* checkShell */, "get package info");
3647
3648        // reader
3649        synchronized (mPackages) {
3650            // Normalize package name to handle renamed packages and static libs
3651            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3652
3653            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3654            if (matchFactoryOnly) {
3655                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3656                if (ps != null) {
3657                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3658                        return null;
3659                    }
3660                    if (filterAppAccessLPr(ps, callingUid, userId)) {
3661                        return null;
3662                    }
3663                    return generatePackageInfo(ps, flags, userId);
3664                }
3665            }
3666
3667            PackageParser.Package p = mPackages.get(packageName);
3668            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3669                return null;
3670            }
3671            if (DEBUG_PACKAGE_INFO)
3672                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3673            if (p != null) {
3674                final PackageSetting ps = (PackageSetting) p.mExtras;
3675                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3676                    return null;
3677                }
3678                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
3679                    return null;
3680                }
3681                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3682            }
3683            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3684                final PackageSetting ps = mSettings.mPackages.get(packageName);
3685                if (ps == null) return null;
3686                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3687                    return null;
3688                }
3689                if (filterAppAccessLPr(ps, callingUid, userId)) {
3690                    return null;
3691                }
3692                return generatePackageInfo(ps, flags, userId);
3693            }
3694        }
3695        return null;
3696    }
3697
3698    /**
3699     * Returns whether or not access to the application should be filtered.
3700     * <p>
3701     * Access may be limited based upon whether the calling or target applications
3702     * are instant applications.
3703     *
3704     * @see #canAccessInstantApps(int)
3705     */
3706    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid,
3707            @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) {
3708        // if we're in an isolated process, get the real calling UID
3709        if (Process.isIsolated(callingUid)) {
3710            callingUid = mIsolatedOwners.get(callingUid);
3711        }
3712        // if the target and caller are the same application, don't filter
3713        if (isCallerSameApp(ps.name, callingUid)) {
3714            return false;
3715        }
3716        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3717        final boolean callerIsInstantApp = instantAppPkgName != null;
3718        if (callerIsInstantApp) {
3719            // request for a specific component; if it hasn't been explicitly exposed, filter
3720            if (component != null) {
3721                return !componentVisibleToInstantApp;
3722            }
3723            // request for application; if no components have been explicitly exposed, filter
3724            return !ps.pkg.visibleToInstantApps;
3725        }
3726        if (ps.getInstantApp(userId)) {
3727            // caller can see all components of all instant applications, don't filter
3728            if (canAccessInstantApps(callingUid)) {
3729                return false;
3730            }
3731            // request for a specific instant application component, filter
3732            if (component != null) {
3733                return true;
3734            }
3735            // request for an instant application; if the caller hasn't been granted access, filter
3736            return !mInstantAppRegistry.isInstantAccessGranted(
3737                    userId, UserHandle.getAppId(callingUid), ps.appId);
3738        }
3739        return false;
3740    }
3741
3742    /**
3743     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
3744     */
3745    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid, int userId) {
3746        return filterAppAccessLPr(ps, callingUid, null, false, userId);
3747    }
3748
3749    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
3750            int flags) {
3751        // Callers can access only the libs they depend on, otherwise they need to explicitly
3752        // ask for the shared libraries given the caller is allowed to access all static libs.
3753        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3754            // System/shell/root get to see all static libs
3755            final int appId = UserHandle.getAppId(uid);
3756            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3757                    || appId == Process.ROOT_UID) {
3758                return false;
3759            }
3760        }
3761
3762        // No package means no static lib as it is always on internal storage
3763        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3764            return false;
3765        }
3766
3767        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3768                ps.pkg.staticSharedLibVersion);
3769        if (libEntry == null) {
3770            return false;
3771        }
3772
3773        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3774        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3775        if (uidPackageNames == null) {
3776            return true;
3777        }
3778
3779        for (String uidPackageName : uidPackageNames) {
3780            if (ps.name.equals(uidPackageName)) {
3781                return false;
3782            }
3783            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3784            if (uidPs != null) {
3785                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3786                        libEntry.info.getName());
3787                if (index < 0) {
3788                    continue;
3789                }
3790                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3791                    return false;
3792                }
3793            }
3794        }
3795        return true;
3796    }
3797
3798    @Override
3799    public String[] currentToCanonicalPackageNames(String[] names) {
3800        String[] out = new String[names.length];
3801        // reader
3802        synchronized (mPackages) {
3803            for (int i=names.length-1; i>=0; i--) {
3804                PackageSetting ps = mSettings.mPackages.get(names[i]);
3805                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3806            }
3807        }
3808        return out;
3809    }
3810
3811    @Override
3812    public String[] canonicalToCurrentPackageNames(String[] names) {
3813        String[] out = new String[names.length];
3814        // reader
3815        synchronized (mPackages) {
3816            for (int i=names.length-1; i>=0; i--) {
3817                String cur = mSettings.getRenamedPackageLPr(names[i]);
3818                out[i] = cur != null ? cur : names[i];
3819            }
3820        }
3821        return out;
3822    }
3823
3824    @Override
3825    public int getPackageUid(String packageName, int flags, int userId) {
3826        if (!sUserManager.exists(userId)) return -1;
3827        flags = updateFlagsForPackage(flags, userId, packageName);
3828        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3829                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3830
3831        // reader
3832        synchronized (mPackages) {
3833            final PackageParser.Package p = mPackages.get(packageName);
3834            if (p != null && p.isMatch(flags)) {
3835                return UserHandle.getUid(userId, p.applicationInfo.uid);
3836            }
3837            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3838                final PackageSetting ps = mSettings.mPackages.get(packageName);
3839                if (ps != null && ps.isMatch(flags)) {
3840                    return UserHandle.getUid(userId, ps.appId);
3841                }
3842            }
3843        }
3844
3845        return -1;
3846    }
3847
3848    @Override
3849    public int[] getPackageGids(String packageName, int flags, int userId) {
3850        if (!sUserManager.exists(userId)) return null;
3851        flags = updateFlagsForPackage(flags, userId, packageName);
3852        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3853                false /* requireFullPermission */, false /* checkShell */,
3854                "getPackageGids");
3855
3856        // reader
3857        synchronized (mPackages) {
3858            final PackageParser.Package p = mPackages.get(packageName);
3859            if (p != null && p.isMatch(flags)) {
3860                PackageSetting ps = (PackageSetting) p.mExtras;
3861                // TODO: Shouldn't this be checking for package installed state for userId and
3862                // return null?
3863                return ps.getPermissionsState().computeGids(userId);
3864            }
3865            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3866                final PackageSetting ps = mSettings.mPackages.get(packageName);
3867                if (ps != null && ps.isMatch(flags)) {
3868                    return ps.getPermissionsState().computeGids(userId);
3869                }
3870            }
3871        }
3872
3873        return null;
3874    }
3875
3876    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3877        if (bp.perm != null) {
3878            return PackageParser.generatePermissionInfo(bp.perm, flags);
3879        }
3880        PermissionInfo pi = new PermissionInfo();
3881        pi.name = bp.name;
3882        pi.packageName = bp.sourcePackage;
3883        pi.nonLocalizedLabel = bp.name;
3884        pi.protectionLevel = bp.protectionLevel;
3885        return pi;
3886    }
3887
3888    @Override
3889    public PermissionInfo getPermissionInfo(String name, int flags) {
3890        // reader
3891        synchronized (mPackages) {
3892            final BasePermission p = mSettings.mPermissions.get(name);
3893            if (p != null) {
3894                return generatePermissionInfo(p, flags);
3895            }
3896            return null;
3897        }
3898    }
3899
3900    @Override
3901    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3902            int flags) {
3903        // reader
3904        synchronized (mPackages) {
3905            if (group != null && !mPermissionGroups.containsKey(group)) {
3906                // This is thrown as NameNotFoundException
3907                return null;
3908            }
3909
3910            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3911            for (BasePermission p : mSettings.mPermissions.values()) {
3912                if (group == null) {
3913                    if (p.perm == null || p.perm.info.group == null) {
3914                        out.add(generatePermissionInfo(p, flags));
3915                    }
3916                } else {
3917                    if (p.perm != null && group.equals(p.perm.info.group)) {
3918                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3919                    }
3920                }
3921            }
3922            return new ParceledListSlice<>(out);
3923        }
3924    }
3925
3926    @Override
3927    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3928        // reader
3929        synchronized (mPackages) {
3930            return PackageParser.generatePermissionGroupInfo(
3931                    mPermissionGroups.get(name), flags);
3932        }
3933    }
3934
3935    @Override
3936    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3937        // reader
3938        synchronized (mPackages) {
3939            final int N = mPermissionGroups.size();
3940            ArrayList<PermissionGroupInfo> out
3941                    = new ArrayList<PermissionGroupInfo>(N);
3942            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3943                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3944            }
3945            return new ParceledListSlice<>(out);
3946        }
3947    }
3948
3949    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3950            int uid, int userId) {
3951        if (!sUserManager.exists(userId)) return null;
3952        PackageSetting ps = mSettings.mPackages.get(packageName);
3953        if (ps != null) {
3954            if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
3955                return null;
3956            }
3957            if (filterAppAccessLPr(ps, uid, userId)) {
3958                return null;
3959            }
3960            if (ps.pkg == null) {
3961                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3962                if (pInfo != null) {
3963                    return pInfo.applicationInfo;
3964                }
3965                return null;
3966            }
3967            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3968                    ps.readUserState(userId), userId);
3969            if (ai != null) {
3970                rebaseEnabledOverlays(ai, userId);
3971                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3972            }
3973            return ai;
3974        }
3975        return null;
3976    }
3977
3978    @Override
3979    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3980        if (!sUserManager.exists(userId)) return null;
3981        flags = updateFlagsForApplication(flags, userId, packageName);
3982        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3983                false /* requireFullPermission */, false /* checkShell */, "get application info");
3984
3985        // writer
3986        synchronized (mPackages) {
3987            // Normalize package name to handle renamed packages and static libs
3988            packageName = resolveInternalPackageNameLPr(packageName,
3989                    PackageManager.VERSION_CODE_HIGHEST);
3990
3991            PackageParser.Package p = mPackages.get(packageName);
3992            if (DEBUG_PACKAGE_INFO) Log.v(
3993                    TAG, "getApplicationInfo " + packageName
3994                    + ": " + p);
3995            if (p != null) {
3996                PackageSetting ps = mSettings.mPackages.get(packageName);
3997                if (ps == null) return null;
3998                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
3999                    return null;
4000                }
4001                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
4002                    return null;
4003                }
4004                // Note: isEnabledLP() does not apply here - always return info
4005                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4006                        p, flags, ps.readUserState(userId), userId);
4007                if (ai != null) {
4008                    rebaseEnabledOverlays(ai, userId);
4009                    ai.packageName = resolveExternalPackageNameLPr(p);
4010                }
4011                return ai;
4012            }
4013            if ("android".equals(packageName)||"system".equals(packageName)) {
4014                return mAndroidApplication;
4015            }
4016            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4017                // Already generates the external package name
4018                return generateApplicationInfoFromSettingsLPw(packageName,
4019                        Binder.getCallingUid(), flags, userId);
4020            }
4021        }
4022        return null;
4023    }
4024
4025    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
4026        List<String> paths = new ArrayList<>();
4027        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
4028            mEnabledOverlayPaths.get(userId);
4029        if (userSpecificOverlays != null) {
4030            if (!"android".equals(ai.packageName)) {
4031                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
4032                if (frameworkOverlays != null) {
4033                    paths.addAll(frameworkOverlays);
4034                }
4035            }
4036
4037            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
4038            if (appOverlays != null) {
4039                paths.addAll(appOverlays);
4040            }
4041        }
4042        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
4043    }
4044
4045    private String normalizePackageNameLPr(String packageName) {
4046        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4047        return normalizedPackageName != null ? normalizedPackageName : packageName;
4048    }
4049
4050    @Override
4051    public void deletePreloadsFileCache() {
4052        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4053            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4054        }
4055        File dir = Environment.getDataPreloadsFileCacheDirectory();
4056        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4057        FileUtils.deleteContents(dir);
4058    }
4059
4060    @Override
4061    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4062            final IPackageDataObserver observer) {
4063        mContext.enforceCallingOrSelfPermission(
4064                android.Manifest.permission.CLEAR_APP_CACHE, null);
4065        mHandler.post(() -> {
4066            boolean success = false;
4067            try {
4068                freeStorage(volumeUuid, freeStorageSize, 0);
4069                success = true;
4070            } catch (IOException e) {
4071                Slog.w(TAG, e);
4072            }
4073            if (observer != null) {
4074                try {
4075                    observer.onRemoveCompleted(null, success);
4076                } catch (RemoteException e) {
4077                    Slog.w(TAG, e);
4078                }
4079            }
4080        });
4081    }
4082
4083    @Override
4084    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4085            final IntentSender pi) {
4086        mContext.enforceCallingOrSelfPermission(
4087                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4088        mHandler.post(() -> {
4089            boolean success = false;
4090            try {
4091                freeStorage(volumeUuid, freeStorageSize, 0);
4092                success = true;
4093            } catch (IOException e) {
4094                Slog.w(TAG, e);
4095            }
4096            if (pi != null) {
4097                try {
4098                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4099                } catch (SendIntentException e) {
4100                    Slog.w(TAG, e);
4101                }
4102            }
4103        });
4104    }
4105
4106    /**
4107     * Blocking call to clear various types of cached data across the system
4108     * until the requested bytes are available.
4109     */
4110    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4111        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4112        final File file = storage.findPathForUuid(volumeUuid);
4113        if (file.getUsableSpace() >= bytes) return;
4114
4115        if (ENABLE_FREE_CACHE_V2) {
4116            final boolean aggressive = (storageFlags
4117                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4118            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4119                    volumeUuid);
4120
4121            // 1. Pre-flight to determine if we have any chance to succeed
4122            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4123            if (internalVolume && (aggressive || SystemProperties
4124                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4125                deletePreloadsFileCache();
4126                if (file.getUsableSpace() >= bytes) return;
4127            }
4128
4129            // 3. Consider parsed APK data (aggressive only)
4130            if (internalVolume && aggressive) {
4131                FileUtils.deleteContents(mCacheDir);
4132                if (file.getUsableSpace() >= bytes) return;
4133            }
4134
4135            // 4. Consider cached app data (above quotas)
4136            try {
4137                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
4138            } catch (InstallerException ignored) {
4139            }
4140            if (file.getUsableSpace() >= bytes) return;
4141
4142            // 5. Consider shared libraries with refcount=0 and age>2h
4143            // 6. Consider dexopt output (aggressive only)
4144            // 7. Consider ephemeral apps not used in last week
4145
4146            // 8. Consider cached app data (below quotas)
4147            try {
4148                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
4149                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4150            } catch (InstallerException ignored) {
4151            }
4152            if (file.getUsableSpace() >= bytes) return;
4153
4154            // 9. Consider DropBox entries
4155            // 10. Consider ephemeral cookies
4156
4157        } else {
4158            try {
4159                mInstaller.freeCache(volumeUuid, bytes, 0);
4160            } catch (InstallerException ignored) {
4161            }
4162            if (file.getUsableSpace() >= bytes) return;
4163        }
4164
4165        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4166    }
4167
4168    /**
4169     * Update given flags based on encryption status of current user.
4170     */
4171    private int updateFlags(int flags, int userId) {
4172        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4173                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4174            // Caller expressed an explicit opinion about what encryption
4175            // aware/unaware components they want to see, so fall through and
4176            // give them what they want
4177        } else {
4178            // Caller expressed no opinion, so match based on user state
4179            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4180                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4181            } else {
4182                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4183            }
4184        }
4185        return flags;
4186    }
4187
4188    private UserManagerInternal getUserManagerInternal() {
4189        if (mUserManagerInternal == null) {
4190            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4191        }
4192        return mUserManagerInternal;
4193    }
4194
4195    private DeviceIdleController.LocalService getDeviceIdleController() {
4196        if (mDeviceIdleController == null) {
4197            mDeviceIdleController =
4198                    LocalServices.getService(DeviceIdleController.LocalService.class);
4199        }
4200        return mDeviceIdleController;
4201    }
4202
4203    /**
4204     * Update given flags when being used to request {@link PackageInfo}.
4205     */
4206    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4207        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4208        boolean triaged = true;
4209        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4210                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4211            // Caller is asking for component details, so they'd better be
4212            // asking for specific encryption matching behavior, or be triaged
4213            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4214                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4215                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4216                triaged = false;
4217            }
4218        }
4219        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4220                | PackageManager.MATCH_SYSTEM_ONLY
4221                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4222            triaged = false;
4223        }
4224        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4225            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4226                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4227                    + Debug.getCallers(5));
4228        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4229                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4230            // If the caller wants all packages and has a restricted profile associated with it,
4231            // then match all users. This is to make sure that launchers that need to access work
4232            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4233            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4234            flags |= PackageManager.MATCH_ANY_USER;
4235        }
4236        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4237            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4238                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4239        }
4240        return updateFlags(flags, userId);
4241    }
4242
4243    /**
4244     * Update given flags when being used to request {@link ApplicationInfo}.
4245     */
4246    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4247        return updateFlagsForPackage(flags, userId, cookie);
4248    }
4249
4250    /**
4251     * Update given flags when being used to request {@link ComponentInfo}.
4252     */
4253    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4254        if (cookie instanceof Intent) {
4255            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4256                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4257            }
4258        }
4259
4260        boolean triaged = true;
4261        // Caller is asking for component details, so they'd better be
4262        // asking for specific encryption matching behavior, or be triaged
4263        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4264                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4265                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4266            triaged = false;
4267        }
4268        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4269            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4270                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4271        }
4272
4273        return updateFlags(flags, userId);
4274    }
4275
4276    /**
4277     * Update given intent when being used to request {@link ResolveInfo}.
4278     */
4279    private Intent updateIntentForResolve(Intent intent) {
4280        if (intent.getSelector() != null) {
4281            intent = intent.getSelector();
4282        }
4283        if (DEBUG_PREFERRED) {
4284            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4285        }
4286        return intent;
4287    }
4288
4289    /**
4290     * Update given flags when being used to request {@link ResolveInfo}.
4291     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4292     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4293     * flag set. However, this flag is only honoured in three circumstances:
4294     * <ul>
4295     * <li>when called from a system process</li>
4296     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4297     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4298     * action and a {@code android.intent.category.BROWSABLE} category</li>
4299     * </ul>
4300     */
4301    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4302        return updateFlagsForResolve(flags, userId, intent, callingUid,
4303                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4304    }
4305    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4306            boolean wantInstantApps) {
4307        return updateFlagsForResolve(flags, userId, intent, callingUid,
4308                wantInstantApps, false /*onlyExposedExplicitly*/);
4309    }
4310    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4311            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4312        // Safe mode means we shouldn't match any third-party components
4313        if (mSafeMode) {
4314            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4315        }
4316        if (getInstantAppPackageName(callingUid) != null) {
4317            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4318            if (onlyExposedExplicitly) {
4319                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4320            }
4321            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4322            flags |= PackageManager.MATCH_INSTANT;
4323        } else {
4324            final boolean allowMatchInstant =
4325                    (wantInstantApps
4326                            && Intent.ACTION_VIEW.equals(intent.getAction())
4327                            && hasWebURI(intent))
4328                    || canAccessInstantApps(callingUid);
4329            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4330                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4331            if (!allowMatchInstant) {
4332                flags &= ~PackageManager.MATCH_INSTANT;
4333            }
4334        }
4335        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4336    }
4337
4338    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4339            int userId) {
4340        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4341        if (ret != null) {
4342            rebaseEnabledOverlays(ret.applicationInfo, userId);
4343        }
4344        return ret;
4345    }
4346
4347    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4348            PackageUserState state, int userId) {
4349        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4350        if (ai != null) {
4351            rebaseEnabledOverlays(ai.applicationInfo, userId);
4352        }
4353        return ai;
4354    }
4355
4356    @Override
4357    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4358        if (!sUserManager.exists(userId)) return null;
4359        final int callingUid = Binder.getCallingUid();
4360        flags = updateFlagsForComponent(flags, userId, component);
4361        enforceCrossUserPermission(callingUid, userId,
4362                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4363        synchronized (mPackages) {
4364            PackageParser.Activity a = mActivities.mActivities.get(component);
4365
4366            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4367            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4368                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4369                if (ps == null) return null;
4370                final boolean visibleToInstantApp =
4371                        (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4372                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4373                    return null;
4374                }
4375                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4376            }
4377            if (mResolveComponentName.equals(component)) {
4378                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4379                        userId);
4380            }
4381        }
4382        return null;
4383    }
4384
4385    @Override
4386    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4387            String resolvedType) {
4388        synchronized (mPackages) {
4389            if (component.equals(mResolveComponentName)) {
4390                // The resolver supports EVERYTHING!
4391                return true;
4392            }
4393            PackageParser.Activity a = mActivities.mActivities.get(component);
4394            if (a == null) {
4395                return false;
4396            }
4397            for (int i=0; i<a.intents.size(); i++) {
4398                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4399                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4400                    return true;
4401                }
4402            }
4403            return false;
4404        }
4405    }
4406
4407    @Override
4408    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4409        if (!sUserManager.exists(userId)) return null;
4410        flags = updateFlagsForComponent(flags, userId, component);
4411        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4412                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4413        synchronized (mPackages) {
4414            PackageParser.Activity a = mReceivers.mActivities.get(component);
4415            if (DEBUG_PACKAGE_INFO) Log.v(
4416                TAG, "getReceiverInfo " + component + ": " + a);
4417            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4418                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4419                if (ps == null) return null;
4420                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4421            }
4422        }
4423        return null;
4424    }
4425
4426    @Override
4427    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4428            int flags, int userId) {
4429        if (!sUserManager.exists(userId)) return null;
4430        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4431
4432        flags = updateFlagsForPackage(flags, userId, null);
4433
4434        final boolean canSeeStaticLibraries =
4435                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4436                        == PERMISSION_GRANTED
4437                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4438                        == PERMISSION_GRANTED
4439                || canRequestPackageInstallsInternal(packageName,
4440                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4441                        false  /* throwIfPermNotDeclared*/)
4442                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4443                        == PERMISSION_GRANTED;
4444
4445        synchronized (mPackages) {
4446            List<SharedLibraryInfo> result = null;
4447
4448            final int libCount = mSharedLibraries.size();
4449            for (int i = 0; i < libCount; i++) {
4450                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4451                if (versionedLib == null) {
4452                    continue;
4453                }
4454
4455                final int versionCount = versionedLib.size();
4456                for (int j = 0; j < versionCount; j++) {
4457                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4458                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4459                        break;
4460                    }
4461                    final long identity = Binder.clearCallingIdentity();
4462                    try {
4463                        PackageInfo packageInfo = getPackageInfoVersioned(
4464                                libInfo.getDeclaringPackage(), flags
4465                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4466                        if (packageInfo == null) {
4467                            continue;
4468                        }
4469                    } finally {
4470                        Binder.restoreCallingIdentity(identity);
4471                    }
4472
4473                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4474                            libInfo.getVersion(), libInfo.getType(),
4475                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4476                            flags, userId));
4477
4478                    if (result == null) {
4479                        result = new ArrayList<>();
4480                    }
4481                    result.add(resLibInfo);
4482                }
4483            }
4484
4485            return result != null ? new ParceledListSlice<>(result) : null;
4486        }
4487    }
4488
4489    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4490            SharedLibraryInfo libInfo, int flags, int userId) {
4491        List<VersionedPackage> versionedPackages = null;
4492        final int packageCount = mSettings.mPackages.size();
4493        for (int i = 0; i < packageCount; i++) {
4494            PackageSetting ps = mSettings.mPackages.valueAt(i);
4495
4496            if (ps == null) {
4497                continue;
4498            }
4499
4500            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4501                continue;
4502            }
4503
4504            final String libName = libInfo.getName();
4505            if (libInfo.isStatic()) {
4506                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4507                if (libIdx < 0) {
4508                    continue;
4509                }
4510                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4511                    continue;
4512                }
4513                if (versionedPackages == null) {
4514                    versionedPackages = new ArrayList<>();
4515                }
4516                // If the dependent is a static shared lib, use the public package name
4517                String dependentPackageName = ps.name;
4518                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4519                    dependentPackageName = ps.pkg.manifestPackageName;
4520                }
4521                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4522            } else if (ps.pkg != null) {
4523                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4524                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4525                    if (versionedPackages == null) {
4526                        versionedPackages = new ArrayList<>();
4527                    }
4528                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4529                }
4530            }
4531        }
4532
4533        return versionedPackages;
4534    }
4535
4536    @Override
4537    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4538        if (!sUserManager.exists(userId)) return null;
4539        final int callingUid = Binder.getCallingUid();
4540        flags = updateFlagsForComponent(flags, userId, component);
4541        enforceCrossUserPermission(callingUid, userId,
4542                false /* requireFullPermission */, false /* checkShell */, "get service info");
4543        synchronized (mPackages) {
4544            PackageParser.Service s = mServices.mServices.get(component);
4545            if (DEBUG_PACKAGE_INFO) Log.v(
4546                TAG, "getServiceInfo " + component + ": " + s);
4547            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4548                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4549                if (ps == null) return null;
4550                final boolean visibleToInstantApp =
4551                        (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4552                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4553                    return null;
4554                }
4555                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4556                        ps.readUserState(userId), userId);
4557                if (si != null) {
4558                    rebaseEnabledOverlays(si.applicationInfo, userId);
4559                }
4560                return si;
4561            }
4562        }
4563        return null;
4564    }
4565
4566    @Override
4567    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4568        if (!sUserManager.exists(userId)) return null;
4569        final int callingUid = Binder.getCallingUid();
4570        flags = updateFlagsForComponent(flags, userId, component);
4571        enforceCrossUserPermission(callingUid, userId,
4572                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4573        synchronized (mPackages) {
4574            PackageParser.Provider p = mProviders.mProviders.get(component);
4575            if (DEBUG_PACKAGE_INFO) Log.v(
4576                TAG, "getProviderInfo " + component + ": " + p);
4577            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4578                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4579                if (ps == null) return null;
4580                final boolean visibleToInstantApp =
4581                        (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4582                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4583                    return null;
4584                }
4585                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4586                        ps.readUserState(userId), userId);
4587                if (pi != null) {
4588                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4589                }
4590                return pi;
4591            }
4592        }
4593        return null;
4594    }
4595
4596    @Override
4597    public String[] getSystemSharedLibraryNames() {
4598        synchronized (mPackages) {
4599            Set<String> libs = null;
4600            final int libCount = mSharedLibraries.size();
4601            for (int i = 0; i < libCount; i++) {
4602                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4603                if (versionedLib == null) {
4604                    continue;
4605                }
4606                final int versionCount = versionedLib.size();
4607                for (int j = 0; j < versionCount; j++) {
4608                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4609                    if (!libEntry.info.isStatic()) {
4610                        if (libs == null) {
4611                            libs = new ArraySet<>();
4612                        }
4613                        libs.add(libEntry.info.getName());
4614                        break;
4615                    }
4616                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4617                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4618                            UserHandle.getUserId(Binder.getCallingUid()),
4619                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4620                        if (libs == null) {
4621                            libs = new ArraySet<>();
4622                        }
4623                        libs.add(libEntry.info.getName());
4624                        break;
4625                    }
4626                }
4627            }
4628
4629            if (libs != null) {
4630                String[] libsArray = new String[libs.size()];
4631                libs.toArray(libsArray);
4632                return libsArray;
4633            }
4634
4635            return null;
4636        }
4637    }
4638
4639    @Override
4640    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4641        synchronized (mPackages) {
4642            return mServicesSystemSharedLibraryPackageName;
4643        }
4644    }
4645
4646    @Override
4647    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4648        synchronized (mPackages) {
4649            return mSharedSystemSharedLibraryPackageName;
4650        }
4651    }
4652
4653    private void updateSequenceNumberLP(String packageName, int[] userList) {
4654        for (int i = userList.length - 1; i >= 0; --i) {
4655            final int userId = userList[i];
4656            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4657            if (changedPackages == null) {
4658                changedPackages = new SparseArray<>();
4659                mChangedPackages.put(userId, changedPackages);
4660            }
4661            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4662            if (sequenceNumbers == null) {
4663                sequenceNumbers = new HashMap<>();
4664                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4665            }
4666            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4667            if (sequenceNumber != null) {
4668                changedPackages.remove(sequenceNumber);
4669            }
4670            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4671            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4672        }
4673        mChangedPackagesSequenceNumber++;
4674    }
4675
4676    @Override
4677    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4678        synchronized (mPackages) {
4679            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4680                return null;
4681            }
4682            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4683            if (changedPackages == null) {
4684                return null;
4685            }
4686            final List<String> packageNames =
4687                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4688            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4689                final String packageName = changedPackages.get(i);
4690                if (packageName != null) {
4691                    packageNames.add(packageName);
4692                }
4693            }
4694            return packageNames.isEmpty()
4695                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4696        }
4697    }
4698
4699    @Override
4700    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4701        ArrayList<FeatureInfo> res;
4702        synchronized (mAvailableFeatures) {
4703            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4704            res.addAll(mAvailableFeatures.values());
4705        }
4706        final FeatureInfo fi = new FeatureInfo();
4707        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4708                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4709        res.add(fi);
4710
4711        return new ParceledListSlice<>(res);
4712    }
4713
4714    @Override
4715    public boolean hasSystemFeature(String name, int version) {
4716        synchronized (mAvailableFeatures) {
4717            final FeatureInfo feat = mAvailableFeatures.get(name);
4718            if (feat == null) {
4719                return false;
4720            } else {
4721                return feat.version >= version;
4722            }
4723        }
4724    }
4725
4726    @Override
4727    public int checkPermission(String permName, String pkgName, int userId) {
4728        if (!sUserManager.exists(userId)) {
4729            return PackageManager.PERMISSION_DENIED;
4730        }
4731
4732        synchronized (mPackages) {
4733            final PackageParser.Package p = mPackages.get(pkgName);
4734            if (p != null && p.mExtras != null) {
4735                final PackageSetting ps = (PackageSetting) p.mExtras;
4736                final PermissionsState permissionsState = ps.getPermissionsState();
4737                if (permissionsState.hasPermission(permName, userId)) {
4738                    return PackageManager.PERMISSION_GRANTED;
4739                }
4740                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4741                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4742                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4743                    return PackageManager.PERMISSION_GRANTED;
4744                }
4745            }
4746        }
4747
4748        return PackageManager.PERMISSION_DENIED;
4749    }
4750
4751    @Override
4752    public int checkUidPermission(String permName, int uid) {
4753        final int userId = UserHandle.getUserId(uid);
4754
4755        if (!sUserManager.exists(userId)) {
4756            return PackageManager.PERMISSION_DENIED;
4757        }
4758
4759        synchronized (mPackages) {
4760            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4761            if (obj != null) {
4762                final SettingBase ps = (SettingBase) obj;
4763                final PermissionsState permissionsState = ps.getPermissionsState();
4764                if (permissionsState.hasPermission(permName, userId)) {
4765                    return PackageManager.PERMISSION_GRANTED;
4766                }
4767                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4768                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4769                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4770                    return PackageManager.PERMISSION_GRANTED;
4771                }
4772            } else {
4773                ArraySet<String> perms = mSystemPermissions.get(uid);
4774                if (perms != null) {
4775                    if (perms.contains(permName)) {
4776                        return PackageManager.PERMISSION_GRANTED;
4777                    }
4778                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4779                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4780                        return PackageManager.PERMISSION_GRANTED;
4781                    }
4782                }
4783            }
4784        }
4785
4786        return PackageManager.PERMISSION_DENIED;
4787    }
4788
4789    @Override
4790    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4791        if (UserHandle.getCallingUserId() != userId) {
4792            mContext.enforceCallingPermission(
4793                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4794                    "isPermissionRevokedByPolicy for user " + userId);
4795        }
4796
4797        if (checkPermission(permission, packageName, userId)
4798                == PackageManager.PERMISSION_GRANTED) {
4799            return false;
4800        }
4801
4802        final long identity = Binder.clearCallingIdentity();
4803        try {
4804            final int flags = getPermissionFlags(permission, packageName, userId);
4805            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4806        } finally {
4807            Binder.restoreCallingIdentity(identity);
4808        }
4809    }
4810
4811    @Override
4812    public String getPermissionControllerPackageName() {
4813        synchronized (mPackages) {
4814            return mRequiredInstallerPackage;
4815        }
4816    }
4817
4818    /**
4819     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4820     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4821     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4822     * @param message the message to log on security exception
4823     */
4824    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4825            boolean checkShell, String message) {
4826        if (userId < 0) {
4827            throw new IllegalArgumentException("Invalid userId " + userId);
4828        }
4829        if (checkShell) {
4830            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4831        }
4832        if (userId == UserHandle.getUserId(callingUid)) return;
4833        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4834            if (requireFullPermission) {
4835                mContext.enforceCallingOrSelfPermission(
4836                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4837            } else {
4838                try {
4839                    mContext.enforceCallingOrSelfPermission(
4840                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4841                } catch (SecurityException se) {
4842                    mContext.enforceCallingOrSelfPermission(
4843                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4844                }
4845            }
4846        }
4847    }
4848
4849    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4850        if (callingUid == Process.SHELL_UID) {
4851            if (userHandle >= 0
4852                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4853                throw new SecurityException("Shell does not have permission to access user "
4854                        + userHandle);
4855            } else if (userHandle < 0) {
4856                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4857                        + Debug.getCallers(3));
4858            }
4859        }
4860    }
4861
4862    private BasePermission findPermissionTreeLP(String permName) {
4863        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4864            if (permName.startsWith(bp.name) &&
4865                    permName.length() > bp.name.length() &&
4866                    permName.charAt(bp.name.length()) == '.') {
4867                return bp;
4868            }
4869        }
4870        return null;
4871    }
4872
4873    private BasePermission checkPermissionTreeLP(String permName) {
4874        if (permName != null) {
4875            BasePermission bp = findPermissionTreeLP(permName);
4876            if (bp != null) {
4877                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4878                    return bp;
4879                }
4880                throw new SecurityException("Calling uid "
4881                        + Binder.getCallingUid()
4882                        + " is not allowed to add to permission tree "
4883                        + bp.name + " owned by uid " + bp.uid);
4884            }
4885        }
4886        throw new SecurityException("No permission tree found for " + permName);
4887    }
4888
4889    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4890        if (s1 == null) {
4891            return s2 == null;
4892        }
4893        if (s2 == null) {
4894            return false;
4895        }
4896        if (s1.getClass() != s2.getClass()) {
4897            return false;
4898        }
4899        return s1.equals(s2);
4900    }
4901
4902    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4903        if (pi1.icon != pi2.icon) return false;
4904        if (pi1.logo != pi2.logo) return false;
4905        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4906        if (!compareStrings(pi1.name, pi2.name)) return false;
4907        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4908        // We'll take care of setting this one.
4909        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4910        // These are not currently stored in settings.
4911        //if (!compareStrings(pi1.group, pi2.group)) return false;
4912        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4913        //if (pi1.labelRes != pi2.labelRes) return false;
4914        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4915        return true;
4916    }
4917
4918    int permissionInfoFootprint(PermissionInfo info) {
4919        int size = info.name.length();
4920        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4921        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4922        return size;
4923    }
4924
4925    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4926        int size = 0;
4927        for (BasePermission perm : mSettings.mPermissions.values()) {
4928            if (perm.uid == tree.uid) {
4929                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4930            }
4931        }
4932        return size;
4933    }
4934
4935    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4936        // We calculate the max size of permissions defined by this uid and throw
4937        // if that plus the size of 'info' would exceed our stated maximum.
4938        if (tree.uid != Process.SYSTEM_UID) {
4939            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4940            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4941                throw new SecurityException("Permission tree size cap exceeded");
4942            }
4943        }
4944    }
4945
4946    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4947        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4948            throw new SecurityException("Label must be specified in permission");
4949        }
4950        BasePermission tree = checkPermissionTreeLP(info.name);
4951        BasePermission bp = mSettings.mPermissions.get(info.name);
4952        boolean added = bp == null;
4953        boolean changed = true;
4954        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4955        if (added) {
4956            enforcePermissionCapLocked(info, tree);
4957            bp = new BasePermission(info.name, tree.sourcePackage,
4958                    BasePermission.TYPE_DYNAMIC);
4959        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4960            throw new SecurityException(
4961                    "Not allowed to modify non-dynamic permission "
4962                    + info.name);
4963        } else {
4964            if (bp.protectionLevel == fixedLevel
4965                    && bp.perm.owner.equals(tree.perm.owner)
4966                    && bp.uid == tree.uid
4967                    && comparePermissionInfos(bp.perm.info, info)) {
4968                changed = false;
4969            }
4970        }
4971        bp.protectionLevel = fixedLevel;
4972        info = new PermissionInfo(info);
4973        info.protectionLevel = fixedLevel;
4974        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4975        bp.perm.info.packageName = tree.perm.info.packageName;
4976        bp.uid = tree.uid;
4977        if (added) {
4978            mSettings.mPermissions.put(info.name, bp);
4979        }
4980        if (changed) {
4981            if (!async) {
4982                mSettings.writeLPr();
4983            } else {
4984                scheduleWriteSettingsLocked();
4985            }
4986        }
4987        return added;
4988    }
4989
4990    @Override
4991    public boolean addPermission(PermissionInfo info) {
4992        synchronized (mPackages) {
4993            return addPermissionLocked(info, false);
4994        }
4995    }
4996
4997    @Override
4998    public boolean addPermissionAsync(PermissionInfo info) {
4999        synchronized (mPackages) {
5000            return addPermissionLocked(info, true);
5001        }
5002    }
5003
5004    @Override
5005    public void removePermission(String name) {
5006        synchronized (mPackages) {
5007            checkPermissionTreeLP(name);
5008            BasePermission bp = mSettings.mPermissions.get(name);
5009            if (bp != null) {
5010                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5011                    throw new SecurityException(
5012                            "Not allowed to modify non-dynamic permission "
5013                            + name);
5014                }
5015                mSettings.mPermissions.remove(name);
5016                mSettings.writeLPr();
5017            }
5018        }
5019    }
5020
5021    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
5022            BasePermission bp) {
5023        int index = pkg.requestedPermissions.indexOf(bp.name);
5024        if (index == -1) {
5025            throw new SecurityException("Package " + pkg.packageName
5026                    + " has not requested permission " + bp.name);
5027        }
5028        if (!bp.isRuntime() && !bp.isDevelopment()) {
5029            throw new SecurityException("Permission " + bp.name
5030                    + " is not a changeable permission type");
5031        }
5032    }
5033
5034    @Override
5035    public void grantRuntimePermission(String packageName, String name, final int userId) {
5036        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5037    }
5038
5039    private void grantRuntimePermission(String packageName, String name, final int userId,
5040            boolean overridePolicy) {
5041        if (!sUserManager.exists(userId)) {
5042            Log.e(TAG, "No such user:" + userId);
5043            return;
5044        }
5045
5046        mContext.enforceCallingOrSelfPermission(
5047                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5048                "grantRuntimePermission");
5049
5050        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5051                true /* requireFullPermission */, true /* checkShell */,
5052                "grantRuntimePermission");
5053
5054        final int uid;
5055        final SettingBase sb;
5056
5057        synchronized (mPackages) {
5058            final PackageParser.Package pkg = mPackages.get(packageName);
5059            if (pkg == null) {
5060                throw new IllegalArgumentException("Unknown package: " + packageName);
5061            }
5062
5063            final BasePermission bp = mSettings.mPermissions.get(name);
5064            if (bp == null) {
5065                throw new IllegalArgumentException("Unknown permission: " + name);
5066            }
5067
5068            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5069
5070            // If a permission review is required for legacy apps we represent
5071            // their permissions as always granted runtime ones since we need
5072            // to keep the review required permission flag per user while an
5073            // install permission's state is shared across all users.
5074            if (mPermissionReviewRequired
5075                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5076                    && bp.isRuntime()) {
5077                return;
5078            }
5079
5080            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5081            sb = (SettingBase) pkg.mExtras;
5082            if (sb == null) {
5083                throw new IllegalArgumentException("Unknown package: " + packageName);
5084            }
5085
5086            final PermissionsState permissionsState = sb.getPermissionsState();
5087
5088            final int flags = permissionsState.getPermissionFlags(name, userId);
5089            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5090                throw new SecurityException("Cannot grant system fixed permission "
5091                        + name + " for package " + packageName);
5092            }
5093            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5094                throw new SecurityException("Cannot grant policy fixed permission "
5095                        + name + " for package " + packageName);
5096            }
5097
5098            if (bp.isDevelopment()) {
5099                // Development permissions must be handled specially, since they are not
5100                // normal runtime permissions.  For now they apply to all users.
5101                if (permissionsState.grantInstallPermission(bp) !=
5102                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5103                    scheduleWriteSettingsLocked();
5104                }
5105                return;
5106            }
5107
5108            final PackageSetting ps = mSettings.mPackages.get(packageName);
5109            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5110                throw new SecurityException("Cannot grant non-ephemeral permission"
5111                        + name + " for package " + packageName);
5112            }
5113
5114            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5115                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5116                return;
5117            }
5118
5119            final int result = permissionsState.grantRuntimePermission(bp, userId);
5120            switch (result) {
5121                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5122                    return;
5123                }
5124
5125                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5126                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5127                    mHandler.post(new Runnable() {
5128                        @Override
5129                        public void run() {
5130                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5131                        }
5132                    });
5133                }
5134                break;
5135            }
5136
5137            if (bp.isRuntime()) {
5138                logPermissionGranted(mContext, name, packageName);
5139            }
5140
5141            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5142
5143            // Not critical if that is lost - app has to request again.
5144            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5145        }
5146
5147        // Only need to do this if user is initialized. Otherwise it's a new user
5148        // and there are no processes running as the user yet and there's no need
5149        // to make an expensive call to remount processes for the changed permissions.
5150        if (READ_EXTERNAL_STORAGE.equals(name)
5151                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5152            final long token = Binder.clearCallingIdentity();
5153            try {
5154                if (sUserManager.isInitialized(userId)) {
5155                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5156                            StorageManagerInternal.class);
5157                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5158                }
5159            } finally {
5160                Binder.restoreCallingIdentity(token);
5161            }
5162        }
5163    }
5164
5165    @Override
5166    public void revokeRuntimePermission(String packageName, String name, int userId) {
5167        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5168    }
5169
5170    private void revokeRuntimePermission(String packageName, String name, int userId,
5171            boolean overridePolicy) {
5172        if (!sUserManager.exists(userId)) {
5173            Log.e(TAG, "No such user:" + userId);
5174            return;
5175        }
5176
5177        mContext.enforceCallingOrSelfPermission(
5178                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5179                "revokeRuntimePermission");
5180
5181        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5182                true /* requireFullPermission */, true /* checkShell */,
5183                "revokeRuntimePermission");
5184
5185        final int appId;
5186
5187        synchronized (mPackages) {
5188            final PackageParser.Package pkg = mPackages.get(packageName);
5189            if (pkg == null) {
5190                throw new IllegalArgumentException("Unknown package: " + packageName);
5191            }
5192
5193            final BasePermission bp = mSettings.mPermissions.get(name);
5194            if (bp == null) {
5195                throw new IllegalArgumentException("Unknown permission: " + name);
5196            }
5197
5198            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5199
5200            // If a permission review is required for legacy apps we represent
5201            // their permissions as always granted runtime ones since we need
5202            // to keep the review required permission flag per user while an
5203            // install permission's state is shared across all users.
5204            if (mPermissionReviewRequired
5205                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5206                    && bp.isRuntime()) {
5207                return;
5208            }
5209
5210            SettingBase sb = (SettingBase) pkg.mExtras;
5211            if (sb == null) {
5212                throw new IllegalArgumentException("Unknown package: " + packageName);
5213            }
5214
5215            final PermissionsState permissionsState = sb.getPermissionsState();
5216
5217            final int flags = permissionsState.getPermissionFlags(name, userId);
5218            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5219                throw new SecurityException("Cannot revoke system fixed permission "
5220                        + name + " for package " + packageName);
5221            }
5222            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5223                throw new SecurityException("Cannot revoke policy fixed permission "
5224                        + name + " for package " + packageName);
5225            }
5226
5227            if (bp.isDevelopment()) {
5228                // Development permissions must be handled specially, since they are not
5229                // normal runtime permissions.  For now they apply to all users.
5230                if (permissionsState.revokeInstallPermission(bp) !=
5231                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5232                    scheduleWriteSettingsLocked();
5233                }
5234                return;
5235            }
5236
5237            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5238                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5239                return;
5240            }
5241
5242            if (bp.isRuntime()) {
5243                logPermissionRevoked(mContext, name, packageName);
5244            }
5245
5246            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5247
5248            // Critical, after this call app should never have the permission.
5249            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5250
5251            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5252        }
5253
5254        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5255    }
5256
5257    /**
5258     * Get the first event id for the permission.
5259     *
5260     * <p>There are four events for each permission: <ul>
5261     *     <li>Request permission: first id + 0</li>
5262     *     <li>Grant permission: first id + 1</li>
5263     *     <li>Request for permission denied: first id + 2</li>
5264     *     <li>Revoke permission: first id + 3</li>
5265     * </ul></p>
5266     *
5267     * @param name name of the permission
5268     *
5269     * @return The first event id for the permission
5270     */
5271    private static int getBaseEventId(@NonNull String name) {
5272        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5273
5274        if (eventIdIndex == -1) {
5275            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5276                    || "user".equals(Build.TYPE)) {
5277                Log.i(TAG, "Unknown permission " + name);
5278
5279                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5280            } else {
5281                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5282                //
5283                // Also update
5284                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5285                // - metrics_constants.proto
5286                throw new IllegalStateException("Unknown permission " + name);
5287            }
5288        }
5289
5290        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5291    }
5292
5293    /**
5294     * Log that a permission was revoked.
5295     *
5296     * @param context Context of the caller
5297     * @param name name of the permission
5298     * @param packageName package permission if for
5299     */
5300    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5301            @NonNull String packageName) {
5302        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5303    }
5304
5305    /**
5306     * Log that a permission request was granted.
5307     *
5308     * @param context Context of the caller
5309     * @param name name of the permission
5310     * @param packageName package permission if for
5311     */
5312    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5313            @NonNull String packageName) {
5314        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5315    }
5316
5317    @Override
5318    public void resetRuntimePermissions() {
5319        mContext.enforceCallingOrSelfPermission(
5320                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5321                "revokeRuntimePermission");
5322
5323        int callingUid = Binder.getCallingUid();
5324        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5325            mContext.enforceCallingOrSelfPermission(
5326                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5327                    "resetRuntimePermissions");
5328        }
5329
5330        synchronized (mPackages) {
5331            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5332            for (int userId : UserManagerService.getInstance().getUserIds()) {
5333                final int packageCount = mPackages.size();
5334                for (int i = 0; i < packageCount; i++) {
5335                    PackageParser.Package pkg = mPackages.valueAt(i);
5336                    if (!(pkg.mExtras instanceof PackageSetting)) {
5337                        continue;
5338                    }
5339                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5340                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5341                }
5342            }
5343        }
5344    }
5345
5346    @Override
5347    public int getPermissionFlags(String name, String packageName, int userId) {
5348        if (!sUserManager.exists(userId)) {
5349            return 0;
5350        }
5351
5352        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5353
5354        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5355                true /* requireFullPermission */, false /* checkShell */,
5356                "getPermissionFlags");
5357
5358        synchronized (mPackages) {
5359            final PackageParser.Package pkg = mPackages.get(packageName);
5360            if (pkg == null) {
5361                return 0;
5362            }
5363
5364            final BasePermission bp = mSettings.mPermissions.get(name);
5365            if (bp == null) {
5366                return 0;
5367            }
5368
5369            SettingBase sb = (SettingBase) pkg.mExtras;
5370            if (sb == null) {
5371                return 0;
5372            }
5373
5374            PermissionsState permissionsState = sb.getPermissionsState();
5375            return permissionsState.getPermissionFlags(name, userId);
5376        }
5377    }
5378
5379    @Override
5380    public void updatePermissionFlags(String name, String packageName, int flagMask,
5381            int flagValues, int userId) {
5382        if (!sUserManager.exists(userId)) {
5383            return;
5384        }
5385
5386        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5387
5388        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5389                true /* requireFullPermission */, true /* checkShell */,
5390                "updatePermissionFlags");
5391
5392        // Only the system can change these flags and nothing else.
5393        if (getCallingUid() != Process.SYSTEM_UID) {
5394            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5395            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5396            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5397            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5398            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5399        }
5400
5401        synchronized (mPackages) {
5402            final PackageParser.Package pkg = mPackages.get(packageName);
5403            if (pkg == null) {
5404                throw new IllegalArgumentException("Unknown package: " + packageName);
5405            }
5406
5407            final BasePermission bp = mSettings.mPermissions.get(name);
5408            if (bp == null) {
5409                throw new IllegalArgumentException("Unknown permission: " + name);
5410            }
5411
5412            SettingBase sb = (SettingBase) pkg.mExtras;
5413            if (sb == null) {
5414                throw new IllegalArgumentException("Unknown package: " + packageName);
5415            }
5416
5417            PermissionsState permissionsState = sb.getPermissionsState();
5418
5419            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5420
5421            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5422                // Install and runtime permissions are stored in different places,
5423                // so figure out what permission changed and persist the change.
5424                if (permissionsState.getInstallPermissionState(name) != null) {
5425                    scheduleWriteSettingsLocked();
5426                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5427                        || hadState) {
5428                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5429                }
5430            }
5431        }
5432    }
5433
5434    /**
5435     * Update the permission flags for all packages and runtime permissions of a user in order
5436     * to allow device or profile owner to remove POLICY_FIXED.
5437     */
5438    @Override
5439    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5440        if (!sUserManager.exists(userId)) {
5441            return;
5442        }
5443
5444        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5445
5446        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5447                true /* requireFullPermission */, true /* checkShell */,
5448                "updatePermissionFlagsForAllApps");
5449
5450        // Only the system can change system fixed flags.
5451        if (getCallingUid() != Process.SYSTEM_UID) {
5452            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5453            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5454        }
5455
5456        synchronized (mPackages) {
5457            boolean changed = false;
5458            final int packageCount = mPackages.size();
5459            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5460                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5461                SettingBase sb = (SettingBase) pkg.mExtras;
5462                if (sb == null) {
5463                    continue;
5464                }
5465                PermissionsState permissionsState = sb.getPermissionsState();
5466                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5467                        userId, flagMask, flagValues);
5468            }
5469            if (changed) {
5470                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5471            }
5472        }
5473    }
5474
5475    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5476        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5477                != PackageManager.PERMISSION_GRANTED
5478            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5479                != PackageManager.PERMISSION_GRANTED) {
5480            throw new SecurityException(message + " requires "
5481                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5482                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5483        }
5484    }
5485
5486    @Override
5487    public boolean shouldShowRequestPermissionRationale(String permissionName,
5488            String packageName, int userId) {
5489        if (UserHandle.getCallingUserId() != userId) {
5490            mContext.enforceCallingPermission(
5491                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5492                    "canShowRequestPermissionRationale for user " + userId);
5493        }
5494
5495        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5496        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5497            return false;
5498        }
5499
5500        if (checkPermission(permissionName, packageName, userId)
5501                == PackageManager.PERMISSION_GRANTED) {
5502            return false;
5503        }
5504
5505        final int flags;
5506
5507        final long identity = Binder.clearCallingIdentity();
5508        try {
5509            flags = getPermissionFlags(permissionName,
5510                    packageName, userId);
5511        } finally {
5512            Binder.restoreCallingIdentity(identity);
5513        }
5514
5515        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5516                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5517                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5518
5519        if ((flags & fixedFlags) != 0) {
5520            return false;
5521        }
5522
5523        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5524    }
5525
5526    @Override
5527    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5528        mContext.enforceCallingOrSelfPermission(
5529                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5530                "addOnPermissionsChangeListener");
5531
5532        synchronized (mPackages) {
5533            mOnPermissionChangeListeners.addListenerLocked(listener);
5534        }
5535    }
5536
5537    @Override
5538    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5539        synchronized (mPackages) {
5540            mOnPermissionChangeListeners.removeListenerLocked(listener);
5541        }
5542    }
5543
5544    @Override
5545    public boolean isProtectedBroadcast(String actionName) {
5546        synchronized (mPackages) {
5547            if (mProtectedBroadcasts.contains(actionName)) {
5548                return true;
5549            } else if (actionName != null) {
5550                // TODO: remove these terrible hacks
5551                if (actionName.startsWith("android.net.netmon.lingerExpired")
5552                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5553                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5554                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5555                    return true;
5556                }
5557            }
5558        }
5559        return false;
5560    }
5561
5562    @Override
5563    public int checkSignatures(String pkg1, String pkg2) {
5564        synchronized (mPackages) {
5565            final PackageParser.Package p1 = mPackages.get(pkg1);
5566            final PackageParser.Package p2 = mPackages.get(pkg2);
5567            if (p1 == null || p1.mExtras == null
5568                    || p2 == null || p2.mExtras == null) {
5569                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5570            }
5571            return compareSignatures(p1.mSignatures, p2.mSignatures);
5572        }
5573    }
5574
5575    @Override
5576    public int checkUidSignatures(int uid1, int uid2) {
5577        // Map to base uids.
5578        uid1 = UserHandle.getAppId(uid1);
5579        uid2 = UserHandle.getAppId(uid2);
5580        // reader
5581        synchronized (mPackages) {
5582            Signature[] s1;
5583            Signature[] s2;
5584            Object obj = mSettings.getUserIdLPr(uid1);
5585            if (obj != null) {
5586                if (obj instanceof SharedUserSetting) {
5587                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5588                } else if (obj instanceof PackageSetting) {
5589                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5590                } else {
5591                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5592                }
5593            } else {
5594                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5595            }
5596            obj = mSettings.getUserIdLPr(uid2);
5597            if (obj != null) {
5598                if (obj instanceof SharedUserSetting) {
5599                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5600                } else if (obj instanceof PackageSetting) {
5601                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5602                } else {
5603                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5604                }
5605            } else {
5606                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5607            }
5608            return compareSignatures(s1, s2);
5609        }
5610    }
5611
5612    /**
5613     * This method should typically only be used when granting or revoking
5614     * permissions, since the app may immediately restart after this call.
5615     * <p>
5616     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5617     * guard your work against the app being relaunched.
5618     */
5619    private void killUid(int appId, int userId, String reason) {
5620        final long identity = Binder.clearCallingIdentity();
5621        try {
5622            IActivityManager am = ActivityManager.getService();
5623            if (am != null) {
5624                try {
5625                    am.killUid(appId, userId, reason);
5626                } catch (RemoteException e) {
5627                    /* ignore - same process */
5628                }
5629            }
5630        } finally {
5631            Binder.restoreCallingIdentity(identity);
5632        }
5633    }
5634
5635    /**
5636     * Compares two sets of signatures. Returns:
5637     * <br />
5638     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5639     * <br />
5640     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5641     * <br />
5642     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5643     * <br />
5644     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5645     * <br />
5646     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5647     */
5648    static int compareSignatures(Signature[] s1, Signature[] s2) {
5649        if (s1 == null) {
5650            return s2 == null
5651                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5652                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5653        }
5654
5655        if (s2 == null) {
5656            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5657        }
5658
5659        if (s1.length != s2.length) {
5660            return PackageManager.SIGNATURE_NO_MATCH;
5661        }
5662
5663        // Since both signature sets are of size 1, we can compare without HashSets.
5664        if (s1.length == 1) {
5665            return s1[0].equals(s2[0]) ?
5666                    PackageManager.SIGNATURE_MATCH :
5667                    PackageManager.SIGNATURE_NO_MATCH;
5668        }
5669
5670        ArraySet<Signature> set1 = new ArraySet<Signature>();
5671        for (Signature sig : s1) {
5672            set1.add(sig);
5673        }
5674        ArraySet<Signature> set2 = new ArraySet<Signature>();
5675        for (Signature sig : s2) {
5676            set2.add(sig);
5677        }
5678        // Make sure s2 contains all signatures in s1.
5679        if (set1.equals(set2)) {
5680            return PackageManager.SIGNATURE_MATCH;
5681        }
5682        return PackageManager.SIGNATURE_NO_MATCH;
5683    }
5684
5685    /**
5686     * If the database version for this type of package (internal storage or
5687     * external storage) is less than the version where package signatures
5688     * were updated, return true.
5689     */
5690    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5691        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5692        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5693    }
5694
5695    /**
5696     * Used for backward compatibility to make sure any packages with
5697     * certificate chains get upgraded to the new style. {@code existingSigs}
5698     * will be in the old format (since they were stored on disk from before the
5699     * system upgrade) and {@code scannedSigs} will be in the newer format.
5700     */
5701    private int compareSignaturesCompat(PackageSignatures existingSigs,
5702            PackageParser.Package scannedPkg) {
5703        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5704            return PackageManager.SIGNATURE_NO_MATCH;
5705        }
5706
5707        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5708        for (Signature sig : existingSigs.mSignatures) {
5709            existingSet.add(sig);
5710        }
5711        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5712        for (Signature sig : scannedPkg.mSignatures) {
5713            try {
5714                Signature[] chainSignatures = sig.getChainSignatures();
5715                for (Signature chainSig : chainSignatures) {
5716                    scannedCompatSet.add(chainSig);
5717                }
5718            } catch (CertificateEncodingException e) {
5719                scannedCompatSet.add(sig);
5720            }
5721        }
5722        /*
5723         * Make sure the expanded scanned set contains all signatures in the
5724         * existing one.
5725         */
5726        if (scannedCompatSet.equals(existingSet)) {
5727            // Migrate the old signatures to the new scheme.
5728            existingSigs.assignSignatures(scannedPkg.mSignatures);
5729            // The new KeySets will be re-added later in the scanning process.
5730            synchronized (mPackages) {
5731                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5732            }
5733            return PackageManager.SIGNATURE_MATCH;
5734        }
5735        return PackageManager.SIGNATURE_NO_MATCH;
5736    }
5737
5738    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5739        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5740        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5741    }
5742
5743    private int compareSignaturesRecover(PackageSignatures existingSigs,
5744            PackageParser.Package scannedPkg) {
5745        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5746            return PackageManager.SIGNATURE_NO_MATCH;
5747        }
5748
5749        String msg = null;
5750        try {
5751            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5752                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5753                        + scannedPkg.packageName);
5754                return PackageManager.SIGNATURE_MATCH;
5755            }
5756        } catch (CertificateException e) {
5757            msg = e.getMessage();
5758        }
5759
5760        logCriticalInfo(Log.INFO,
5761                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5762        return PackageManager.SIGNATURE_NO_MATCH;
5763    }
5764
5765    @Override
5766    public List<String> getAllPackages() {
5767        synchronized (mPackages) {
5768            return new ArrayList<String>(mPackages.keySet());
5769        }
5770    }
5771
5772    @Override
5773    public String[] getPackagesForUid(int uid) {
5774        final int userId = UserHandle.getUserId(uid);
5775        uid = UserHandle.getAppId(uid);
5776        // reader
5777        synchronized (mPackages) {
5778            Object obj = mSettings.getUserIdLPr(uid);
5779            if (obj instanceof SharedUserSetting) {
5780                final SharedUserSetting sus = (SharedUserSetting) obj;
5781                final int N = sus.packages.size();
5782                String[] res = new String[N];
5783                final Iterator<PackageSetting> it = sus.packages.iterator();
5784                int i = 0;
5785                while (it.hasNext()) {
5786                    PackageSetting ps = it.next();
5787                    if (ps.getInstalled(userId)) {
5788                        res[i++] = ps.name;
5789                    } else {
5790                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5791                    }
5792                }
5793                return res;
5794            } else if (obj instanceof PackageSetting) {
5795                final PackageSetting ps = (PackageSetting) obj;
5796                if (ps.getInstalled(userId)) {
5797                    return new String[]{ps.name};
5798                }
5799            }
5800        }
5801        return null;
5802    }
5803
5804    @Override
5805    public String getNameForUid(int uid) {
5806        // reader
5807        synchronized (mPackages) {
5808            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5809            if (obj instanceof SharedUserSetting) {
5810                final SharedUserSetting sus = (SharedUserSetting) obj;
5811                return sus.name + ":" + sus.userId;
5812            } else if (obj instanceof PackageSetting) {
5813                final PackageSetting ps = (PackageSetting) obj;
5814                return ps.name;
5815            }
5816        }
5817        return null;
5818    }
5819
5820    @Override
5821    public int getUidForSharedUser(String sharedUserName) {
5822        if(sharedUserName == null) {
5823            return -1;
5824        }
5825        // reader
5826        synchronized (mPackages) {
5827            SharedUserSetting suid;
5828            try {
5829                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5830                if (suid != null) {
5831                    return suid.userId;
5832                }
5833            } catch (PackageManagerException ignore) {
5834                // can't happen, but, still need to catch it
5835            }
5836            return -1;
5837        }
5838    }
5839
5840    @Override
5841    public int getFlagsForUid(int uid) {
5842        synchronized (mPackages) {
5843            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5844            if (obj instanceof SharedUserSetting) {
5845                final SharedUserSetting sus = (SharedUserSetting) obj;
5846                return sus.pkgFlags;
5847            } else if (obj instanceof PackageSetting) {
5848                final PackageSetting ps = (PackageSetting) obj;
5849                return ps.pkgFlags;
5850            }
5851        }
5852        return 0;
5853    }
5854
5855    @Override
5856    public int getPrivateFlagsForUid(int uid) {
5857        synchronized (mPackages) {
5858            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5859            if (obj instanceof SharedUserSetting) {
5860                final SharedUserSetting sus = (SharedUserSetting) obj;
5861                return sus.pkgPrivateFlags;
5862            } else if (obj instanceof PackageSetting) {
5863                final PackageSetting ps = (PackageSetting) obj;
5864                return ps.pkgPrivateFlags;
5865            }
5866        }
5867        return 0;
5868    }
5869
5870    @Override
5871    public boolean isUidPrivileged(int uid) {
5872        uid = UserHandle.getAppId(uid);
5873        // reader
5874        synchronized (mPackages) {
5875            Object obj = mSettings.getUserIdLPr(uid);
5876            if (obj instanceof SharedUserSetting) {
5877                final SharedUserSetting sus = (SharedUserSetting) obj;
5878                final Iterator<PackageSetting> it = sus.packages.iterator();
5879                while (it.hasNext()) {
5880                    if (it.next().isPrivileged()) {
5881                        return true;
5882                    }
5883                }
5884            } else if (obj instanceof PackageSetting) {
5885                final PackageSetting ps = (PackageSetting) obj;
5886                return ps.isPrivileged();
5887            }
5888        }
5889        return false;
5890    }
5891
5892    @Override
5893    public String[] getAppOpPermissionPackages(String permissionName) {
5894        synchronized (mPackages) {
5895            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5896            if (pkgs == null) {
5897                return null;
5898            }
5899            return pkgs.toArray(new String[pkgs.size()]);
5900        }
5901    }
5902
5903    @Override
5904    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5905            int flags, int userId) {
5906        return resolveIntentInternal(
5907                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5908    }
5909
5910    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5911            int flags, int userId, boolean resolveForStart) {
5912        try {
5913            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5914
5915            if (!sUserManager.exists(userId)) return null;
5916            final int callingUid = Binder.getCallingUid();
5917            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5918            enforceCrossUserPermission(callingUid, userId,
5919                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5920
5921            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5922            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5923                    flags, userId, resolveForStart);
5924            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5925
5926            final ResolveInfo bestChoice =
5927                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5928            return bestChoice;
5929        } finally {
5930            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5931        }
5932    }
5933
5934    @Override
5935    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5936        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5937            throw new SecurityException(
5938                    "findPersistentPreferredActivity can only be run by the system");
5939        }
5940        if (!sUserManager.exists(userId)) {
5941            return null;
5942        }
5943        final int callingUid = Binder.getCallingUid();
5944        intent = updateIntentForResolve(intent);
5945        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5946        final int flags = updateFlagsForResolve(
5947                0, userId, intent, callingUid, false /*includeInstantApps*/);
5948        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5949                userId);
5950        synchronized (mPackages) {
5951            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5952                    userId);
5953        }
5954    }
5955
5956    @Override
5957    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5958            IntentFilter filter, int match, ComponentName activity) {
5959        final int userId = UserHandle.getCallingUserId();
5960        if (DEBUG_PREFERRED) {
5961            Log.v(TAG, "setLastChosenActivity intent=" + intent
5962                + " resolvedType=" + resolvedType
5963                + " flags=" + flags
5964                + " filter=" + filter
5965                + " match=" + match
5966                + " activity=" + activity);
5967            filter.dump(new PrintStreamPrinter(System.out), "    ");
5968        }
5969        intent.setComponent(null);
5970        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5971                userId);
5972        // Find any earlier preferred or last chosen entries and nuke them
5973        findPreferredActivity(intent, resolvedType,
5974                flags, query, 0, false, true, false, userId);
5975        // Add the new activity as the last chosen for this filter
5976        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5977                "Setting last chosen");
5978    }
5979
5980    @Override
5981    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5982        final int userId = UserHandle.getCallingUserId();
5983        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5984        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5985                userId);
5986        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5987                false, false, false, userId);
5988    }
5989
5990    /**
5991     * Returns whether or not instant apps have been disabled remotely.
5992     */
5993    private boolean isEphemeralDisabled() {
5994        return mEphemeralAppsDisabled;
5995    }
5996
5997    private boolean isInstantAppAllowed(
5998            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5999            boolean skipPackageCheck) {
6000        if (mInstantAppResolverConnection == null) {
6001            return false;
6002        }
6003        if (mInstantAppInstallerActivity == null) {
6004            return false;
6005        }
6006        if (intent.getComponent() != null) {
6007            return false;
6008        }
6009        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6010            return false;
6011        }
6012        if (!skipPackageCheck && intent.getPackage() != null) {
6013            return false;
6014        }
6015        final boolean isWebUri = hasWebURI(intent);
6016        if (!isWebUri || intent.getData().getHost() == null) {
6017            return false;
6018        }
6019        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6020        // Or if there's already an ephemeral app installed that handles the action
6021        synchronized (mPackages) {
6022            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6023            for (int n = 0; n < count; n++) {
6024                final ResolveInfo info = resolvedActivities.get(n);
6025                final String packageName = info.activityInfo.packageName;
6026                final PackageSetting ps = mSettings.mPackages.get(packageName);
6027                if (ps != null) {
6028                    // only check domain verification status if the app is not a browser
6029                    if (!info.handleAllWebDataURI) {
6030                        // Try to get the status from User settings first
6031                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6032                        final int status = (int) (packedStatus >> 32);
6033                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6034                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6035                            if (DEBUG_EPHEMERAL) {
6036                                Slog.v(TAG, "DENY instant app;"
6037                                    + " pkg: " + packageName + ", status: " + status);
6038                            }
6039                            return false;
6040                        }
6041                    }
6042                    if (ps.getInstantApp(userId)) {
6043                        if (DEBUG_EPHEMERAL) {
6044                            Slog.v(TAG, "DENY instant app installed;"
6045                                    + " pkg: " + packageName);
6046                        }
6047                        return false;
6048                    }
6049                }
6050            }
6051        }
6052        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6053        return true;
6054    }
6055
6056    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6057            Intent origIntent, String resolvedType, String callingPackage,
6058            Bundle verificationBundle, int userId) {
6059        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6060                new InstantAppRequest(responseObj, origIntent, resolvedType,
6061                        callingPackage, userId, verificationBundle));
6062        mHandler.sendMessage(msg);
6063    }
6064
6065    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6066            int flags, List<ResolveInfo> query, int userId) {
6067        if (query != null) {
6068            final int N = query.size();
6069            if (N == 1) {
6070                return query.get(0);
6071            } else if (N > 1) {
6072                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6073                // If there is more than one activity with the same priority,
6074                // then let the user decide between them.
6075                ResolveInfo r0 = query.get(0);
6076                ResolveInfo r1 = query.get(1);
6077                if (DEBUG_INTENT_MATCHING || debug) {
6078                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6079                            + r1.activityInfo.name + "=" + r1.priority);
6080                }
6081                // If the first activity has a higher priority, or a different
6082                // default, then it is always desirable to pick it.
6083                if (r0.priority != r1.priority
6084                        || r0.preferredOrder != r1.preferredOrder
6085                        || r0.isDefault != r1.isDefault) {
6086                    return query.get(0);
6087                }
6088                // If we have saved a preference for a preferred activity for
6089                // this Intent, use that.
6090                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6091                        flags, query, r0.priority, true, false, debug, userId);
6092                if (ri != null) {
6093                    return ri;
6094                }
6095                // If we have an ephemeral app, use it
6096                for (int i = 0; i < N; i++) {
6097                    ri = query.get(i);
6098                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6099                        final String packageName = ri.activityInfo.packageName;
6100                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6101                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6102                        final int status = (int)(packedStatus >> 32);
6103                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6104                            return ri;
6105                        }
6106                    }
6107                }
6108                ri = new ResolveInfo(mResolveInfo);
6109                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6110                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6111                // If all of the options come from the same package, show the application's
6112                // label and icon instead of the generic resolver's.
6113                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6114                // and then throw away the ResolveInfo itself, meaning that the caller loses
6115                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6116                // a fallback for this case; we only set the target package's resources on
6117                // the ResolveInfo, not the ActivityInfo.
6118                final String intentPackage = intent.getPackage();
6119                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6120                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6121                    ri.resolvePackageName = intentPackage;
6122                    if (userNeedsBadging(userId)) {
6123                        ri.noResourceId = true;
6124                    } else {
6125                        ri.icon = appi.icon;
6126                    }
6127                    ri.iconResourceId = appi.icon;
6128                    ri.labelRes = appi.labelRes;
6129                }
6130                ri.activityInfo.applicationInfo = new ApplicationInfo(
6131                        ri.activityInfo.applicationInfo);
6132                if (userId != 0) {
6133                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6134                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6135                }
6136                // Make sure that the resolver is displayable in car mode
6137                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6138                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6139                return ri;
6140            }
6141        }
6142        return null;
6143    }
6144
6145    /**
6146     * Return true if the given list is not empty and all of its contents have
6147     * an activityInfo with the given package name.
6148     */
6149    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6150        if (ArrayUtils.isEmpty(list)) {
6151            return false;
6152        }
6153        for (int i = 0, N = list.size(); i < N; i++) {
6154            final ResolveInfo ri = list.get(i);
6155            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6156            if (ai == null || !packageName.equals(ai.packageName)) {
6157                return false;
6158            }
6159        }
6160        return true;
6161    }
6162
6163    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6164            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6165        final int N = query.size();
6166        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6167                .get(userId);
6168        // Get the list of persistent preferred activities that handle the intent
6169        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6170        List<PersistentPreferredActivity> pprefs = ppir != null
6171                ? ppir.queryIntent(intent, resolvedType,
6172                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6173                        userId)
6174                : null;
6175        if (pprefs != null && pprefs.size() > 0) {
6176            final int M = pprefs.size();
6177            for (int i=0; i<M; i++) {
6178                final PersistentPreferredActivity ppa = pprefs.get(i);
6179                if (DEBUG_PREFERRED || debug) {
6180                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6181                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6182                            + "\n  component=" + ppa.mComponent);
6183                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6184                }
6185                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6186                        flags | MATCH_DISABLED_COMPONENTS, userId);
6187                if (DEBUG_PREFERRED || debug) {
6188                    Slog.v(TAG, "Found persistent preferred activity:");
6189                    if (ai != null) {
6190                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6191                    } else {
6192                        Slog.v(TAG, "  null");
6193                    }
6194                }
6195                if (ai == null) {
6196                    // This previously registered persistent preferred activity
6197                    // component is no longer known. Ignore it and do NOT remove it.
6198                    continue;
6199                }
6200                for (int j=0; j<N; j++) {
6201                    final ResolveInfo ri = query.get(j);
6202                    if (!ri.activityInfo.applicationInfo.packageName
6203                            .equals(ai.applicationInfo.packageName)) {
6204                        continue;
6205                    }
6206                    if (!ri.activityInfo.name.equals(ai.name)) {
6207                        continue;
6208                    }
6209                    //  Found a persistent preference that can handle the intent.
6210                    if (DEBUG_PREFERRED || debug) {
6211                        Slog.v(TAG, "Returning persistent preferred activity: " +
6212                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6213                    }
6214                    return ri;
6215                }
6216            }
6217        }
6218        return null;
6219    }
6220
6221    // TODO: handle preferred activities missing while user has amnesia
6222    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6223            List<ResolveInfo> query, int priority, boolean always,
6224            boolean removeMatches, boolean debug, int userId) {
6225        if (!sUserManager.exists(userId)) return null;
6226        final int callingUid = Binder.getCallingUid();
6227        flags = updateFlagsForResolve(
6228                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6229        intent = updateIntentForResolve(intent);
6230        // writer
6231        synchronized (mPackages) {
6232            // Try to find a matching persistent preferred activity.
6233            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6234                    debug, userId);
6235
6236            // If a persistent preferred activity matched, use it.
6237            if (pri != null) {
6238                return pri;
6239            }
6240
6241            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6242            // Get the list of preferred activities that handle the intent
6243            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6244            List<PreferredActivity> prefs = pir != null
6245                    ? pir.queryIntent(intent, resolvedType,
6246                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6247                            userId)
6248                    : null;
6249            if (prefs != null && prefs.size() > 0) {
6250                boolean changed = false;
6251                try {
6252                    // First figure out how good the original match set is.
6253                    // We will only allow preferred activities that came
6254                    // from the same match quality.
6255                    int match = 0;
6256
6257                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6258
6259                    final int N = query.size();
6260                    for (int j=0; j<N; j++) {
6261                        final ResolveInfo ri = query.get(j);
6262                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6263                                + ": 0x" + Integer.toHexString(match));
6264                        if (ri.match > match) {
6265                            match = ri.match;
6266                        }
6267                    }
6268
6269                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6270                            + Integer.toHexString(match));
6271
6272                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6273                    final int M = prefs.size();
6274                    for (int i=0; i<M; i++) {
6275                        final PreferredActivity pa = prefs.get(i);
6276                        if (DEBUG_PREFERRED || debug) {
6277                            Slog.v(TAG, "Checking PreferredActivity ds="
6278                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6279                                    + "\n  component=" + pa.mPref.mComponent);
6280                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6281                        }
6282                        if (pa.mPref.mMatch != match) {
6283                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6284                                    + Integer.toHexString(pa.mPref.mMatch));
6285                            continue;
6286                        }
6287                        // If it's not an "always" type preferred activity and that's what we're
6288                        // looking for, skip it.
6289                        if (always && !pa.mPref.mAlways) {
6290                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6291                            continue;
6292                        }
6293                        final ActivityInfo ai = getActivityInfo(
6294                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6295                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6296                                userId);
6297                        if (DEBUG_PREFERRED || debug) {
6298                            Slog.v(TAG, "Found preferred activity:");
6299                            if (ai != null) {
6300                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6301                            } else {
6302                                Slog.v(TAG, "  null");
6303                            }
6304                        }
6305                        if (ai == null) {
6306                            // This previously registered preferred activity
6307                            // component is no longer known.  Most likely an update
6308                            // to the app was installed and in the new version this
6309                            // component no longer exists.  Clean it up by removing
6310                            // it from the preferred activities list, and skip it.
6311                            Slog.w(TAG, "Removing dangling preferred activity: "
6312                                    + pa.mPref.mComponent);
6313                            pir.removeFilter(pa);
6314                            changed = true;
6315                            continue;
6316                        }
6317                        for (int j=0; j<N; j++) {
6318                            final ResolveInfo ri = query.get(j);
6319                            if (!ri.activityInfo.applicationInfo.packageName
6320                                    .equals(ai.applicationInfo.packageName)) {
6321                                continue;
6322                            }
6323                            if (!ri.activityInfo.name.equals(ai.name)) {
6324                                continue;
6325                            }
6326
6327                            if (removeMatches) {
6328                                pir.removeFilter(pa);
6329                                changed = true;
6330                                if (DEBUG_PREFERRED) {
6331                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6332                                }
6333                                break;
6334                            }
6335
6336                            // Okay we found a previously set preferred or last chosen app.
6337                            // If the result set is different from when this
6338                            // was created, we need to clear it and re-ask the
6339                            // user their preference, if we're looking for an "always" type entry.
6340                            if (always && !pa.mPref.sameSet(query)) {
6341                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6342                                        + intent + " type " + resolvedType);
6343                                if (DEBUG_PREFERRED) {
6344                                    Slog.v(TAG, "Removing preferred activity since set changed "
6345                                            + pa.mPref.mComponent);
6346                                }
6347                                pir.removeFilter(pa);
6348                                // Re-add the filter as a "last chosen" entry (!always)
6349                                PreferredActivity lastChosen = new PreferredActivity(
6350                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6351                                pir.addFilter(lastChosen);
6352                                changed = true;
6353                                return null;
6354                            }
6355
6356                            // Yay! Either the set matched or we're looking for the last chosen
6357                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6358                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6359                            return ri;
6360                        }
6361                    }
6362                } finally {
6363                    if (changed) {
6364                        if (DEBUG_PREFERRED) {
6365                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6366                        }
6367                        scheduleWritePackageRestrictionsLocked(userId);
6368                    }
6369                }
6370            }
6371        }
6372        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6373        return null;
6374    }
6375
6376    /*
6377     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6378     */
6379    @Override
6380    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6381            int targetUserId) {
6382        mContext.enforceCallingOrSelfPermission(
6383                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6384        List<CrossProfileIntentFilter> matches =
6385                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6386        if (matches != null) {
6387            int size = matches.size();
6388            for (int i = 0; i < size; i++) {
6389                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6390            }
6391        }
6392        if (hasWebURI(intent)) {
6393            // cross-profile app linking works only towards the parent.
6394            final int callingUid = Binder.getCallingUid();
6395            final UserInfo parent = getProfileParent(sourceUserId);
6396            synchronized(mPackages) {
6397                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6398                        false /*includeInstantApps*/);
6399                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6400                        intent, resolvedType, flags, sourceUserId, parent.id);
6401                return xpDomainInfo != null;
6402            }
6403        }
6404        return false;
6405    }
6406
6407    private UserInfo getProfileParent(int userId) {
6408        final long identity = Binder.clearCallingIdentity();
6409        try {
6410            return sUserManager.getProfileParent(userId);
6411        } finally {
6412            Binder.restoreCallingIdentity(identity);
6413        }
6414    }
6415
6416    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6417            String resolvedType, int userId) {
6418        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6419        if (resolver != null) {
6420            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6421        }
6422        return null;
6423    }
6424
6425    @Override
6426    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6427            String resolvedType, int flags, int userId) {
6428        try {
6429            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6430
6431            return new ParceledListSlice<>(
6432                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6433        } finally {
6434            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6435        }
6436    }
6437
6438    /**
6439     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6440     * instant, returns {@code null}.
6441     */
6442    private String getInstantAppPackageName(int callingUid) {
6443        // If the caller is an isolated app use the owner's uid for the lookup.
6444        if (Process.isIsolated(callingUid)) {
6445            callingUid = mIsolatedOwners.get(callingUid);
6446        }
6447        final int appId = UserHandle.getAppId(callingUid);
6448        synchronized (mPackages) {
6449            final Object obj = mSettings.getUserIdLPr(appId);
6450            if (obj instanceof PackageSetting) {
6451                final PackageSetting ps = (PackageSetting) obj;
6452                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6453                return isInstantApp ? ps.pkg.packageName : null;
6454            }
6455        }
6456        return null;
6457    }
6458
6459    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6460            String resolvedType, int flags, int userId) {
6461        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6462    }
6463
6464    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6465            String resolvedType, int flags, int userId, boolean resolveForStart) {
6466        if (!sUserManager.exists(userId)) return Collections.emptyList();
6467        final int callingUid = Binder.getCallingUid();
6468        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6469        enforceCrossUserPermission(callingUid, userId,
6470                false /* requireFullPermission */, false /* checkShell */,
6471                "query intent activities");
6472        final String pkgName = intent.getPackage();
6473        ComponentName comp = intent.getComponent();
6474        if (comp == null) {
6475            if (intent.getSelector() != null) {
6476                intent = intent.getSelector();
6477                comp = intent.getComponent();
6478            }
6479        }
6480
6481        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
6482                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6483        if (comp != null) {
6484            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6485            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6486            if (ai != null) {
6487                // When specifying an explicit component, we prevent the activity from being
6488                // used when either 1) the calling package is normal and the activity is within
6489                // an ephemeral application or 2) the calling package is ephemeral and the
6490                // activity is not visible to ephemeral applications.
6491                final boolean matchInstantApp =
6492                        (flags & PackageManager.MATCH_INSTANT) != 0;
6493                final boolean matchVisibleToInstantAppOnly =
6494                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6495                final boolean matchExplicitlyVisibleOnly =
6496                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6497                final boolean isCallerInstantApp =
6498                        instantAppPkgName != null;
6499                final boolean isTargetSameInstantApp =
6500                        comp.getPackageName().equals(instantAppPkgName);
6501                final boolean isTargetInstantApp =
6502                        (ai.applicationInfo.privateFlags
6503                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6504                final boolean isTargetVisibleToInstantApp =
6505                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6506                final boolean isTargetExplicitlyVisibleToInstantApp =
6507                        isTargetVisibleToInstantApp
6508                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6509                final boolean isTargetHiddenFromInstantApp =
6510                        !isTargetVisibleToInstantApp
6511                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6512                final boolean blockResolution =
6513                        !isTargetSameInstantApp
6514                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6515                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6516                                        && isTargetHiddenFromInstantApp));
6517                if (!blockResolution) {
6518                    final ResolveInfo ri = new ResolveInfo();
6519                    ri.activityInfo = ai;
6520                    list.add(ri);
6521                }
6522            }
6523            return applyPostResolutionFilter(list, instantAppPkgName);
6524        }
6525
6526        // reader
6527        boolean sortResult = false;
6528        boolean addEphemeral = false;
6529        List<ResolveInfo> result;
6530        final boolean ephemeralDisabled = isEphemeralDisabled();
6531        synchronized (mPackages) {
6532            if (pkgName == null) {
6533                List<CrossProfileIntentFilter> matchingFilters =
6534                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6535                // Check for results that need to skip the current profile.
6536                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6537                        resolvedType, flags, userId);
6538                if (xpResolveInfo != null) {
6539                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6540                    xpResult.add(xpResolveInfo);
6541                    return applyPostResolutionFilter(
6542                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6543                }
6544
6545                // Check for results in the current profile.
6546                result = filterIfNotSystemUser(mActivities.queryIntent(
6547                        intent, resolvedType, flags, userId), userId);
6548                addEphemeral = !ephemeralDisabled
6549                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6550                // Check for cross profile results.
6551                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6552                xpResolveInfo = queryCrossProfileIntents(
6553                        matchingFilters, intent, resolvedType, flags, userId,
6554                        hasNonNegativePriorityResult);
6555                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6556                    boolean isVisibleToUser = filterIfNotSystemUser(
6557                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6558                    if (isVisibleToUser) {
6559                        result.add(xpResolveInfo);
6560                        sortResult = true;
6561                    }
6562                }
6563                if (hasWebURI(intent)) {
6564                    CrossProfileDomainInfo xpDomainInfo = null;
6565                    final UserInfo parent = getProfileParent(userId);
6566                    if (parent != null) {
6567                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6568                                flags, userId, parent.id);
6569                    }
6570                    if (xpDomainInfo != null) {
6571                        if (xpResolveInfo != null) {
6572                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6573                            // in the result.
6574                            result.remove(xpResolveInfo);
6575                        }
6576                        if (result.size() == 0 && !addEphemeral) {
6577                            // No result in current profile, but found candidate in parent user.
6578                            // And we are not going to add emphemeral app, so we can return the
6579                            // result straight away.
6580                            result.add(xpDomainInfo.resolveInfo);
6581                            return applyPostResolutionFilter(result, instantAppPkgName);
6582                        }
6583                    } else if (result.size() <= 1 && !addEphemeral) {
6584                        // No result in parent user and <= 1 result in current profile, and we
6585                        // are not going to add emphemeral app, so we can return the result without
6586                        // further processing.
6587                        return applyPostResolutionFilter(result, instantAppPkgName);
6588                    }
6589                    // We have more than one candidate (combining results from current and parent
6590                    // profile), so we need filtering and sorting.
6591                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6592                            intent, flags, result, xpDomainInfo, userId);
6593                    sortResult = true;
6594                }
6595            } else {
6596                final PackageParser.Package pkg = mPackages.get(pkgName);
6597                result = null;
6598                if (pkg != null) {
6599                    result = filterIfNotSystemUser(
6600                            mActivities.queryIntentForPackage(
6601                                    intent, resolvedType, flags, pkg.activities, userId),
6602                            userId);
6603                }
6604                if (result == null || result.size() == 0) {
6605                    // the caller wants to resolve for a particular package; however, there
6606                    // were no installed results, so, try to find an ephemeral result
6607                    addEphemeral = !ephemeralDisabled
6608                            && isInstantAppAllowed(
6609                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6610                    if (result == null) {
6611                        result = new ArrayList<>();
6612                    }
6613                }
6614            }
6615        }
6616        if (addEphemeral) {
6617            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
6618        }
6619        if (sortResult) {
6620            Collections.sort(result, mResolvePrioritySorter);
6621        }
6622        return applyPostResolutionFilter(result, instantAppPkgName);
6623    }
6624
6625    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6626            String resolvedType, int flags, int userId) {
6627        // first, check to see if we've got an instant app already installed
6628        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6629        ResolveInfo localInstantApp = null;
6630        boolean blockResolution = false;
6631        if (!alreadyResolvedLocally) {
6632            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6633                    flags
6634                        | PackageManager.GET_RESOLVED_FILTER
6635                        | PackageManager.MATCH_INSTANT
6636                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6637                    userId);
6638            for (int i = instantApps.size() - 1; i >= 0; --i) {
6639                final ResolveInfo info = instantApps.get(i);
6640                final String packageName = info.activityInfo.packageName;
6641                final PackageSetting ps = mSettings.mPackages.get(packageName);
6642                if (ps.getInstantApp(userId)) {
6643                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6644                    final int status = (int)(packedStatus >> 32);
6645                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6646                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6647                        // there's a local instant application installed, but, the user has
6648                        // chosen to never use it; skip resolution and don't acknowledge
6649                        // an instant application is even available
6650                        if (DEBUG_EPHEMERAL) {
6651                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6652                        }
6653                        blockResolution = true;
6654                        break;
6655                    } else {
6656                        // we have a locally installed instant application; skip resolution
6657                        // but acknowledge there's an instant application available
6658                        if (DEBUG_EPHEMERAL) {
6659                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6660                        }
6661                        localInstantApp = info;
6662                        break;
6663                    }
6664                }
6665            }
6666        }
6667        // no app installed, let's see if one's available
6668        AuxiliaryResolveInfo auxiliaryResponse = null;
6669        if (!blockResolution) {
6670            if (localInstantApp == null) {
6671                // we don't have an instant app locally, resolve externally
6672                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6673                final InstantAppRequest requestObject = new InstantAppRequest(
6674                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6675                        null /*callingPackage*/, userId, null /*verificationBundle*/);
6676                auxiliaryResponse =
6677                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6678                                mContext, mInstantAppResolverConnection, requestObject);
6679                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6680            } else {
6681                // we have an instant application locally, but, we can't admit that since
6682                // callers shouldn't be able to determine prior browsing. create a dummy
6683                // auxiliary response so the downstream code behaves as if there's an
6684                // instant application available externally. when it comes time to start
6685                // the instant application, we'll do the right thing.
6686                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6687                auxiliaryResponse = new AuxiliaryResolveInfo(
6688                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
6689            }
6690        }
6691        if (auxiliaryResponse != null) {
6692            if (DEBUG_EPHEMERAL) {
6693                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6694            }
6695            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6696            final PackageSetting ps =
6697                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6698            if (ps != null) {
6699                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6700                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6701                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6702                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6703                // make sure this resolver is the default
6704                ephemeralInstaller.isDefault = true;
6705                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6706                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6707                // add a non-generic filter
6708                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6709                ephemeralInstaller.filter.addDataPath(
6710                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6711                ephemeralInstaller.isInstantAppAvailable = true;
6712                result.add(ephemeralInstaller);
6713            }
6714        }
6715        return result;
6716    }
6717
6718    private static class CrossProfileDomainInfo {
6719        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6720        ResolveInfo resolveInfo;
6721        /* Best domain verification status of the activities found in the other profile */
6722        int bestDomainVerificationStatus;
6723    }
6724
6725    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6726            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6727        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6728                sourceUserId)) {
6729            return null;
6730        }
6731        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6732                resolvedType, flags, parentUserId);
6733
6734        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6735            return null;
6736        }
6737        CrossProfileDomainInfo result = null;
6738        int size = resultTargetUser.size();
6739        for (int i = 0; i < size; i++) {
6740            ResolveInfo riTargetUser = resultTargetUser.get(i);
6741            // Intent filter verification is only for filters that specify a host. So don't return
6742            // those that handle all web uris.
6743            if (riTargetUser.handleAllWebDataURI) {
6744                continue;
6745            }
6746            String packageName = riTargetUser.activityInfo.packageName;
6747            PackageSetting ps = mSettings.mPackages.get(packageName);
6748            if (ps == null) {
6749                continue;
6750            }
6751            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6752            int status = (int)(verificationState >> 32);
6753            if (result == null) {
6754                result = new CrossProfileDomainInfo();
6755                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6756                        sourceUserId, parentUserId);
6757                result.bestDomainVerificationStatus = status;
6758            } else {
6759                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6760                        result.bestDomainVerificationStatus);
6761            }
6762        }
6763        // Don't consider matches with status NEVER across profiles.
6764        if (result != null && result.bestDomainVerificationStatus
6765                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6766            return null;
6767        }
6768        return result;
6769    }
6770
6771    /**
6772     * Verification statuses are ordered from the worse to the best, except for
6773     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6774     */
6775    private int bestDomainVerificationStatus(int status1, int status2) {
6776        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6777            return status2;
6778        }
6779        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6780            return status1;
6781        }
6782        return (int) MathUtils.max(status1, status2);
6783    }
6784
6785    private boolean isUserEnabled(int userId) {
6786        long callingId = Binder.clearCallingIdentity();
6787        try {
6788            UserInfo userInfo = sUserManager.getUserInfo(userId);
6789            return userInfo != null && userInfo.isEnabled();
6790        } finally {
6791            Binder.restoreCallingIdentity(callingId);
6792        }
6793    }
6794
6795    /**
6796     * Filter out activities with systemUserOnly flag set, when current user is not System.
6797     *
6798     * @return filtered list
6799     */
6800    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6801        if (userId == UserHandle.USER_SYSTEM) {
6802            return resolveInfos;
6803        }
6804        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6805            ResolveInfo info = resolveInfos.get(i);
6806            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6807                resolveInfos.remove(i);
6808            }
6809        }
6810        return resolveInfos;
6811    }
6812
6813    /**
6814     * Filters out ephemeral activities.
6815     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6816     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6817     *
6818     * @param resolveInfos The pre-filtered list of resolved activities
6819     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6820     *          is performed.
6821     * @return A filtered list of resolved activities.
6822     */
6823    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6824            String ephemeralPkgName) {
6825        // TODO: When adding on-demand split support for non-instant apps, remove this check
6826        // and always apply post filtering
6827        if (ephemeralPkgName == null) {
6828            return resolveInfos;
6829        }
6830        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6831            final ResolveInfo info = resolveInfos.get(i);
6832            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6833            // allow activities that are defined in the provided package
6834            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6835                if (info.activityInfo.splitName != null
6836                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6837                                info.activityInfo.splitName)) {
6838                    // requested activity is defined in a split that hasn't been installed yet.
6839                    // add the installer to the resolve list
6840                    if (DEBUG_EPHEMERAL) {
6841                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6842                    }
6843                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6844                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6845                            info.activityInfo.packageName, info.activityInfo.splitName,
6846                            info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
6847                    // make sure this resolver is the default
6848                    installerInfo.isDefault = true;
6849                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6850                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6851                    // add a non-generic filter
6852                    installerInfo.filter = new IntentFilter();
6853                    // load resources from the correct package
6854                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6855                    resolveInfos.set(i, installerInfo);
6856                }
6857                continue;
6858            }
6859            // allow activities that have been explicitly exposed to ephemeral apps
6860            if (!isEphemeralApp
6861                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6862                continue;
6863            }
6864            resolveInfos.remove(i);
6865        }
6866        return resolveInfos;
6867    }
6868
6869    /**
6870     * @param resolveInfos list of resolve infos in descending priority order
6871     * @return if the list contains a resolve info with non-negative priority
6872     */
6873    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6874        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6875    }
6876
6877    private static boolean hasWebURI(Intent intent) {
6878        if (intent.getData() == null) {
6879            return false;
6880        }
6881        final String scheme = intent.getScheme();
6882        if (TextUtils.isEmpty(scheme)) {
6883            return false;
6884        }
6885        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6886    }
6887
6888    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6889            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6890            int userId) {
6891        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6892
6893        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6894            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6895                    candidates.size());
6896        }
6897
6898        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6899        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6900        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6901        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6902        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6903        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6904
6905        synchronized (mPackages) {
6906            final int count = candidates.size();
6907            // First, try to use linked apps. Partition the candidates into four lists:
6908            // one for the final results, one for the "do not use ever", one for "undefined status"
6909            // and finally one for "browser app type".
6910            for (int n=0; n<count; n++) {
6911                ResolveInfo info = candidates.get(n);
6912                String packageName = info.activityInfo.packageName;
6913                PackageSetting ps = mSettings.mPackages.get(packageName);
6914                if (ps != null) {
6915                    // Add to the special match all list (Browser use case)
6916                    if (info.handleAllWebDataURI) {
6917                        matchAllList.add(info);
6918                        continue;
6919                    }
6920                    // Try to get the status from User settings first
6921                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6922                    int status = (int)(packedStatus >> 32);
6923                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6924                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6925                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6926                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6927                                    + " : linkgen=" + linkGeneration);
6928                        }
6929                        // Use link-enabled generation as preferredOrder, i.e.
6930                        // prefer newly-enabled over earlier-enabled.
6931                        info.preferredOrder = linkGeneration;
6932                        alwaysList.add(info);
6933                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6934                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6935                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6936                        }
6937                        neverList.add(info);
6938                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6939                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6940                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6941                        }
6942                        alwaysAskList.add(info);
6943                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6944                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6945                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6946                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6947                        }
6948                        undefinedList.add(info);
6949                    }
6950                }
6951            }
6952
6953            // We'll want to include browser possibilities in a few cases
6954            boolean includeBrowser = false;
6955
6956            // First try to add the "always" resolution(s) for the current user, if any
6957            if (alwaysList.size() > 0) {
6958                result.addAll(alwaysList);
6959            } else {
6960                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6961                result.addAll(undefinedList);
6962                // Maybe add one for the other profile.
6963                if (xpDomainInfo != null && (
6964                        xpDomainInfo.bestDomainVerificationStatus
6965                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6966                    result.add(xpDomainInfo.resolveInfo);
6967                }
6968                includeBrowser = true;
6969            }
6970
6971            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6972            // If there were 'always' entries their preferred order has been set, so we also
6973            // back that off to make the alternatives equivalent
6974            if (alwaysAskList.size() > 0) {
6975                for (ResolveInfo i : result) {
6976                    i.preferredOrder = 0;
6977                }
6978                result.addAll(alwaysAskList);
6979                includeBrowser = true;
6980            }
6981
6982            if (includeBrowser) {
6983                // Also add browsers (all of them or only the default one)
6984                if (DEBUG_DOMAIN_VERIFICATION) {
6985                    Slog.v(TAG, "   ...including browsers in candidate set");
6986                }
6987                if ((matchFlags & MATCH_ALL) != 0) {
6988                    result.addAll(matchAllList);
6989                } else {
6990                    // Browser/generic handling case.  If there's a default browser, go straight
6991                    // to that (but only if there is no other higher-priority match).
6992                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6993                    int maxMatchPrio = 0;
6994                    ResolveInfo defaultBrowserMatch = null;
6995                    final int numCandidates = matchAllList.size();
6996                    for (int n = 0; n < numCandidates; n++) {
6997                        ResolveInfo info = matchAllList.get(n);
6998                        // track the highest overall match priority...
6999                        if (info.priority > maxMatchPrio) {
7000                            maxMatchPrio = info.priority;
7001                        }
7002                        // ...and the highest-priority default browser match
7003                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7004                            if (defaultBrowserMatch == null
7005                                    || (defaultBrowserMatch.priority < info.priority)) {
7006                                if (debug) {
7007                                    Slog.v(TAG, "Considering default browser match " + info);
7008                                }
7009                                defaultBrowserMatch = info;
7010                            }
7011                        }
7012                    }
7013                    if (defaultBrowserMatch != null
7014                            && defaultBrowserMatch.priority >= maxMatchPrio
7015                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7016                    {
7017                        if (debug) {
7018                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7019                        }
7020                        result.add(defaultBrowserMatch);
7021                    } else {
7022                        result.addAll(matchAllList);
7023                    }
7024                }
7025
7026                // If there is nothing selected, add all candidates and remove the ones that the user
7027                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7028                if (result.size() == 0) {
7029                    result.addAll(candidates);
7030                    result.removeAll(neverList);
7031                }
7032            }
7033        }
7034        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7035            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7036                    result.size());
7037            for (ResolveInfo info : result) {
7038                Slog.v(TAG, "  + " + info.activityInfo);
7039            }
7040        }
7041        return result;
7042    }
7043
7044    // Returns a packed value as a long:
7045    //
7046    // high 'int'-sized word: link status: undefined/ask/never/always.
7047    // low 'int'-sized word: relative priority among 'always' results.
7048    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7049        long result = ps.getDomainVerificationStatusForUser(userId);
7050        // if none available, get the master status
7051        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7052            if (ps.getIntentFilterVerificationInfo() != null) {
7053                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7054            }
7055        }
7056        return result;
7057    }
7058
7059    private ResolveInfo querySkipCurrentProfileIntents(
7060            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7061            int flags, int sourceUserId) {
7062        if (matchingFilters != null) {
7063            int size = matchingFilters.size();
7064            for (int i = 0; i < size; i ++) {
7065                CrossProfileIntentFilter filter = matchingFilters.get(i);
7066                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7067                    // Checking if there are activities in the target user that can handle the
7068                    // intent.
7069                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7070                            resolvedType, flags, sourceUserId);
7071                    if (resolveInfo != null) {
7072                        return resolveInfo;
7073                    }
7074                }
7075            }
7076        }
7077        return null;
7078    }
7079
7080    // Return matching ResolveInfo in target user if any.
7081    private ResolveInfo queryCrossProfileIntents(
7082            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7083            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7084        if (matchingFilters != null) {
7085            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7086            // match the same intent. For performance reasons, it is better not to
7087            // run queryIntent twice for the same userId
7088            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7089            int size = matchingFilters.size();
7090            for (int i = 0; i < size; i++) {
7091                CrossProfileIntentFilter filter = matchingFilters.get(i);
7092                int targetUserId = filter.getTargetUserId();
7093                boolean skipCurrentProfile =
7094                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7095                boolean skipCurrentProfileIfNoMatchFound =
7096                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7097                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7098                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7099                    // Checking if there are activities in the target user that can handle the
7100                    // intent.
7101                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7102                            resolvedType, flags, sourceUserId);
7103                    if (resolveInfo != null) return resolveInfo;
7104                    alreadyTriedUserIds.put(targetUserId, true);
7105                }
7106            }
7107        }
7108        return null;
7109    }
7110
7111    /**
7112     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7113     * will forward the intent to the filter's target user.
7114     * Otherwise, returns null.
7115     */
7116    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7117            String resolvedType, int flags, int sourceUserId) {
7118        int targetUserId = filter.getTargetUserId();
7119        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7120                resolvedType, flags, targetUserId);
7121        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7122            // If all the matches in the target profile are suspended, return null.
7123            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7124                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7125                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7126                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7127                            targetUserId);
7128                }
7129            }
7130        }
7131        return null;
7132    }
7133
7134    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7135            int sourceUserId, int targetUserId) {
7136        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7137        long ident = Binder.clearCallingIdentity();
7138        boolean targetIsProfile;
7139        try {
7140            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7141        } finally {
7142            Binder.restoreCallingIdentity(ident);
7143        }
7144        String className;
7145        if (targetIsProfile) {
7146            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7147        } else {
7148            className = FORWARD_INTENT_TO_PARENT;
7149        }
7150        ComponentName forwardingActivityComponentName = new ComponentName(
7151                mAndroidApplication.packageName, className);
7152        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7153                sourceUserId);
7154        if (!targetIsProfile) {
7155            forwardingActivityInfo.showUserIcon = targetUserId;
7156            forwardingResolveInfo.noResourceId = true;
7157        }
7158        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7159        forwardingResolveInfo.priority = 0;
7160        forwardingResolveInfo.preferredOrder = 0;
7161        forwardingResolveInfo.match = 0;
7162        forwardingResolveInfo.isDefault = true;
7163        forwardingResolveInfo.filter = filter;
7164        forwardingResolveInfo.targetUserId = targetUserId;
7165        return forwardingResolveInfo;
7166    }
7167
7168    @Override
7169    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7170            Intent[] specifics, String[] specificTypes, Intent intent,
7171            String resolvedType, int flags, int userId) {
7172        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7173                specificTypes, intent, resolvedType, flags, userId));
7174    }
7175
7176    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7177            Intent[] specifics, String[] specificTypes, Intent intent,
7178            String resolvedType, int flags, int userId) {
7179        if (!sUserManager.exists(userId)) return Collections.emptyList();
7180        final int callingUid = Binder.getCallingUid();
7181        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7182                false /*includeInstantApps*/);
7183        enforceCrossUserPermission(callingUid, userId,
7184                false /*requireFullPermission*/, false /*checkShell*/,
7185                "query intent activity options");
7186        final String resultsAction = intent.getAction();
7187
7188        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7189                | PackageManager.GET_RESOLVED_FILTER, userId);
7190
7191        if (DEBUG_INTENT_MATCHING) {
7192            Log.v(TAG, "Query " + intent + ": " + results);
7193        }
7194
7195        int specificsPos = 0;
7196        int N;
7197
7198        // todo: note that the algorithm used here is O(N^2).  This
7199        // isn't a problem in our current environment, but if we start running
7200        // into situations where we have more than 5 or 10 matches then this
7201        // should probably be changed to something smarter...
7202
7203        // First we go through and resolve each of the specific items
7204        // that were supplied, taking care of removing any corresponding
7205        // duplicate items in the generic resolve list.
7206        if (specifics != null) {
7207            for (int i=0; i<specifics.length; i++) {
7208                final Intent sintent = specifics[i];
7209                if (sintent == null) {
7210                    continue;
7211                }
7212
7213                if (DEBUG_INTENT_MATCHING) {
7214                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7215                }
7216
7217                String action = sintent.getAction();
7218                if (resultsAction != null && resultsAction.equals(action)) {
7219                    // If this action was explicitly requested, then don't
7220                    // remove things that have it.
7221                    action = null;
7222                }
7223
7224                ResolveInfo ri = null;
7225                ActivityInfo ai = null;
7226
7227                ComponentName comp = sintent.getComponent();
7228                if (comp == null) {
7229                    ri = resolveIntent(
7230                        sintent,
7231                        specificTypes != null ? specificTypes[i] : null,
7232                            flags, userId);
7233                    if (ri == null) {
7234                        continue;
7235                    }
7236                    if (ri == mResolveInfo) {
7237                        // ACK!  Must do something better with this.
7238                    }
7239                    ai = ri.activityInfo;
7240                    comp = new ComponentName(ai.applicationInfo.packageName,
7241                            ai.name);
7242                } else {
7243                    ai = getActivityInfo(comp, flags, userId);
7244                    if (ai == null) {
7245                        continue;
7246                    }
7247                }
7248
7249                // Look for any generic query activities that are duplicates
7250                // of this specific one, and remove them from the results.
7251                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7252                N = results.size();
7253                int j;
7254                for (j=specificsPos; j<N; j++) {
7255                    ResolveInfo sri = results.get(j);
7256                    if ((sri.activityInfo.name.equals(comp.getClassName())
7257                            && sri.activityInfo.applicationInfo.packageName.equals(
7258                                    comp.getPackageName()))
7259                        || (action != null && sri.filter.matchAction(action))) {
7260                        results.remove(j);
7261                        if (DEBUG_INTENT_MATCHING) Log.v(
7262                            TAG, "Removing duplicate item from " + j
7263                            + " due to specific " + specificsPos);
7264                        if (ri == null) {
7265                            ri = sri;
7266                        }
7267                        j--;
7268                        N--;
7269                    }
7270                }
7271
7272                // Add this specific item to its proper place.
7273                if (ri == null) {
7274                    ri = new ResolveInfo();
7275                    ri.activityInfo = ai;
7276                }
7277                results.add(specificsPos, ri);
7278                ri.specificIndex = i;
7279                specificsPos++;
7280            }
7281        }
7282
7283        // Now we go through the remaining generic results and remove any
7284        // duplicate actions that are found here.
7285        N = results.size();
7286        for (int i=specificsPos; i<N-1; i++) {
7287            final ResolveInfo rii = results.get(i);
7288            if (rii.filter == null) {
7289                continue;
7290            }
7291
7292            // Iterate over all of the actions of this result's intent
7293            // filter...  typically this should be just one.
7294            final Iterator<String> it = rii.filter.actionsIterator();
7295            if (it == null) {
7296                continue;
7297            }
7298            while (it.hasNext()) {
7299                final String action = it.next();
7300                if (resultsAction != null && resultsAction.equals(action)) {
7301                    // If this action was explicitly requested, then don't
7302                    // remove things that have it.
7303                    continue;
7304                }
7305                for (int j=i+1; j<N; j++) {
7306                    final ResolveInfo rij = results.get(j);
7307                    if (rij.filter != null && rij.filter.hasAction(action)) {
7308                        results.remove(j);
7309                        if (DEBUG_INTENT_MATCHING) Log.v(
7310                            TAG, "Removing duplicate item from " + j
7311                            + " due to action " + action + " at " + i);
7312                        j--;
7313                        N--;
7314                    }
7315                }
7316            }
7317
7318            // If the caller didn't request filter information, drop it now
7319            // so we don't have to marshall/unmarshall it.
7320            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7321                rii.filter = null;
7322            }
7323        }
7324
7325        // Filter out the caller activity if so requested.
7326        if (caller != null) {
7327            N = results.size();
7328            for (int i=0; i<N; i++) {
7329                ActivityInfo ainfo = results.get(i).activityInfo;
7330                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7331                        && caller.getClassName().equals(ainfo.name)) {
7332                    results.remove(i);
7333                    break;
7334                }
7335            }
7336        }
7337
7338        // If the caller didn't request filter information,
7339        // drop them now so we don't have to
7340        // marshall/unmarshall it.
7341        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7342            N = results.size();
7343            for (int i=0; i<N; i++) {
7344                results.get(i).filter = null;
7345            }
7346        }
7347
7348        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7349        return results;
7350    }
7351
7352    @Override
7353    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7354            String resolvedType, int flags, int userId) {
7355        return new ParceledListSlice<>(
7356                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7357    }
7358
7359    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7360            String resolvedType, int flags, int userId) {
7361        if (!sUserManager.exists(userId)) return Collections.emptyList();
7362        final int callingUid = Binder.getCallingUid();
7363        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7364                false /*includeInstantApps*/);
7365        ComponentName comp = intent.getComponent();
7366        if (comp == null) {
7367            if (intent.getSelector() != null) {
7368                intent = intent.getSelector();
7369                comp = intent.getComponent();
7370            }
7371        }
7372        if (comp != null) {
7373            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7374            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7375            if (ai != null) {
7376                ResolveInfo ri = new ResolveInfo();
7377                ri.activityInfo = ai;
7378                list.add(ri);
7379            }
7380            return list;
7381        }
7382
7383        // reader
7384        synchronized (mPackages) {
7385            String pkgName = intent.getPackage();
7386            if (pkgName == null) {
7387                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7388            }
7389            final PackageParser.Package pkg = mPackages.get(pkgName);
7390            if (pkg != null) {
7391                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7392                        userId);
7393            }
7394            return Collections.emptyList();
7395        }
7396    }
7397
7398    @Override
7399    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7400        final int callingUid = Binder.getCallingUid();
7401        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7402    }
7403
7404    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7405            int userId, int callingUid) {
7406        if (!sUserManager.exists(userId)) return null;
7407        flags = updateFlagsForResolve(
7408                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7409        List<ResolveInfo> query = queryIntentServicesInternal(
7410                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7411        if (query != null) {
7412            if (query.size() >= 1) {
7413                // If there is more than one service with the same priority,
7414                // just arbitrarily pick the first one.
7415                return query.get(0);
7416            }
7417        }
7418        return null;
7419    }
7420
7421    @Override
7422    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7423            String resolvedType, int flags, int userId) {
7424        final int callingUid = Binder.getCallingUid();
7425        return new ParceledListSlice<>(queryIntentServicesInternal(
7426                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7427    }
7428
7429    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7430            String resolvedType, int flags, int userId, int callingUid,
7431            boolean includeInstantApps) {
7432        if (!sUserManager.exists(userId)) return Collections.emptyList();
7433        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7434        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7435        ComponentName comp = intent.getComponent();
7436        if (comp == null) {
7437            if (intent.getSelector() != null) {
7438                intent = intent.getSelector();
7439                comp = intent.getComponent();
7440            }
7441        }
7442        if (comp != null) {
7443            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7444            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7445            if (si != null) {
7446                // When specifying an explicit component, we prevent the service from being
7447                // used when either 1) the service is in an instant application and the
7448                // caller is not the same instant application or 2) the calling package is
7449                // ephemeral and the activity is not visible to ephemeral applications.
7450                final boolean matchInstantApp =
7451                        (flags & PackageManager.MATCH_INSTANT) != 0;
7452                final boolean matchVisibleToInstantAppOnly =
7453                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7454                final boolean isCallerInstantApp =
7455                        instantAppPkgName != null;
7456                final boolean isTargetSameInstantApp =
7457                        comp.getPackageName().equals(instantAppPkgName);
7458                final boolean isTargetInstantApp =
7459                        (si.applicationInfo.privateFlags
7460                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7461                final boolean isTargetHiddenFromInstantApp =
7462                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7463                final boolean blockResolution =
7464                        !isTargetSameInstantApp
7465                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7466                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7467                                        && isTargetHiddenFromInstantApp));
7468                if (!blockResolution) {
7469                    final ResolveInfo ri = new ResolveInfo();
7470                    ri.serviceInfo = si;
7471                    list.add(ri);
7472                }
7473            }
7474            return list;
7475        }
7476
7477        // reader
7478        synchronized (mPackages) {
7479            String pkgName = intent.getPackage();
7480            if (pkgName == null) {
7481                return applyPostServiceResolutionFilter(
7482                        mServices.queryIntent(intent, resolvedType, flags, userId),
7483                        instantAppPkgName);
7484            }
7485            final PackageParser.Package pkg = mPackages.get(pkgName);
7486            if (pkg != null) {
7487                return applyPostServiceResolutionFilter(
7488                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7489                                userId),
7490                        instantAppPkgName);
7491            }
7492            return Collections.emptyList();
7493        }
7494    }
7495
7496    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7497            String instantAppPkgName) {
7498        // TODO: When adding on-demand split support for non-instant apps, remove this check
7499        // and always apply post filtering
7500        if (instantAppPkgName == null) {
7501            return resolveInfos;
7502        }
7503        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7504            final ResolveInfo info = resolveInfos.get(i);
7505            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7506            // allow services that are defined in the provided package
7507            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7508                if (info.serviceInfo.splitName != null
7509                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7510                                info.serviceInfo.splitName)) {
7511                    // requested service is defined in a split that hasn't been installed yet.
7512                    // add the installer to the resolve list
7513                    if (DEBUG_EPHEMERAL) {
7514                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7515                    }
7516                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7517                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7518                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7519                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
7520                    // make sure this resolver is the default
7521                    installerInfo.isDefault = true;
7522                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7523                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7524                    // add a non-generic filter
7525                    installerInfo.filter = new IntentFilter();
7526                    // load resources from the correct package
7527                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7528                    resolveInfos.set(i, installerInfo);
7529                }
7530                continue;
7531            }
7532            // allow services that have been explicitly exposed to ephemeral apps
7533            if (!isEphemeralApp
7534                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7535                continue;
7536            }
7537            resolveInfos.remove(i);
7538        }
7539        return resolveInfos;
7540    }
7541
7542    @Override
7543    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7544            String resolvedType, int flags, int userId) {
7545        return new ParceledListSlice<>(
7546                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7547    }
7548
7549    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7550            Intent intent, String resolvedType, int flags, int userId) {
7551        if (!sUserManager.exists(userId)) return Collections.emptyList();
7552        final int callingUid = Binder.getCallingUid();
7553        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7554        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7555                false /*includeInstantApps*/);
7556        ComponentName comp = intent.getComponent();
7557        if (comp == null) {
7558            if (intent.getSelector() != null) {
7559                intent = intent.getSelector();
7560                comp = intent.getComponent();
7561            }
7562        }
7563        if (comp != null) {
7564            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7565            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7566            if (pi != null) {
7567                // When specifying an explicit component, we prevent the provider from being
7568                // used when either 1) the provider is in an instant application and the
7569                // caller is not the same instant application or 2) the calling package is an
7570                // instant application and the provider is not visible to instant applications.
7571                final boolean matchInstantApp =
7572                        (flags & PackageManager.MATCH_INSTANT) != 0;
7573                final boolean matchVisibleToInstantAppOnly =
7574                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7575                final boolean isCallerInstantApp =
7576                        instantAppPkgName != null;
7577                final boolean isTargetSameInstantApp =
7578                        comp.getPackageName().equals(instantAppPkgName);
7579                final boolean isTargetInstantApp =
7580                        (pi.applicationInfo.privateFlags
7581                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7582                final boolean isTargetHiddenFromInstantApp =
7583                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7584                final boolean blockResolution =
7585                        !isTargetSameInstantApp
7586                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7587                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7588                                        && isTargetHiddenFromInstantApp));
7589                if (!blockResolution) {
7590                    final ResolveInfo ri = new ResolveInfo();
7591                    ri.providerInfo = pi;
7592                    list.add(ri);
7593                }
7594            }
7595            return list;
7596        }
7597
7598        // reader
7599        synchronized (mPackages) {
7600            String pkgName = intent.getPackage();
7601            if (pkgName == null) {
7602                return applyPostContentProviderResolutionFilter(
7603                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7604                        instantAppPkgName);
7605            }
7606            final PackageParser.Package pkg = mPackages.get(pkgName);
7607            if (pkg != null) {
7608                return applyPostContentProviderResolutionFilter(
7609                        mProviders.queryIntentForPackage(
7610                        intent, resolvedType, flags, pkg.providers, userId),
7611                        instantAppPkgName);
7612            }
7613            return Collections.emptyList();
7614        }
7615    }
7616
7617    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7618            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7619        // TODO: When adding on-demand split support for non-instant applications, remove
7620        // this check and always apply post filtering
7621        if (instantAppPkgName == null) {
7622            return resolveInfos;
7623        }
7624        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7625            final ResolveInfo info = resolveInfos.get(i);
7626            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7627            // allow providers that are defined in the provided package
7628            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7629                if (info.providerInfo.splitName != null
7630                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7631                                info.providerInfo.splitName)) {
7632                    // requested provider is defined in a split that hasn't been installed yet.
7633                    // add the installer to the resolve list
7634                    if (DEBUG_EPHEMERAL) {
7635                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7636                    }
7637                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7638                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7639                            info.providerInfo.packageName, info.providerInfo.splitName,
7640                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
7641                    // make sure this resolver is the default
7642                    installerInfo.isDefault = true;
7643                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7644                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7645                    // add a non-generic filter
7646                    installerInfo.filter = new IntentFilter();
7647                    // load resources from the correct package
7648                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7649                    resolveInfos.set(i, installerInfo);
7650                }
7651                continue;
7652            }
7653            // allow providers that have been explicitly exposed to instant applications
7654            if (!isEphemeralApp
7655                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7656                continue;
7657            }
7658            resolveInfos.remove(i);
7659        }
7660        return resolveInfos;
7661    }
7662
7663    @Override
7664    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7665        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7666        flags = updateFlagsForPackage(flags, userId, null);
7667        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7668        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7669                true /* requireFullPermission */, false /* checkShell */,
7670                "get installed packages");
7671
7672        // writer
7673        synchronized (mPackages) {
7674            ArrayList<PackageInfo> list;
7675            if (listUninstalled) {
7676                list = new ArrayList<>(mSettings.mPackages.size());
7677                for (PackageSetting ps : mSettings.mPackages.values()) {
7678                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7679                        continue;
7680                    }
7681                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7682                    if (pi != null) {
7683                        list.add(pi);
7684                    }
7685                }
7686            } else {
7687                list = new ArrayList<>(mPackages.size());
7688                for (PackageParser.Package p : mPackages.values()) {
7689                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7690                            Binder.getCallingUid(), userId, flags)) {
7691                        continue;
7692                    }
7693                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7694                            p.mExtras, flags, userId);
7695                    if (pi != null) {
7696                        list.add(pi);
7697                    }
7698                }
7699            }
7700
7701            return new ParceledListSlice<>(list);
7702        }
7703    }
7704
7705    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7706            String[] permissions, boolean[] tmp, int flags, int userId) {
7707        int numMatch = 0;
7708        final PermissionsState permissionsState = ps.getPermissionsState();
7709        for (int i=0; i<permissions.length; i++) {
7710            final String permission = permissions[i];
7711            if (permissionsState.hasPermission(permission, userId)) {
7712                tmp[i] = true;
7713                numMatch++;
7714            } else {
7715                tmp[i] = false;
7716            }
7717        }
7718        if (numMatch == 0) {
7719            return;
7720        }
7721        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7722
7723        // The above might return null in cases of uninstalled apps or install-state
7724        // skew across users/profiles.
7725        if (pi != null) {
7726            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7727                if (numMatch == permissions.length) {
7728                    pi.requestedPermissions = permissions;
7729                } else {
7730                    pi.requestedPermissions = new String[numMatch];
7731                    numMatch = 0;
7732                    for (int i=0; i<permissions.length; i++) {
7733                        if (tmp[i]) {
7734                            pi.requestedPermissions[numMatch] = permissions[i];
7735                            numMatch++;
7736                        }
7737                    }
7738                }
7739            }
7740            list.add(pi);
7741        }
7742    }
7743
7744    @Override
7745    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7746            String[] permissions, int flags, int userId) {
7747        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7748        flags = updateFlagsForPackage(flags, userId, permissions);
7749        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7750                true /* requireFullPermission */, false /* checkShell */,
7751                "get packages holding permissions");
7752        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7753
7754        // writer
7755        synchronized (mPackages) {
7756            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7757            boolean[] tmpBools = new boolean[permissions.length];
7758            if (listUninstalled) {
7759                for (PackageSetting ps : mSettings.mPackages.values()) {
7760                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7761                            userId);
7762                }
7763            } else {
7764                for (PackageParser.Package pkg : mPackages.values()) {
7765                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7766                    if (ps != null) {
7767                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7768                                userId);
7769                    }
7770                }
7771            }
7772
7773            return new ParceledListSlice<PackageInfo>(list);
7774        }
7775    }
7776
7777    @Override
7778    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7779        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7780        flags = updateFlagsForApplication(flags, userId, null);
7781        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7782
7783        // writer
7784        synchronized (mPackages) {
7785            ArrayList<ApplicationInfo> list;
7786            if (listUninstalled) {
7787                list = new ArrayList<>(mSettings.mPackages.size());
7788                for (PackageSetting ps : mSettings.mPackages.values()) {
7789                    ApplicationInfo ai;
7790                    int effectiveFlags = flags;
7791                    if (ps.isSystem()) {
7792                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7793                    }
7794                    if (ps.pkg != null) {
7795                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7796                            continue;
7797                        }
7798                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7799                                ps.readUserState(userId), userId);
7800                        if (ai != null) {
7801                            rebaseEnabledOverlays(ai, userId);
7802                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7803                        }
7804                    } else {
7805                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7806                        // and already converts to externally visible package name
7807                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7808                                Binder.getCallingUid(), effectiveFlags, userId);
7809                    }
7810                    if (ai != null) {
7811                        list.add(ai);
7812                    }
7813                }
7814            } else {
7815                list = new ArrayList<>(mPackages.size());
7816                for (PackageParser.Package p : mPackages.values()) {
7817                    if (p.mExtras != null) {
7818                        PackageSetting ps = (PackageSetting) p.mExtras;
7819                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7820                            continue;
7821                        }
7822                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7823                                ps.readUserState(userId), userId);
7824                        if (ai != null) {
7825                            rebaseEnabledOverlays(ai, userId);
7826                            ai.packageName = resolveExternalPackageNameLPr(p);
7827                            list.add(ai);
7828                        }
7829                    }
7830                }
7831            }
7832
7833            return new ParceledListSlice<>(list);
7834        }
7835    }
7836
7837    @Override
7838    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7839        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7840            return null;
7841        }
7842
7843        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7844                "getEphemeralApplications");
7845        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7846                true /* requireFullPermission */, false /* checkShell */,
7847                "getEphemeralApplications");
7848        synchronized (mPackages) {
7849            List<InstantAppInfo> instantApps = mInstantAppRegistry
7850                    .getInstantAppsLPr(userId);
7851            if (instantApps != null) {
7852                return new ParceledListSlice<>(instantApps);
7853            }
7854        }
7855        return null;
7856    }
7857
7858    @Override
7859    public boolean isInstantApp(String packageName, int userId) {
7860        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7861                true /* requireFullPermission */, false /* checkShell */,
7862                "isInstantApp");
7863        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7864            return false;
7865        }
7866        int uid = Binder.getCallingUid();
7867        if (Process.isIsolated(uid)) {
7868            uid = mIsolatedOwners.get(uid);
7869        }
7870
7871        synchronized (mPackages) {
7872            final PackageSetting ps = mSettings.mPackages.get(packageName);
7873            PackageParser.Package pkg = mPackages.get(packageName);
7874            final boolean returnAllowed =
7875                    ps != null
7876                    && (isCallerSameApp(packageName, uid)
7877                            || mContext.checkCallingOrSelfPermission(
7878                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
7879                                            == PERMISSION_GRANTED
7880                            || mInstantAppRegistry.isInstantAccessGranted(
7881                                    userId, UserHandle.getAppId(uid), ps.appId));
7882            if (returnAllowed) {
7883                return ps.getInstantApp(userId);
7884            }
7885        }
7886        return false;
7887    }
7888
7889    @Override
7890    public byte[] getInstantAppCookie(String packageName, int userId) {
7891        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7892            return null;
7893        }
7894
7895        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7896                true /* requireFullPermission */, false /* checkShell */,
7897                "getInstantAppCookie");
7898        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7899            return null;
7900        }
7901        synchronized (mPackages) {
7902            return mInstantAppRegistry.getInstantAppCookieLPw(
7903                    packageName, userId);
7904        }
7905    }
7906
7907    @Override
7908    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7909        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7910            return true;
7911        }
7912
7913        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7914                true /* requireFullPermission */, true /* checkShell */,
7915                "setInstantAppCookie");
7916        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7917            return false;
7918        }
7919        synchronized (mPackages) {
7920            return mInstantAppRegistry.setInstantAppCookieLPw(
7921                    packageName, cookie, userId);
7922        }
7923    }
7924
7925    @Override
7926    public Bitmap getInstantAppIcon(String packageName, int userId) {
7927        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7928            return null;
7929        }
7930
7931        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7932                "getInstantAppIcon");
7933
7934        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7935                true /* requireFullPermission */, false /* checkShell */,
7936                "getInstantAppIcon");
7937
7938        synchronized (mPackages) {
7939            return mInstantAppRegistry.getInstantAppIconLPw(
7940                    packageName, userId);
7941        }
7942    }
7943
7944    private boolean isCallerSameApp(String packageName, int uid) {
7945        PackageParser.Package pkg = mPackages.get(packageName);
7946        return pkg != null
7947                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7948    }
7949
7950    @Override
7951    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7952        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7953    }
7954
7955    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7956        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7957
7958        // reader
7959        synchronized (mPackages) {
7960            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7961            final int userId = UserHandle.getCallingUserId();
7962            while (i.hasNext()) {
7963                final PackageParser.Package p = i.next();
7964                if (p.applicationInfo == null) continue;
7965
7966                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7967                        && !p.applicationInfo.isDirectBootAware();
7968                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7969                        && p.applicationInfo.isDirectBootAware();
7970
7971                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7972                        && (!mSafeMode || isSystemApp(p))
7973                        && (matchesUnaware || matchesAware)) {
7974                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7975                    if (ps != null) {
7976                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7977                                ps.readUserState(userId), userId);
7978                        if (ai != null) {
7979                            rebaseEnabledOverlays(ai, userId);
7980                            finalList.add(ai);
7981                        }
7982                    }
7983                }
7984            }
7985        }
7986
7987        return finalList;
7988    }
7989
7990    @Override
7991    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7992        if (!sUserManager.exists(userId)) return null;
7993        flags = updateFlagsForComponent(flags, userId, name);
7994        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7995        // reader
7996        synchronized (mPackages) {
7997            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7998            PackageSetting ps = provider != null
7999                    ? mSettings.mPackages.get(provider.owner.packageName)
8000                    : null;
8001            if (ps != null) {
8002                final boolean isInstantApp = ps.getInstantApp(userId);
8003                // normal application; filter out instant application provider
8004                if (instantAppPkgName == null && isInstantApp) {
8005                    return null;
8006                }
8007                // instant application; filter out other instant applications
8008                if (instantAppPkgName != null
8009                        && isInstantApp
8010                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8011                    return null;
8012                }
8013                // instant application; filter out non-exposed provider
8014                if (instantAppPkgName != null
8015                        && !isInstantApp
8016                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8017                    return null;
8018                }
8019                // provider not enabled
8020                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8021                    return null;
8022                }
8023                return PackageParser.generateProviderInfo(
8024                        provider, flags, ps.readUserState(userId), userId);
8025            }
8026            return null;
8027        }
8028    }
8029
8030    /**
8031     * @deprecated
8032     */
8033    @Deprecated
8034    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8035        // reader
8036        synchronized (mPackages) {
8037            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8038                    .entrySet().iterator();
8039            final int userId = UserHandle.getCallingUserId();
8040            while (i.hasNext()) {
8041                Map.Entry<String, PackageParser.Provider> entry = i.next();
8042                PackageParser.Provider p = entry.getValue();
8043                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8044
8045                if (ps != null && p.syncable
8046                        && (!mSafeMode || (p.info.applicationInfo.flags
8047                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8048                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8049                            ps.readUserState(userId), userId);
8050                    if (info != null) {
8051                        outNames.add(entry.getKey());
8052                        outInfo.add(info);
8053                    }
8054                }
8055            }
8056        }
8057    }
8058
8059    @Override
8060    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8061            int uid, int flags, String metaDataKey) {
8062        final int userId = processName != null ? UserHandle.getUserId(uid)
8063                : UserHandle.getCallingUserId();
8064        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8065        flags = updateFlagsForComponent(flags, userId, processName);
8066
8067        ArrayList<ProviderInfo> finalList = null;
8068        // reader
8069        synchronized (mPackages) {
8070            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8071            while (i.hasNext()) {
8072                final PackageParser.Provider p = i.next();
8073                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8074                if (ps != null && p.info.authority != null
8075                        && (processName == null
8076                                || (p.info.processName.equals(processName)
8077                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8078                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8079
8080                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8081                    // parameter.
8082                    if (metaDataKey != null
8083                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8084                        continue;
8085                    }
8086
8087                    if (finalList == null) {
8088                        finalList = new ArrayList<ProviderInfo>(3);
8089                    }
8090                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8091                            ps.readUserState(userId), userId);
8092                    if (info != null) {
8093                        finalList.add(info);
8094                    }
8095                }
8096            }
8097        }
8098
8099        if (finalList != null) {
8100            Collections.sort(finalList, mProviderInitOrderSorter);
8101            return new ParceledListSlice<ProviderInfo>(finalList);
8102        }
8103
8104        return ParceledListSlice.emptyList();
8105    }
8106
8107    @Override
8108    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
8109        // reader
8110        synchronized (mPackages) {
8111            final PackageParser.Instrumentation i = mInstrumentation.get(name);
8112            return PackageParser.generateInstrumentationInfo(i, flags);
8113        }
8114    }
8115
8116    @Override
8117    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8118            String targetPackage, int flags) {
8119        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8120    }
8121
8122    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8123            int flags) {
8124        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8125
8126        // reader
8127        synchronized (mPackages) {
8128            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8129            while (i.hasNext()) {
8130                final PackageParser.Instrumentation p = i.next();
8131                if (targetPackage == null
8132                        || targetPackage.equals(p.info.targetPackage)) {
8133                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8134                            flags);
8135                    if (ii != null) {
8136                        finalList.add(ii);
8137                    }
8138                }
8139            }
8140        }
8141
8142        return finalList;
8143    }
8144
8145    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8146        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8147        try {
8148            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8149        } finally {
8150            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8151        }
8152    }
8153
8154    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8155        final File[] files = dir.listFiles();
8156        if (ArrayUtils.isEmpty(files)) {
8157            Log.d(TAG, "No files in app dir " + dir);
8158            return;
8159        }
8160
8161        if (DEBUG_PACKAGE_SCANNING) {
8162            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8163                    + " flags=0x" + Integer.toHexString(parseFlags));
8164        }
8165        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8166                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8167                mParallelPackageParserCallback);
8168
8169        // Submit files for parsing in parallel
8170        int fileCount = 0;
8171        for (File file : files) {
8172            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8173                    && !PackageInstallerService.isStageName(file.getName());
8174            if (!isPackage) {
8175                // Ignore entries which are not packages
8176                continue;
8177            }
8178            parallelPackageParser.submit(file, parseFlags);
8179            fileCount++;
8180        }
8181
8182        // Process results one by one
8183        for (; fileCount > 0; fileCount--) {
8184            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8185            Throwable throwable = parseResult.throwable;
8186            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8187
8188            if (throwable == null) {
8189                // Static shared libraries have synthetic package names
8190                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8191                    renameStaticSharedLibraryPackage(parseResult.pkg);
8192                }
8193                try {
8194                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8195                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8196                                currentTime, null);
8197                    }
8198                } catch (PackageManagerException e) {
8199                    errorCode = e.error;
8200                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8201                }
8202            } else if (throwable instanceof PackageParser.PackageParserException) {
8203                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8204                        throwable;
8205                errorCode = e.error;
8206                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8207            } else {
8208                throw new IllegalStateException("Unexpected exception occurred while parsing "
8209                        + parseResult.scanFile, throwable);
8210            }
8211
8212            // Delete invalid userdata apps
8213            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8214                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8215                logCriticalInfo(Log.WARN,
8216                        "Deleting invalid package at " + parseResult.scanFile);
8217                removeCodePathLI(parseResult.scanFile);
8218            }
8219        }
8220        parallelPackageParser.close();
8221    }
8222
8223    private static File getSettingsProblemFile() {
8224        File dataDir = Environment.getDataDirectory();
8225        File systemDir = new File(dataDir, "system");
8226        File fname = new File(systemDir, "uiderrors.txt");
8227        return fname;
8228    }
8229
8230    static void reportSettingsProblem(int priority, String msg) {
8231        logCriticalInfo(priority, msg);
8232    }
8233
8234    public static void logCriticalInfo(int priority, String msg) {
8235        Slog.println(priority, TAG, msg);
8236        EventLogTags.writePmCriticalInfo(msg);
8237        try {
8238            File fname = getSettingsProblemFile();
8239            FileOutputStream out = new FileOutputStream(fname, true);
8240            PrintWriter pw = new FastPrintWriter(out);
8241            SimpleDateFormat formatter = new SimpleDateFormat();
8242            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8243            pw.println(dateString + ": " + msg);
8244            pw.close();
8245            FileUtils.setPermissions(
8246                    fname.toString(),
8247                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8248                    -1, -1);
8249        } catch (java.io.IOException e) {
8250        }
8251    }
8252
8253    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8254        if (srcFile.isDirectory()) {
8255            final File baseFile = new File(pkg.baseCodePath);
8256            long maxModifiedTime = baseFile.lastModified();
8257            if (pkg.splitCodePaths != null) {
8258                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8259                    final File splitFile = new File(pkg.splitCodePaths[i]);
8260                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8261                }
8262            }
8263            return maxModifiedTime;
8264        }
8265        return srcFile.lastModified();
8266    }
8267
8268    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8269            final int policyFlags) throws PackageManagerException {
8270        // When upgrading from pre-N MR1, verify the package time stamp using the package
8271        // directory and not the APK file.
8272        final long lastModifiedTime = mIsPreNMR1Upgrade
8273                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8274        if (ps != null
8275                && ps.codePath.equals(srcFile)
8276                && ps.timeStamp == lastModifiedTime
8277                && !isCompatSignatureUpdateNeeded(pkg)
8278                && !isRecoverSignatureUpdateNeeded(pkg)) {
8279            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8280            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8281            ArraySet<PublicKey> signingKs;
8282            synchronized (mPackages) {
8283                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8284            }
8285            if (ps.signatures.mSignatures != null
8286                    && ps.signatures.mSignatures.length != 0
8287                    && signingKs != null) {
8288                // Optimization: reuse the existing cached certificates
8289                // if the package appears to be unchanged.
8290                pkg.mSignatures = ps.signatures.mSignatures;
8291                pkg.mSigningKeys = signingKs;
8292                return;
8293            }
8294
8295            Slog.w(TAG, "PackageSetting for " + ps.name
8296                    + " is missing signatures.  Collecting certs again to recover them.");
8297        } else {
8298            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
8299        }
8300
8301        try {
8302            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8303            PackageParser.collectCertificates(pkg, policyFlags);
8304        } catch (PackageParserException e) {
8305            throw PackageManagerException.from(e);
8306        } finally {
8307            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8308        }
8309    }
8310
8311    /**
8312     *  Traces a package scan.
8313     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8314     */
8315    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8316            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8317        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8318        try {
8319            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8320        } finally {
8321            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8322        }
8323    }
8324
8325    /**
8326     *  Scans a package and returns the newly parsed package.
8327     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8328     */
8329    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8330            long currentTime, UserHandle user) throws PackageManagerException {
8331        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8332        PackageParser pp = new PackageParser();
8333        pp.setSeparateProcesses(mSeparateProcesses);
8334        pp.setOnlyCoreApps(mOnlyCore);
8335        pp.setDisplayMetrics(mMetrics);
8336        pp.setCallback(mPackageParserCallback);
8337
8338        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8339            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8340        }
8341
8342        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8343        final PackageParser.Package pkg;
8344        try {
8345            pkg = pp.parsePackage(scanFile, parseFlags);
8346        } catch (PackageParserException e) {
8347            throw PackageManagerException.from(e);
8348        } finally {
8349            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8350        }
8351
8352        // Static shared libraries have synthetic package names
8353        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8354            renameStaticSharedLibraryPackage(pkg);
8355        }
8356
8357        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8358    }
8359
8360    /**
8361     *  Scans a package and returns the newly parsed package.
8362     *  @throws PackageManagerException on a parse error.
8363     */
8364    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8365            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8366            throws PackageManagerException {
8367        // If the package has children and this is the first dive in the function
8368        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8369        // packages (parent and children) would be successfully scanned before the
8370        // actual scan since scanning mutates internal state and we want to atomically
8371        // install the package and its children.
8372        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8373            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8374                scanFlags |= SCAN_CHECK_ONLY;
8375            }
8376        } else {
8377            scanFlags &= ~SCAN_CHECK_ONLY;
8378        }
8379
8380        // Scan the parent
8381        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8382                scanFlags, currentTime, user);
8383
8384        // Scan the children
8385        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8386        for (int i = 0; i < childCount; i++) {
8387            PackageParser.Package childPackage = pkg.childPackages.get(i);
8388            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8389                    currentTime, user);
8390        }
8391
8392
8393        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8394            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8395        }
8396
8397        return scannedPkg;
8398    }
8399
8400    /**
8401     *  Scans a package and returns the newly parsed package.
8402     *  @throws PackageManagerException on a parse error.
8403     */
8404    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8405            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8406            throws PackageManagerException {
8407        PackageSetting ps = null;
8408        PackageSetting updatedPkg;
8409        // reader
8410        synchronized (mPackages) {
8411            // Look to see if we already know about this package.
8412            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8413            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8414                // This package has been renamed to its original name.  Let's
8415                // use that.
8416                ps = mSettings.getPackageLPr(oldName);
8417            }
8418            // If there was no original package, see one for the real package name.
8419            if (ps == null) {
8420                ps = mSettings.getPackageLPr(pkg.packageName);
8421            }
8422            // Check to see if this package could be hiding/updating a system
8423            // package.  Must look for it either under the original or real
8424            // package name depending on our state.
8425            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8426            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8427
8428            // If this is a package we don't know about on the system partition, we
8429            // may need to remove disabled child packages on the system partition
8430            // or may need to not add child packages if the parent apk is updated
8431            // on the data partition and no longer defines this child package.
8432            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8433                // If this is a parent package for an updated system app and this system
8434                // app got an OTA update which no longer defines some of the child packages
8435                // we have to prune them from the disabled system packages.
8436                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8437                if (disabledPs != null) {
8438                    final int scannedChildCount = (pkg.childPackages != null)
8439                            ? pkg.childPackages.size() : 0;
8440                    final int disabledChildCount = disabledPs.childPackageNames != null
8441                            ? disabledPs.childPackageNames.size() : 0;
8442                    for (int i = 0; i < disabledChildCount; i++) {
8443                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8444                        boolean disabledPackageAvailable = false;
8445                        for (int j = 0; j < scannedChildCount; j++) {
8446                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8447                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8448                                disabledPackageAvailable = true;
8449                                break;
8450                            }
8451                         }
8452                         if (!disabledPackageAvailable) {
8453                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8454                         }
8455                    }
8456                }
8457            }
8458        }
8459
8460        boolean updatedPkgBetter = false;
8461        // First check if this is a system package that may involve an update
8462        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8463            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8464            // it needs to drop FLAG_PRIVILEGED.
8465            if (locationIsPrivileged(scanFile)) {
8466                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8467            } else {
8468                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8469            }
8470
8471            if (ps != null && !ps.codePath.equals(scanFile)) {
8472                // The path has changed from what was last scanned...  check the
8473                // version of the new path against what we have stored to determine
8474                // what to do.
8475                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8476                if (pkg.mVersionCode <= ps.versionCode) {
8477                    // The system package has been updated and the code path does not match
8478                    // Ignore entry. Skip it.
8479                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8480                            + " ignored: updated version " + ps.versionCode
8481                            + " better than this " + pkg.mVersionCode);
8482                    if (!updatedPkg.codePath.equals(scanFile)) {
8483                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8484                                + ps.name + " changing from " + updatedPkg.codePathString
8485                                + " to " + scanFile);
8486                        updatedPkg.codePath = scanFile;
8487                        updatedPkg.codePathString = scanFile.toString();
8488                        updatedPkg.resourcePath = scanFile;
8489                        updatedPkg.resourcePathString = scanFile.toString();
8490                    }
8491                    updatedPkg.pkg = pkg;
8492                    updatedPkg.versionCode = pkg.mVersionCode;
8493
8494                    // Update the disabled system child packages to point to the package too.
8495                    final int childCount = updatedPkg.childPackageNames != null
8496                            ? updatedPkg.childPackageNames.size() : 0;
8497                    for (int i = 0; i < childCount; i++) {
8498                        String childPackageName = updatedPkg.childPackageNames.get(i);
8499                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8500                                childPackageName);
8501                        if (updatedChildPkg != null) {
8502                            updatedChildPkg.pkg = pkg;
8503                            updatedChildPkg.versionCode = pkg.mVersionCode;
8504                        }
8505                    }
8506
8507                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8508                            + scanFile + " ignored: updated version " + ps.versionCode
8509                            + " better than this " + pkg.mVersionCode);
8510                } else {
8511                    // The current app on the system partition is better than
8512                    // what we have updated to on the data partition; switch
8513                    // back to the system partition version.
8514                    // At this point, its safely assumed that package installation for
8515                    // apps in system partition will go through. If not there won't be a working
8516                    // version of the app
8517                    // writer
8518                    synchronized (mPackages) {
8519                        // Just remove the loaded entries from package lists.
8520                        mPackages.remove(ps.name);
8521                    }
8522
8523                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8524                            + " reverting from " + ps.codePathString
8525                            + ": new version " + pkg.mVersionCode
8526                            + " better than installed " + ps.versionCode);
8527
8528                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8529                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8530                    synchronized (mInstallLock) {
8531                        args.cleanUpResourcesLI();
8532                    }
8533                    synchronized (mPackages) {
8534                        mSettings.enableSystemPackageLPw(ps.name);
8535                    }
8536                    updatedPkgBetter = true;
8537                }
8538            }
8539        }
8540
8541        if (updatedPkg != null) {
8542            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8543            // initially
8544            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8545
8546            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8547            // flag set initially
8548            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8549                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8550            }
8551        }
8552
8553        // Verify certificates against what was last scanned
8554        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8555
8556        /*
8557         * A new system app appeared, but we already had a non-system one of the
8558         * same name installed earlier.
8559         */
8560        boolean shouldHideSystemApp = false;
8561        if (updatedPkg == null && ps != null
8562                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8563            /*
8564             * Check to make sure the signatures match first. If they don't,
8565             * wipe the installed application and its data.
8566             */
8567            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8568                    != PackageManager.SIGNATURE_MATCH) {
8569                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8570                        + " signatures don't match existing userdata copy; removing");
8571                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8572                        "scanPackageInternalLI")) {
8573                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8574                }
8575                ps = null;
8576            } else {
8577                /*
8578                 * If the newly-added system app is an older version than the
8579                 * already installed version, hide it. It will be scanned later
8580                 * and re-added like an update.
8581                 */
8582                if (pkg.mVersionCode <= ps.versionCode) {
8583                    shouldHideSystemApp = true;
8584                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8585                            + " but new version " + pkg.mVersionCode + " better than installed "
8586                            + ps.versionCode + "; hiding system");
8587                } else {
8588                    /*
8589                     * The newly found system app is a newer version that the
8590                     * one previously installed. Simply remove the
8591                     * already-installed application and replace it with our own
8592                     * while keeping the application data.
8593                     */
8594                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8595                            + " reverting from " + ps.codePathString + ": new version "
8596                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8597                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8598                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8599                    synchronized (mInstallLock) {
8600                        args.cleanUpResourcesLI();
8601                    }
8602                }
8603            }
8604        }
8605
8606        // The apk is forward locked (not public) if its code and resources
8607        // are kept in different files. (except for app in either system or
8608        // vendor path).
8609        // TODO grab this value from PackageSettings
8610        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8611            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8612                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8613            }
8614        }
8615
8616        // TODO: extend to support forward-locked splits
8617        String resourcePath = null;
8618        String baseResourcePath = null;
8619        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8620            if (ps != null && ps.resourcePathString != null) {
8621                resourcePath = ps.resourcePathString;
8622                baseResourcePath = ps.resourcePathString;
8623            } else {
8624                // Should not happen at all. Just log an error.
8625                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8626            }
8627        } else {
8628            resourcePath = pkg.codePath;
8629            baseResourcePath = pkg.baseCodePath;
8630        }
8631
8632        // Set application objects path explicitly.
8633        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8634        pkg.setApplicationInfoCodePath(pkg.codePath);
8635        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8636        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8637        pkg.setApplicationInfoResourcePath(resourcePath);
8638        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8639        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8640
8641        final int userId = ((user == null) ? 0 : user.getIdentifier());
8642        if (ps != null && ps.getInstantApp(userId)) {
8643            scanFlags |= SCAN_AS_INSTANT_APP;
8644        }
8645
8646        // Note that we invoke the following method only if we are about to unpack an application
8647        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8648                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8649
8650        /*
8651         * If the system app should be overridden by a previously installed
8652         * data, hide the system app now and let the /data/app scan pick it up
8653         * again.
8654         */
8655        if (shouldHideSystemApp) {
8656            synchronized (mPackages) {
8657                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8658            }
8659        }
8660
8661        return scannedPkg;
8662    }
8663
8664    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8665        // Derive the new package synthetic package name
8666        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8667                + pkg.staticSharedLibVersion);
8668    }
8669
8670    private static String fixProcessName(String defProcessName,
8671            String processName) {
8672        if (processName == null) {
8673            return defProcessName;
8674        }
8675        return processName;
8676    }
8677
8678    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8679            throws PackageManagerException {
8680        if (pkgSetting.signatures.mSignatures != null) {
8681            // Already existing package. Make sure signatures match
8682            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8683                    == PackageManager.SIGNATURE_MATCH;
8684            if (!match) {
8685                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8686                        == PackageManager.SIGNATURE_MATCH;
8687            }
8688            if (!match) {
8689                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8690                        == PackageManager.SIGNATURE_MATCH;
8691            }
8692            if (!match) {
8693                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8694                        + pkg.packageName + " signatures do not match the "
8695                        + "previously installed version; ignoring!");
8696            }
8697        }
8698
8699        // Check for shared user signatures
8700        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8701            // Already existing package. Make sure signatures match
8702            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8703                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8704            if (!match) {
8705                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8706                        == PackageManager.SIGNATURE_MATCH;
8707            }
8708            if (!match) {
8709                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8710                        == PackageManager.SIGNATURE_MATCH;
8711            }
8712            if (!match) {
8713                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8714                        "Package " + pkg.packageName
8715                        + " has no signatures that match those in shared user "
8716                        + pkgSetting.sharedUser.name + "; ignoring!");
8717            }
8718        }
8719    }
8720
8721    /**
8722     * Enforces that only the system UID or root's UID can call a method exposed
8723     * via Binder.
8724     *
8725     * @param message used as message if SecurityException is thrown
8726     * @throws SecurityException if the caller is not system or root
8727     */
8728    private static final void enforceSystemOrRoot(String message) {
8729        final int uid = Binder.getCallingUid();
8730        if (uid != Process.SYSTEM_UID && uid != 0) {
8731            throw new SecurityException(message);
8732        }
8733    }
8734
8735    @Override
8736    public void performFstrimIfNeeded() {
8737        enforceSystemOrRoot("Only the system can request fstrim");
8738
8739        // Before everything else, see whether we need to fstrim.
8740        try {
8741            IStorageManager sm = PackageHelper.getStorageManager();
8742            if (sm != null) {
8743                boolean doTrim = false;
8744                final long interval = android.provider.Settings.Global.getLong(
8745                        mContext.getContentResolver(),
8746                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8747                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8748                if (interval > 0) {
8749                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8750                    if (timeSinceLast > interval) {
8751                        doTrim = true;
8752                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8753                                + "; running immediately");
8754                    }
8755                }
8756                if (doTrim) {
8757                    final boolean dexOptDialogShown;
8758                    synchronized (mPackages) {
8759                        dexOptDialogShown = mDexOptDialogShown;
8760                    }
8761                    if (!isFirstBoot() && dexOptDialogShown) {
8762                        try {
8763                            ActivityManager.getService().showBootMessage(
8764                                    mContext.getResources().getString(
8765                                            R.string.android_upgrading_fstrim), true);
8766                        } catch (RemoteException e) {
8767                        }
8768                    }
8769                    sm.runMaintenance();
8770                }
8771            } else {
8772                Slog.e(TAG, "storageManager service unavailable!");
8773            }
8774        } catch (RemoteException e) {
8775            // Can't happen; StorageManagerService is local
8776        }
8777    }
8778
8779    @Override
8780    public void updatePackagesIfNeeded() {
8781        enforceSystemOrRoot("Only the system can request package update");
8782
8783        // We need to re-extract after an OTA.
8784        boolean causeUpgrade = isUpgrade();
8785
8786        // First boot or factory reset.
8787        // Note: we also handle devices that are upgrading to N right now as if it is their
8788        //       first boot, as they do not have profile data.
8789        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8790
8791        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8792        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8793
8794        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8795            return;
8796        }
8797
8798        List<PackageParser.Package> pkgs;
8799        synchronized (mPackages) {
8800            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8801        }
8802
8803        final long startTime = System.nanoTime();
8804        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8805                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8806
8807        final int elapsedTimeSeconds =
8808                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8809
8810        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8811        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8812        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8813        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8814        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8815    }
8816
8817    /*
8818     * Return the prebuilt profile path given a package base code path.
8819     */
8820    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8821        return pkg.baseCodePath + ".prof";
8822    }
8823
8824    /**
8825     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8826     * containing statistics about the invocation. The array consists of three elements,
8827     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8828     * and {@code numberOfPackagesFailed}.
8829     */
8830    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8831            String compilerFilter) {
8832
8833        int numberOfPackagesVisited = 0;
8834        int numberOfPackagesOptimized = 0;
8835        int numberOfPackagesSkipped = 0;
8836        int numberOfPackagesFailed = 0;
8837        final int numberOfPackagesToDexopt = pkgs.size();
8838
8839        for (PackageParser.Package pkg : pkgs) {
8840            numberOfPackagesVisited++;
8841
8842            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8843                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8844                // that are already compiled.
8845                File profileFile = new File(getPrebuildProfilePath(pkg));
8846                // Copy profile if it exists.
8847                if (profileFile.exists()) {
8848                    try {
8849                        // We could also do this lazily before calling dexopt in
8850                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8851                        // is that we don't have a good way to say "do this only once".
8852                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8853                                pkg.applicationInfo.uid, pkg.packageName)) {
8854                            Log.e(TAG, "Installer failed to copy system profile!");
8855                        }
8856                    } catch (Exception e) {
8857                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8858                                e);
8859                    }
8860                }
8861            }
8862
8863            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8864                if (DEBUG_DEXOPT) {
8865                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8866                }
8867                numberOfPackagesSkipped++;
8868                continue;
8869            }
8870
8871            if (DEBUG_DEXOPT) {
8872                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8873                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8874            }
8875
8876            if (showDialog) {
8877                try {
8878                    ActivityManager.getService().showBootMessage(
8879                            mContext.getResources().getString(R.string.android_upgrading_apk,
8880                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8881                } catch (RemoteException e) {
8882                }
8883                synchronized (mPackages) {
8884                    mDexOptDialogShown = true;
8885                }
8886            }
8887
8888            // If the OTA updates a system app which was previously preopted to a non-preopted state
8889            // the app might end up being verified at runtime. That's because by default the apps
8890            // are verify-profile but for preopted apps there's no profile.
8891            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8892            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8893            // filter (by default 'quicken').
8894            // Note that at this stage unused apps are already filtered.
8895            if (isSystemApp(pkg) &&
8896                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8897                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8898                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8899            }
8900
8901            // checkProfiles is false to avoid merging profiles during boot which
8902            // might interfere with background compilation (b/28612421).
8903            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8904            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8905            // trade-off worth doing to save boot time work.
8906            int dexOptStatus = performDexOptTraced(pkg.packageName,
8907                    false /* checkProfiles */,
8908                    compilerFilter,
8909                    false /* force */);
8910            switch (dexOptStatus) {
8911                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8912                    numberOfPackagesOptimized++;
8913                    break;
8914                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8915                    numberOfPackagesSkipped++;
8916                    break;
8917                case PackageDexOptimizer.DEX_OPT_FAILED:
8918                    numberOfPackagesFailed++;
8919                    break;
8920                default:
8921                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8922                    break;
8923            }
8924        }
8925
8926        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8927                numberOfPackagesFailed };
8928    }
8929
8930    @Override
8931    public void notifyPackageUse(String packageName, int reason) {
8932        synchronized (mPackages) {
8933            PackageParser.Package p = mPackages.get(packageName);
8934            if (p == null) {
8935                return;
8936            }
8937            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8938        }
8939    }
8940
8941    @Override
8942    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8943        int userId = UserHandle.getCallingUserId();
8944        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8945        if (ai == null) {
8946            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8947                + loadingPackageName + ", user=" + userId);
8948            return;
8949        }
8950        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8951    }
8952
8953    @Override
8954    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
8955            IDexModuleRegisterCallback callback) {
8956        int userId = UserHandle.getCallingUserId();
8957        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
8958        DexManager.RegisterDexModuleResult result;
8959        if (ai == null) {
8960            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
8961                     " calling user. package=" + packageName + ", user=" + userId);
8962            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
8963        } else {
8964            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
8965        }
8966
8967        if (callback != null) {
8968            mHandler.post(() -> {
8969                try {
8970                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
8971                } catch (RemoteException e) {
8972                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
8973                }
8974            });
8975        }
8976    }
8977
8978    @Override
8979    public boolean performDexOpt(String packageName,
8980            boolean checkProfiles, int compileReason, boolean force) {
8981        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8982                getCompilerFilterForReason(compileReason), force);
8983        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8984    }
8985
8986    @Override
8987    public boolean performDexOptMode(String packageName,
8988            boolean checkProfiles, String targetCompilerFilter, boolean force) {
8989        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8990                targetCompilerFilter, force);
8991        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8992    }
8993
8994    private int performDexOptTraced(String packageName,
8995                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8996        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8997        try {
8998            return performDexOptInternal(packageName, checkProfiles,
8999                    targetCompilerFilter, force);
9000        } finally {
9001            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9002        }
9003    }
9004
9005    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9006    // if the package can now be considered up to date for the given filter.
9007    private int performDexOptInternal(String packageName,
9008                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9009        PackageParser.Package p;
9010        synchronized (mPackages) {
9011            p = mPackages.get(packageName);
9012            if (p == null) {
9013                // Package could not be found. Report failure.
9014                return PackageDexOptimizer.DEX_OPT_FAILED;
9015            }
9016            mPackageUsage.maybeWriteAsync(mPackages);
9017            mCompilerStats.maybeWriteAsync();
9018        }
9019        long callingId = Binder.clearCallingIdentity();
9020        try {
9021            synchronized (mInstallLock) {
9022                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
9023                        targetCompilerFilter, force);
9024            }
9025        } finally {
9026            Binder.restoreCallingIdentity(callingId);
9027        }
9028    }
9029
9030    public ArraySet<String> getOptimizablePackages() {
9031        ArraySet<String> pkgs = new ArraySet<String>();
9032        synchronized (mPackages) {
9033            for (PackageParser.Package p : mPackages.values()) {
9034                if (PackageDexOptimizer.canOptimizePackage(p)) {
9035                    pkgs.add(p.packageName);
9036                }
9037            }
9038        }
9039        return pkgs;
9040    }
9041
9042    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9043            boolean checkProfiles, String targetCompilerFilter,
9044            boolean force) {
9045        // Select the dex optimizer based on the force parameter.
9046        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9047        //       allocate an object here.
9048        PackageDexOptimizer pdo = force
9049                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9050                : mPackageDexOptimizer;
9051
9052        // Dexopt all dependencies first. Note: we ignore the return value and march on
9053        // on errors.
9054        // Note that we are going to call performDexOpt on those libraries as many times as
9055        // they are referenced in packages. When we do a batch of performDexOpt (for example
9056        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9057        // and the first package that uses the library will dexopt it. The
9058        // others will see that the compiled code for the library is up to date.
9059        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9060        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9061        if (!deps.isEmpty()) {
9062            for (PackageParser.Package depPackage : deps) {
9063                // TODO: Analyze and investigate if we (should) profile libraries.
9064                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9065                        false /* checkProfiles */,
9066                        targetCompilerFilter,
9067                        getOrCreateCompilerPackageStats(depPackage),
9068                        true /* isUsedByOtherApps */);
9069            }
9070        }
9071        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
9072                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
9073                mDexManager.isUsedByOtherApps(p.packageName));
9074    }
9075
9076    // Performs dexopt on the used secondary dex files belonging to the given package.
9077    // Returns true if all dex files were process successfully (which could mean either dexopt or
9078    // skip). Returns false if any of the files caused errors.
9079    @Override
9080    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9081            boolean force) {
9082        mDexManager.reconcileSecondaryDexFiles(packageName);
9083        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
9084    }
9085
9086    public boolean performDexOptSecondary(String packageName, int compileReason,
9087            boolean force) {
9088        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
9089    }
9090
9091    /**
9092     * Reconcile the information we have about the secondary dex files belonging to
9093     * {@code packagName} and the actual dex files. For all dex files that were
9094     * deleted, update the internal records and delete the generated oat files.
9095     */
9096    @Override
9097    public void reconcileSecondaryDexFiles(String packageName) {
9098        mDexManager.reconcileSecondaryDexFiles(packageName);
9099    }
9100
9101    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9102    // a reference there.
9103    /*package*/ DexManager getDexManager() {
9104        return mDexManager;
9105    }
9106
9107    /**
9108     * Execute the background dexopt job immediately.
9109     */
9110    @Override
9111    public boolean runBackgroundDexoptJob() {
9112        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9113    }
9114
9115    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9116        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9117                || p.usesStaticLibraries != null) {
9118            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9119            Set<String> collectedNames = new HashSet<>();
9120            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9121
9122            retValue.remove(p);
9123
9124            return retValue;
9125        } else {
9126            return Collections.emptyList();
9127        }
9128    }
9129
9130    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9131            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9132        if (!collectedNames.contains(p.packageName)) {
9133            collectedNames.add(p.packageName);
9134            collected.add(p);
9135
9136            if (p.usesLibraries != null) {
9137                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9138                        null, collected, collectedNames);
9139            }
9140            if (p.usesOptionalLibraries != null) {
9141                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9142                        null, collected, collectedNames);
9143            }
9144            if (p.usesStaticLibraries != null) {
9145                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9146                        p.usesStaticLibrariesVersions, collected, collectedNames);
9147            }
9148        }
9149    }
9150
9151    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9152            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9153        final int libNameCount = libs.size();
9154        for (int i = 0; i < libNameCount; i++) {
9155            String libName = libs.get(i);
9156            int version = (versions != null && versions.length == libNameCount)
9157                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9158            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9159            if (libPkg != null) {
9160                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9161            }
9162        }
9163    }
9164
9165    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9166        synchronized (mPackages) {
9167            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9168            if (libEntry != null) {
9169                return mPackages.get(libEntry.apk);
9170            }
9171            return null;
9172        }
9173    }
9174
9175    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9176        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9177        if (versionedLib == null) {
9178            return null;
9179        }
9180        return versionedLib.get(version);
9181    }
9182
9183    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9184        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9185                pkg.staticSharedLibName);
9186        if (versionedLib == null) {
9187            return null;
9188        }
9189        int previousLibVersion = -1;
9190        final int versionCount = versionedLib.size();
9191        for (int i = 0; i < versionCount; i++) {
9192            final int libVersion = versionedLib.keyAt(i);
9193            if (libVersion < pkg.staticSharedLibVersion) {
9194                previousLibVersion = Math.max(previousLibVersion, libVersion);
9195            }
9196        }
9197        if (previousLibVersion >= 0) {
9198            return versionedLib.get(previousLibVersion);
9199        }
9200        return null;
9201    }
9202
9203    public void shutdown() {
9204        mPackageUsage.writeNow(mPackages);
9205        mCompilerStats.writeNow();
9206    }
9207
9208    @Override
9209    public void dumpProfiles(String packageName) {
9210        PackageParser.Package pkg;
9211        synchronized (mPackages) {
9212            pkg = mPackages.get(packageName);
9213            if (pkg == null) {
9214                throw new IllegalArgumentException("Unknown package: " + packageName);
9215            }
9216        }
9217        /* Only the shell, root, or the app user should be able to dump profiles. */
9218        int callingUid = Binder.getCallingUid();
9219        if (callingUid != Process.SHELL_UID &&
9220            callingUid != Process.ROOT_UID &&
9221            callingUid != pkg.applicationInfo.uid) {
9222            throw new SecurityException("dumpProfiles");
9223        }
9224
9225        synchronized (mInstallLock) {
9226            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9227            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9228            try {
9229                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9230                String codePaths = TextUtils.join(";", allCodePaths);
9231                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9232            } catch (InstallerException e) {
9233                Slog.w(TAG, "Failed to dump profiles", e);
9234            }
9235            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9236        }
9237    }
9238
9239    @Override
9240    public void forceDexOpt(String packageName) {
9241        enforceSystemOrRoot("forceDexOpt");
9242
9243        PackageParser.Package pkg;
9244        synchronized (mPackages) {
9245            pkg = mPackages.get(packageName);
9246            if (pkg == null) {
9247                throw new IllegalArgumentException("Unknown package: " + packageName);
9248            }
9249        }
9250
9251        synchronized (mInstallLock) {
9252            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9253
9254            // Whoever is calling forceDexOpt wants a compiled package.
9255            // Don't use profiles since that may cause compilation to be skipped.
9256            final int res = performDexOptInternalWithDependenciesLI(pkg,
9257                    false /* checkProfiles */, getDefaultCompilerFilter(),
9258                    true /* force */);
9259
9260            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9261            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9262                throw new IllegalStateException("Failed to dexopt: " + res);
9263            }
9264        }
9265    }
9266
9267    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9268        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9269            Slog.w(TAG, "Unable to update from " + oldPkg.name
9270                    + " to " + newPkg.packageName
9271                    + ": old package not in system partition");
9272            return false;
9273        } else if (mPackages.get(oldPkg.name) != null) {
9274            Slog.w(TAG, "Unable to update from " + oldPkg.name
9275                    + " to " + newPkg.packageName
9276                    + ": old package still exists");
9277            return false;
9278        }
9279        return true;
9280    }
9281
9282    void removeCodePathLI(File codePath) {
9283        if (codePath.isDirectory()) {
9284            try {
9285                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9286            } catch (InstallerException e) {
9287                Slog.w(TAG, "Failed to remove code path", e);
9288            }
9289        } else {
9290            codePath.delete();
9291        }
9292    }
9293
9294    private int[] resolveUserIds(int userId) {
9295        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9296    }
9297
9298    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9299        if (pkg == null) {
9300            Slog.wtf(TAG, "Package was null!", new Throwable());
9301            return;
9302        }
9303        clearAppDataLeafLIF(pkg, userId, flags);
9304        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9305        for (int i = 0; i < childCount; i++) {
9306            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9307        }
9308    }
9309
9310    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9311        final PackageSetting ps;
9312        synchronized (mPackages) {
9313            ps = mSettings.mPackages.get(pkg.packageName);
9314        }
9315        for (int realUserId : resolveUserIds(userId)) {
9316            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9317            try {
9318                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9319                        ceDataInode);
9320            } catch (InstallerException e) {
9321                Slog.w(TAG, String.valueOf(e));
9322            }
9323        }
9324    }
9325
9326    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9327        if (pkg == null) {
9328            Slog.wtf(TAG, "Package was null!", new Throwable());
9329            return;
9330        }
9331        destroyAppDataLeafLIF(pkg, userId, flags);
9332        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9333        for (int i = 0; i < childCount; i++) {
9334            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9335        }
9336    }
9337
9338    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9339        final PackageSetting ps;
9340        synchronized (mPackages) {
9341            ps = mSettings.mPackages.get(pkg.packageName);
9342        }
9343        for (int realUserId : resolveUserIds(userId)) {
9344            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9345            try {
9346                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9347                        ceDataInode);
9348            } catch (InstallerException e) {
9349                Slog.w(TAG, String.valueOf(e));
9350            }
9351            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9352        }
9353    }
9354
9355    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9356        if (pkg == null) {
9357            Slog.wtf(TAG, "Package was null!", new Throwable());
9358            return;
9359        }
9360        destroyAppProfilesLeafLIF(pkg);
9361        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9362        for (int i = 0; i < childCount; i++) {
9363            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9364        }
9365    }
9366
9367    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9368        try {
9369            mInstaller.destroyAppProfiles(pkg.packageName);
9370        } catch (InstallerException e) {
9371            Slog.w(TAG, String.valueOf(e));
9372        }
9373    }
9374
9375    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9376        if (pkg == null) {
9377            Slog.wtf(TAG, "Package was null!", new Throwable());
9378            return;
9379        }
9380        clearAppProfilesLeafLIF(pkg);
9381        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9382        for (int i = 0; i < childCount; i++) {
9383            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9384        }
9385    }
9386
9387    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9388        try {
9389            mInstaller.clearAppProfiles(pkg.packageName);
9390        } catch (InstallerException e) {
9391            Slog.w(TAG, String.valueOf(e));
9392        }
9393    }
9394
9395    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9396            long lastUpdateTime) {
9397        // Set parent install/update time
9398        PackageSetting ps = (PackageSetting) pkg.mExtras;
9399        if (ps != null) {
9400            ps.firstInstallTime = firstInstallTime;
9401            ps.lastUpdateTime = lastUpdateTime;
9402        }
9403        // Set children install/update time
9404        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9405        for (int i = 0; i < childCount; i++) {
9406            PackageParser.Package childPkg = pkg.childPackages.get(i);
9407            ps = (PackageSetting) childPkg.mExtras;
9408            if (ps != null) {
9409                ps.firstInstallTime = firstInstallTime;
9410                ps.lastUpdateTime = lastUpdateTime;
9411            }
9412        }
9413    }
9414
9415    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9416            PackageParser.Package changingLib) {
9417        if (file.path != null) {
9418            usesLibraryFiles.add(file.path);
9419            return;
9420        }
9421        PackageParser.Package p = mPackages.get(file.apk);
9422        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9423            // If we are doing this while in the middle of updating a library apk,
9424            // then we need to make sure to use that new apk for determining the
9425            // dependencies here.  (We haven't yet finished committing the new apk
9426            // to the package manager state.)
9427            if (p == null || p.packageName.equals(changingLib.packageName)) {
9428                p = changingLib;
9429            }
9430        }
9431        if (p != null) {
9432            usesLibraryFiles.addAll(p.getAllCodePaths());
9433            if (p.usesLibraryFiles != null) {
9434                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9435            }
9436        }
9437    }
9438
9439    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9440            PackageParser.Package changingLib) throws PackageManagerException {
9441        if (pkg == null) {
9442            return;
9443        }
9444        ArraySet<String> usesLibraryFiles = null;
9445        if (pkg.usesLibraries != null) {
9446            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9447                    null, null, pkg.packageName, changingLib, true, null);
9448        }
9449        if (pkg.usesStaticLibraries != null) {
9450            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9451                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9452                    pkg.packageName, changingLib, true, usesLibraryFiles);
9453        }
9454        if (pkg.usesOptionalLibraries != null) {
9455            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9456                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9457        }
9458        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9459            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9460        } else {
9461            pkg.usesLibraryFiles = null;
9462        }
9463    }
9464
9465    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9466            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9467            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9468            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9469            throws PackageManagerException {
9470        final int libCount = requestedLibraries.size();
9471        for (int i = 0; i < libCount; i++) {
9472            final String libName = requestedLibraries.get(i);
9473            final int libVersion = requiredVersions != null ? requiredVersions[i]
9474                    : SharedLibraryInfo.VERSION_UNDEFINED;
9475            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9476            if (libEntry == null) {
9477                if (required) {
9478                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9479                            "Package " + packageName + " requires unavailable shared library "
9480                                    + libName + "; failing!");
9481                } else if (DEBUG_SHARED_LIBRARIES) {
9482                    Slog.i(TAG, "Package " + packageName
9483                            + " desires unavailable shared library "
9484                            + libName + "; ignoring!");
9485                }
9486            } else {
9487                if (requiredVersions != null && requiredCertDigests != null) {
9488                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9489                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9490                            "Package " + packageName + " requires unavailable static shared"
9491                                    + " library " + libName + " version "
9492                                    + libEntry.info.getVersion() + "; failing!");
9493                    }
9494
9495                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9496                    if (libPkg == null) {
9497                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9498                                "Package " + packageName + " requires unavailable static shared"
9499                                        + " library; failing!");
9500                    }
9501
9502                    String expectedCertDigest = requiredCertDigests[i];
9503                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9504                                libPkg.mSignatures[0]);
9505                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9506                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9507                                "Package " + packageName + " requires differently signed" +
9508                                        " static shared library; failing!");
9509                    }
9510                }
9511
9512                if (outUsedLibraries == null) {
9513                    outUsedLibraries = new ArraySet<>();
9514                }
9515                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9516            }
9517        }
9518        return outUsedLibraries;
9519    }
9520
9521    private static boolean hasString(List<String> list, List<String> which) {
9522        if (list == null) {
9523            return false;
9524        }
9525        for (int i=list.size()-1; i>=0; i--) {
9526            for (int j=which.size()-1; j>=0; j--) {
9527                if (which.get(j).equals(list.get(i))) {
9528                    return true;
9529                }
9530            }
9531        }
9532        return false;
9533    }
9534
9535    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9536            PackageParser.Package changingPkg) {
9537        ArrayList<PackageParser.Package> res = null;
9538        for (PackageParser.Package pkg : mPackages.values()) {
9539            if (changingPkg != null
9540                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9541                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9542                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9543                            changingPkg.staticSharedLibName)) {
9544                return null;
9545            }
9546            if (res == null) {
9547                res = new ArrayList<>();
9548            }
9549            res.add(pkg);
9550            try {
9551                updateSharedLibrariesLPr(pkg, changingPkg);
9552            } catch (PackageManagerException e) {
9553                // If a system app update or an app and a required lib missing we
9554                // delete the package and for updated system apps keep the data as
9555                // it is better for the user to reinstall than to be in an limbo
9556                // state. Also libs disappearing under an app should never happen
9557                // - just in case.
9558                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9559                    final int flags = pkg.isUpdatedSystemApp()
9560                            ? PackageManager.DELETE_KEEP_DATA : 0;
9561                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9562                            flags , null, true, null);
9563                }
9564                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9565            }
9566        }
9567        return res;
9568    }
9569
9570    /**
9571     * Derive the value of the {@code cpuAbiOverride} based on the provided
9572     * value and an optional stored value from the package settings.
9573     */
9574    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9575        String cpuAbiOverride = null;
9576
9577        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9578            cpuAbiOverride = null;
9579        } else if (abiOverride != null) {
9580            cpuAbiOverride = abiOverride;
9581        } else if (settings != null) {
9582            cpuAbiOverride = settings.cpuAbiOverrideString;
9583        }
9584
9585        return cpuAbiOverride;
9586    }
9587
9588    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9589            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9590                    throws PackageManagerException {
9591        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9592        // If the package has children and this is the first dive in the function
9593        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9594        // whether all packages (parent and children) would be successfully scanned
9595        // before the actual scan since scanning mutates internal state and we want
9596        // to atomically install the package and its children.
9597        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9598            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9599                scanFlags |= SCAN_CHECK_ONLY;
9600            }
9601        } else {
9602            scanFlags &= ~SCAN_CHECK_ONLY;
9603        }
9604
9605        final PackageParser.Package scannedPkg;
9606        try {
9607            // Scan the parent
9608            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9609            // Scan the children
9610            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9611            for (int i = 0; i < childCount; i++) {
9612                PackageParser.Package childPkg = pkg.childPackages.get(i);
9613                scanPackageLI(childPkg, policyFlags,
9614                        scanFlags, currentTime, user);
9615            }
9616        } finally {
9617            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9618        }
9619
9620        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9621            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9622        }
9623
9624        return scannedPkg;
9625    }
9626
9627    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9628            int scanFlags, long currentTime, @Nullable UserHandle user)
9629                    throws PackageManagerException {
9630        boolean success = false;
9631        try {
9632            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9633                    currentTime, user);
9634            success = true;
9635            return res;
9636        } finally {
9637            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9638                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9639                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9640                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9641                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9642            }
9643        }
9644    }
9645
9646    /**
9647     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9648     */
9649    private static boolean apkHasCode(String fileName) {
9650        StrictJarFile jarFile = null;
9651        try {
9652            jarFile = new StrictJarFile(fileName,
9653                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9654            return jarFile.findEntry("classes.dex") != null;
9655        } catch (IOException ignore) {
9656        } finally {
9657            try {
9658                if (jarFile != null) {
9659                    jarFile.close();
9660                }
9661            } catch (IOException ignore) {}
9662        }
9663        return false;
9664    }
9665
9666    /**
9667     * Enforces code policy for the package. This ensures that if an APK has
9668     * declared hasCode="true" in its manifest that the APK actually contains
9669     * code.
9670     *
9671     * @throws PackageManagerException If bytecode could not be found when it should exist
9672     */
9673    private static void assertCodePolicy(PackageParser.Package pkg)
9674            throws PackageManagerException {
9675        final boolean shouldHaveCode =
9676                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9677        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9678            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9679                    "Package " + pkg.baseCodePath + " code is missing");
9680        }
9681
9682        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9683            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9684                final boolean splitShouldHaveCode =
9685                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9686                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9687                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9688                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9689                }
9690            }
9691        }
9692    }
9693
9694    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9695            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9696                    throws PackageManagerException {
9697        if (DEBUG_PACKAGE_SCANNING) {
9698            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9699                Log.d(TAG, "Scanning package " + pkg.packageName);
9700        }
9701
9702        applyPolicy(pkg, policyFlags);
9703
9704        assertPackageIsValid(pkg, policyFlags, scanFlags);
9705
9706        // Initialize package source and resource directories
9707        final File scanFile = new File(pkg.codePath);
9708        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9709        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9710
9711        SharedUserSetting suid = null;
9712        PackageSetting pkgSetting = null;
9713
9714        // Getting the package setting may have a side-effect, so if we
9715        // are only checking if scan would succeed, stash a copy of the
9716        // old setting to restore at the end.
9717        PackageSetting nonMutatedPs = null;
9718
9719        // We keep references to the derived CPU Abis from settings in oder to reuse
9720        // them in the case where we're not upgrading or booting for the first time.
9721        String primaryCpuAbiFromSettings = null;
9722        String secondaryCpuAbiFromSettings = null;
9723
9724        // writer
9725        synchronized (mPackages) {
9726            if (pkg.mSharedUserId != null) {
9727                // SIDE EFFECTS; may potentially allocate a new shared user
9728                suid = mSettings.getSharedUserLPw(
9729                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9730                if (DEBUG_PACKAGE_SCANNING) {
9731                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9732                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9733                                + "): packages=" + suid.packages);
9734                }
9735            }
9736
9737            // Check if we are renaming from an original package name.
9738            PackageSetting origPackage = null;
9739            String realName = null;
9740            if (pkg.mOriginalPackages != null) {
9741                // This package may need to be renamed to a previously
9742                // installed name.  Let's check on that...
9743                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9744                if (pkg.mOriginalPackages.contains(renamed)) {
9745                    // This package had originally been installed as the
9746                    // original name, and we have already taken care of
9747                    // transitioning to the new one.  Just update the new
9748                    // one to continue using the old name.
9749                    realName = pkg.mRealPackage;
9750                    if (!pkg.packageName.equals(renamed)) {
9751                        // Callers into this function may have already taken
9752                        // care of renaming the package; only do it here if
9753                        // it is not already done.
9754                        pkg.setPackageName(renamed);
9755                    }
9756                } else {
9757                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9758                        if ((origPackage = mSettings.getPackageLPr(
9759                                pkg.mOriginalPackages.get(i))) != null) {
9760                            // We do have the package already installed under its
9761                            // original name...  should we use it?
9762                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9763                                // New package is not compatible with original.
9764                                origPackage = null;
9765                                continue;
9766                            } else if (origPackage.sharedUser != null) {
9767                                // Make sure uid is compatible between packages.
9768                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9769                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9770                                            + " to " + pkg.packageName + ": old uid "
9771                                            + origPackage.sharedUser.name
9772                                            + " differs from " + pkg.mSharedUserId);
9773                                    origPackage = null;
9774                                    continue;
9775                                }
9776                                // TODO: Add case when shared user id is added [b/28144775]
9777                            } else {
9778                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9779                                        + pkg.packageName + " to old name " + origPackage.name);
9780                            }
9781                            break;
9782                        }
9783                    }
9784                }
9785            }
9786
9787            if (mTransferedPackages.contains(pkg.packageName)) {
9788                Slog.w(TAG, "Package " + pkg.packageName
9789                        + " was transferred to another, but its .apk remains");
9790            }
9791
9792            // See comments in nonMutatedPs declaration
9793            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9794                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9795                if (foundPs != null) {
9796                    nonMutatedPs = new PackageSetting(foundPs);
9797                }
9798            }
9799
9800            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9801                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9802                if (foundPs != null) {
9803                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9804                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9805                }
9806            }
9807
9808            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9809            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9810                PackageManagerService.reportSettingsProblem(Log.WARN,
9811                        "Package " + pkg.packageName + " shared user changed from "
9812                                + (pkgSetting.sharedUser != null
9813                                        ? pkgSetting.sharedUser.name : "<nothing>")
9814                                + " to "
9815                                + (suid != null ? suid.name : "<nothing>")
9816                                + "; replacing with new");
9817                pkgSetting = null;
9818            }
9819            final PackageSetting oldPkgSetting =
9820                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9821            final PackageSetting disabledPkgSetting =
9822                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9823
9824            String[] usesStaticLibraries = null;
9825            if (pkg.usesStaticLibraries != null) {
9826                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9827                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9828            }
9829
9830            if (pkgSetting == null) {
9831                final String parentPackageName = (pkg.parentPackage != null)
9832                        ? pkg.parentPackage.packageName : null;
9833                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9834                // REMOVE SharedUserSetting from method; update in a separate call
9835                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9836                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9837                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9838                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9839                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9840                        true /*allowInstall*/, instantApp, parentPackageName,
9841                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
9842                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9843                // SIDE EFFECTS; updates system state; move elsewhere
9844                if (origPackage != null) {
9845                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9846                }
9847                mSettings.addUserToSettingLPw(pkgSetting);
9848            } else {
9849                // REMOVE SharedUserSetting from method; update in a separate call.
9850                //
9851                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9852                // secondaryCpuAbi are not known at this point so we always update them
9853                // to null here, only to reset them at a later point.
9854                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9855                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9856                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9857                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9858                        UserManagerService.getInstance(), usesStaticLibraries,
9859                        pkg.usesStaticLibrariesVersions);
9860            }
9861            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9862            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9863
9864            // SIDE EFFECTS; modifies system state; move elsewhere
9865            if (pkgSetting.origPackage != null) {
9866                // If we are first transitioning from an original package,
9867                // fix up the new package's name now.  We need to do this after
9868                // looking up the package under its new name, so getPackageLP
9869                // can take care of fiddling things correctly.
9870                pkg.setPackageName(origPackage.name);
9871
9872                // File a report about this.
9873                String msg = "New package " + pkgSetting.realName
9874                        + " renamed to replace old package " + pkgSetting.name;
9875                reportSettingsProblem(Log.WARN, msg);
9876
9877                // Make a note of it.
9878                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9879                    mTransferedPackages.add(origPackage.name);
9880                }
9881
9882                // No longer need to retain this.
9883                pkgSetting.origPackage = null;
9884            }
9885
9886            // SIDE EFFECTS; modifies system state; move elsewhere
9887            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9888                // Make a note of it.
9889                mTransferedPackages.add(pkg.packageName);
9890            }
9891
9892            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9893                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9894            }
9895
9896            if ((scanFlags & SCAN_BOOTING) == 0
9897                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9898                // Check all shared libraries and map to their actual file path.
9899                // We only do this here for apps not on a system dir, because those
9900                // are the only ones that can fail an install due to this.  We
9901                // will take care of the system apps by updating all of their
9902                // library paths after the scan is done. Also during the initial
9903                // scan don't update any libs as we do this wholesale after all
9904                // apps are scanned to avoid dependency based scanning.
9905                updateSharedLibrariesLPr(pkg, null);
9906            }
9907
9908            if (mFoundPolicyFile) {
9909                SELinuxMMAC.assignSeInfoValue(pkg);
9910            }
9911            pkg.applicationInfo.uid = pkgSetting.appId;
9912            pkg.mExtras = pkgSetting;
9913
9914
9915            // Static shared libs have same package with different versions where
9916            // we internally use a synthetic package name to allow multiple versions
9917            // of the same package, therefore we need to compare signatures against
9918            // the package setting for the latest library version.
9919            PackageSetting signatureCheckPs = pkgSetting;
9920            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9921                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9922                if (libraryEntry != null) {
9923                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9924                }
9925            }
9926
9927            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9928                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9929                    // We just determined the app is signed correctly, so bring
9930                    // over the latest parsed certs.
9931                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9932                } else {
9933                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9934                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9935                                "Package " + pkg.packageName + " upgrade keys do not match the "
9936                                + "previously installed version");
9937                    } else {
9938                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9939                        String msg = "System package " + pkg.packageName
9940                                + " signature changed; retaining data.";
9941                        reportSettingsProblem(Log.WARN, msg);
9942                    }
9943                }
9944            } else {
9945                try {
9946                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9947                    verifySignaturesLP(signatureCheckPs, pkg);
9948                    // We just determined the app is signed correctly, so bring
9949                    // over the latest parsed certs.
9950                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9951                } catch (PackageManagerException e) {
9952                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9953                        throw e;
9954                    }
9955                    // The signature has changed, but this package is in the system
9956                    // image...  let's recover!
9957                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9958                    // However...  if this package is part of a shared user, but it
9959                    // doesn't match the signature of the shared user, let's fail.
9960                    // What this means is that you can't change the signatures
9961                    // associated with an overall shared user, which doesn't seem all
9962                    // that unreasonable.
9963                    if (signatureCheckPs.sharedUser != null) {
9964                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9965                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9966                            throw new PackageManagerException(
9967                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9968                                    "Signature mismatch for shared user: "
9969                                            + pkgSetting.sharedUser);
9970                        }
9971                    }
9972                    // File a report about this.
9973                    String msg = "System package " + pkg.packageName
9974                            + " signature changed; retaining data.";
9975                    reportSettingsProblem(Log.WARN, msg);
9976                }
9977            }
9978
9979            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9980                // This package wants to adopt ownership of permissions from
9981                // another package.
9982                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9983                    final String origName = pkg.mAdoptPermissions.get(i);
9984                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9985                    if (orig != null) {
9986                        if (verifyPackageUpdateLPr(orig, pkg)) {
9987                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9988                                    + pkg.packageName);
9989                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9990                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
9991                        }
9992                    }
9993                }
9994            }
9995        }
9996
9997        pkg.applicationInfo.processName = fixProcessName(
9998                pkg.applicationInfo.packageName,
9999                pkg.applicationInfo.processName);
10000
10001        if (pkg != mPlatformPackage) {
10002            // Get all of our default paths setup
10003            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10004        }
10005
10006        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10007
10008        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10009            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10010                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10011                derivePackageAbi(
10012                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
10013                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10014
10015                // Some system apps still use directory structure for native libraries
10016                // in which case we might end up not detecting abi solely based on apk
10017                // structure. Try to detect abi based on directory structure.
10018                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10019                        pkg.applicationInfo.primaryCpuAbi == null) {
10020                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10021                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10022                }
10023            } else {
10024                // This is not a first boot or an upgrade, don't bother deriving the
10025                // ABI during the scan. Instead, trust the value that was stored in the
10026                // package setting.
10027                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10028                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10029
10030                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10031
10032                if (DEBUG_ABI_SELECTION) {
10033                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10034                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10035                        pkg.applicationInfo.secondaryCpuAbi);
10036                }
10037            }
10038        } else {
10039            if ((scanFlags & SCAN_MOVE) != 0) {
10040                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10041                // but we already have this packages package info in the PackageSetting. We just
10042                // use that and derive the native library path based on the new codepath.
10043                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10044                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10045            }
10046
10047            // Set native library paths again. For moves, the path will be updated based on the
10048            // ABIs we've determined above. For non-moves, the path will be updated based on the
10049            // ABIs we determined during compilation, but the path will depend on the final
10050            // package path (after the rename away from the stage path).
10051            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10052        }
10053
10054        // This is a special case for the "system" package, where the ABI is
10055        // dictated by the zygote configuration (and init.rc). We should keep track
10056        // of this ABI so that we can deal with "normal" applications that run under
10057        // the same UID correctly.
10058        if (mPlatformPackage == pkg) {
10059            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10060                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10061        }
10062
10063        // If there's a mismatch between the abi-override in the package setting
10064        // and the abiOverride specified for the install. Warn about this because we
10065        // would've already compiled the app without taking the package setting into
10066        // account.
10067        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10068            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10069                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10070                        " for package " + pkg.packageName);
10071            }
10072        }
10073
10074        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10075        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10076        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10077
10078        // Copy the derived override back to the parsed package, so that we can
10079        // update the package settings accordingly.
10080        pkg.cpuAbiOverride = cpuAbiOverride;
10081
10082        if (DEBUG_ABI_SELECTION) {
10083            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10084                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10085                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10086        }
10087
10088        // Push the derived path down into PackageSettings so we know what to
10089        // clean up at uninstall time.
10090        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10091
10092        if (DEBUG_ABI_SELECTION) {
10093            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10094                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10095                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10096        }
10097
10098        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10099        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10100            // We don't do this here during boot because we can do it all
10101            // at once after scanning all existing packages.
10102            //
10103            // We also do this *before* we perform dexopt on this package, so that
10104            // we can avoid redundant dexopts, and also to make sure we've got the
10105            // code and package path correct.
10106            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10107        }
10108
10109        if (mFactoryTest && pkg.requestedPermissions.contains(
10110                android.Manifest.permission.FACTORY_TEST)) {
10111            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10112        }
10113
10114        if (isSystemApp(pkg)) {
10115            pkgSetting.isOrphaned = true;
10116        }
10117
10118        // Take care of first install / last update times.
10119        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10120        if (currentTime != 0) {
10121            if (pkgSetting.firstInstallTime == 0) {
10122                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10123            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10124                pkgSetting.lastUpdateTime = currentTime;
10125            }
10126        } else if (pkgSetting.firstInstallTime == 0) {
10127            // We need *something*.  Take time time stamp of the file.
10128            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10129        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10130            if (scanFileTime != pkgSetting.timeStamp) {
10131                // A package on the system image has changed; consider this
10132                // to be an update.
10133                pkgSetting.lastUpdateTime = scanFileTime;
10134            }
10135        }
10136        pkgSetting.setTimeStamp(scanFileTime);
10137
10138        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10139            if (nonMutatedPs != null) {
10140                synchronized (mPackages) {
10141                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10142                }
10143            }
10144        } else {
10145            final int userId = user == null ? 0 : user.getIdentifier();
10146            // Modify state for the given package setting
10147            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10148                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10149            if (pkgSetting.getInstantApp(userId)) {
10150                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10151            }
10152        }
10153        return pkg;
10154    }
10155
10156    /**
10157     * Applies policy to the parsed package based upon the given policy flags.
10158     * Ensures the package is in a good state.
10159     * <p>
10160     * Implementation detail: This method must NOT have any side effect. It would
10161     * ideally be static, but, it requires locks to read system state.
10162     */
10163    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10164        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10165            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10166            if (pkg.applicationInfo.isDirectBootAware()) {
10167                // we're direct boot aware; set for all components
10168                for (PackageParser.Service s : pkg.services) {
10169                    s.info.encryptionAware = s.info.directBootAware = true;
10170                }
10171                for (PackageParser.Provider p : pkg.providers) {
10172                    p.info.encryptionAware = p.info.directBootAware = true;
10173                }
10174                for (PackageParser.Activity a : pkg.activities) {
10175                    a.info.encryptionAware = a.info.directBootAware = true;
10176                }
10177                for (PackageParser.Activity r : pkg.receivers) {
10178                    r.info.encryptionAware = r.info.directBootAware = true;
10179                }
10180            }
10181        } else {
10182            // Only allow system apps to be flagged as core apps.
10183            pkg.coreApp = false;
10184            // clear flags not applicable to regular apps
10185            pkg.applicationInfo.privateFlags &=
10186                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10187            pkg.applicationInfo.privateFlags &=
10188                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10189        }
10190        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10191
10192        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10193            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10194        }
10195
10196        if (!isSystemApp(pkg)) {
10197            // Only system apps can use these features.
10198            pkg.mOriginalPackages = null;
10199            pkg.mRealPackage = null;
10200            pkg.mAdoptPermissions = null;
10201        }
10202    }
10203
10204    /**
10205     * Asserts the parsed package is valid according to the given policy. If the
10206     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10207     * <p>
10208     * Implementation detail: This method must NOT have any side effects. It would
10209     * ideally be static, but, it requires locks to read system state.
10210     *
10211     * @throws PackageManagerException If the package fails any of the validation checks
10212     */
10213    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10214            throws PackageManagerException {
10215        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10216            assertCodePolicy(pkg);
10217        }
10218
10219        if (pkg.applicationInfo.getCodePath() == null ||
10220                pkg.applicationInfo.getResourcePath() == null) {
10221            // Bail out. The resource and code paths haven't been set.
10222            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10223                    "Code and resource paths haven't been set correctly");
10224        }
10225
10226        // Make sure we're not adding any bogus keyset info
10227        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10228        ksms.assertScannedPackageValid(pkg);
10229
10230        synchronized (mPackages) {
10231            // The special "android" package can only be defined once
10232            if (pkg.packageName.equals("android")) {
10233                if (mAndroidApplication != null) {
10234                    Slog.w(TAG, "*************************************************");
10235                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10236                    Slog.w(TAG, " codePath=" + pkg.codePath);
10237                    Slog.w(TAG, "*************************************************");
10238                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10239                            "Core android package being redefined.  Skipping.");
10240                }
10241            }
10242
10243            // A package name must be unique; don't allow duplicates
10244            if (mPackages.containsKey(pkg.packageName)) {
10245                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10246                        "Application package " + pkg.packageName
10247                        + " already installed.  Skipping duplicate.");
10248            }
10249
10250            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10251                // Static libs have a synthetic package name containing the version
10252                // but we still want the base name to be unique.
10253                if (mPackages.containsKey(pkg.manifestPackageName)) {
10254                    throw new PackageManagerException(
10255                            "Duplicate static shared lib provider package");
10256                }
10257
10258                // Static shared libraries should have at least O target SDK
10259                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10260                    throw new PackageManagerException(
10261                            "Packages declaring static-shared libs must target O SDK or higher");
10262                }
10263
10264                // Package declaring static a shared lib cannot be instant apps
10265                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10266                    throw new PackageManagerException(
10267                            "Packages declaring static-shared libs cannot be instant apps");
10268                }
10269
10270                // Package declaring static a shared lib cannot be renamed since the package
10271                // name is synthetic and apps can't code around package manager internals.
10272                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10273                    throw new PackageManagerException(
10274                            "Packages declaring static-shared libs cannot be renamed");
10275                }
10276
10277                // Package declaring static a shared lib cannot declare child packages
10278                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10279                    throw new PackageManagerException(
10280                            "Packages declaring static-shared libs cannot have child packages");
10281                }
10282
10283                // Package declaring static a shared lib cannot declare dynamic libs
10284                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10285                    throw new PackageManagerException(
10286                            "Packages declaring static-shared libs cannot declare dynamic libs");
10287                }
10288
10289                // Package declaring static a shared lib cannot declare shared users
10290                if (pkg.mSharedUserId != null) {
10291                    throw new PackageManagerException(
10292                            "Packages declaring static-shared libs cannot declare shared users");
10293                }
10294
10295                // Static shared libs cannot declare activities
10296                if (!pkg.activities.isEmpty()) {
10297                    throw new PackageManagerException(
10298                            "Static shared libs cannot declare activities");
10299                }
10300
10301                // Static shared libs cannot declare services
10302                if (!pkg.services.isEmpty()) {
10303                    throw new PackageManagerException(
10304                            "Static shared libs cannot declare services");
10305                }
10306
10307                // Static shared libs cannot declare providers
10308                if (!pkg.providers.isEmpty()) {
10309                    throw new PackageManagerException(
10310                            "Static shared libs cannot declare content providers");
10311                }
10312
10313                // Static shared libs cannot declare receivers
10314                if (!pkg.receivers.isEmpty()) {
10315                    throw new PackageManagerException(
10316                            "Static shared libs cannot declare broadcast receivers");
10317                }
10318
10319                // Static shared libs cannot declare permission groups
10320                if (!pkg.permissionGroups.isEmpty()) {
10321                    throw new PackageManagerException(
10322                            "Static shared libs cannot declare permission groups");
10323                }
10324
10325                // Static shared libs cannot declare permissions
10326                if (!pkg.permissions.isEmpty()) {
10327                    throw new PackageManagerException(
10328                            "Static shared libs cannot declare permissions");
10329                }
10330
10331                // Static shared libs cannot declare protected broadcasts
10332                if (pkg.protectedBroadcasts != null) {
10333                    throw new PackageManagerException(
10334                            "Static shared libs cannot declare protected broadcasts");
10335                }
10336
10337                // Static shared libs cannot be overlay targets
10338                if (pkg.mOverlayTarget != null) {
10339                    throw new PackageManagerException(
10340                            "Static shared libs cannot be overlay targets");
10341                }
10342
10343                // The version codes must be ordered as lib versions
10344                int minVersionCode = Integer.MIN_VALUE;
10345                int maxVersionCode = Integer.MAX_VALUE;
10346
10347                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10348                        pkg.staticSharedLibName);
10349                if (versionedLib != null) {
10350                    final int versionCount = versionedLib.size();
10351                    for (int i = 0; i < versionCount; i++) {
10352                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10353                        // TODO: We will change version code to long, so in the new API it is long
10354                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
10355                                .getVersionCode();
10356                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
10357                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10358                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
10359                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10360                        } else {
10361                            minVersionCode = maxVersionCode = libVersionCode;
10362                            break;
10363                        }
10364                    }
10365                }
10366                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
10367                    throw new PackageManagerException("Static shared"
10368                            + " lib version codes must be ordered as lib versions");
10369                }
10370            }
10371
10372            // Only privileged apps and updated privileged apps can add child packages.
10373            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10374                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
10375                    throw new PackageManagerException("Only privileged apps can add child "
10376                            + "packages. Ignoring package " + pkg.packageName);
10377                }
10378                final int childCount = pkg.childPackages.size();
10379                for (int i = 0; i < childCount; i++) {
10380                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10381                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10382                            childPkg.packageName)) {
10383                        throw new PackageManagerException("Can't override child of "
10384                                + "another disabled app. Ignoring package " + pkg.packageName);
10385                    }
10386                }
10387            }
10388
10389            // If we're only installing presumed-existing packages, require that the
10390            // scanned APK is both already known and at the path previously established
10391            // for it.  Previously unknown packages we pick up normally, but if we have an
10392            // a priori expectation about this package's install presence, enforce it.
10393            // With a singular exception for new system packages. When an OTA contains
10394            // a new system package, we allow the codepath to change from a system location
10395            // to the user-installed location. If we don't allow this change, any newer,
10396            // user-installed version of the application will be ignored.
10397            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10398                if (mExpectingBetter.containsKey(pkg.packageName)) {
10399                    logCriticalInfo(Log.WARN,
10400                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10401                } else {
10402                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10403                    if (known != null) {
10404                        if (DEBUG_PACKAGE_SCANNING) {
10405                            Log.d(TAG, "Examining " + pkg.codePath
10406                                    + " and requiring known paths " + known.codePathString
10407                                    + " & " + known.resourcePathString);
10408                        }
10409                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10410                                || !pkg.applicationInfo.getResourcePath().equals(
10411                                        known.resourcePathString)) {
10412                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10413                                    "Application package " + pkg.packageName
10414                                    + " found at " + pkg.applicationInfo.getCodePath()
10415                                    + " but expected at " + known.codePathString
10416                                    + "; ignoring.");
10417                        }
10418                    }
10419                }
10420            }
10421
10422            // Verify that this new package doesn't have any content providers
10423            // that conflict with existing packages.  Only do this if the
10424            // package isn't already installed, since we don't want to break
10425            // things that are installed.
10426            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10427                final int N = pkg.providers.size();
10428                int i;
10429                for (i=0; i<N; i++) {
10430                    PackageParser.Provider p = pkg.providers.get(i);
10431                    if (p.info.authority != null) {
10432                        String names[] = p.info.authority.split(";");
10433                        for (int j = 0; j < names.length; j++) {
10434                            if (mProvidersByAuthority.containsKey(names[j])) {
10435                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10436                                final String otherPackageName =
10437                                        ((other != null && other.getComponentName() != null) ?
10438                                                other.getComponentName().getPackageName() : "?");
10439                                throw new PackageManagerException(
10440                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10441                                        "Can't install because provider name " + names[j]
10442                                                + " (in package " + pkg.applicationInfo.packageName
10443                                                + ") is already used by " + otherPackageName);
10444                            }
10445                        }
10446                    }
10447                }
10448            }
10449        }
10450    }
10451
10452    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10453            int type, String declaringPackageName, int declaringVersionCode) {
10454        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10455        if (versionedLib == null) {
10456            versionedLib = new SparseArray<>();
10457            mSharedLibraries.put(name, versionedLib);
10458            if (type == SharedLibraryInfo.TYPE_STATIC) {
10459                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10460            }
10461        } else if (versionedLib.indexOfKey(version) >= 0) {
10462            return false;
10463        }
10464        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10465                version, type, declaringPackageName, declaringVersionCode);
10466        versionedLib.put(version, libEntry);
10467        return true;
10468    }
10469
10470    private boolean removeSharedLibraryLPw(String name, int version) {
10471        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10472        if (versionedLib == null) {
10473            return false;
10474        }
10475        final int libIdx = versionedLib.indexOfKey(version);
10476        if (libIdx < 0) {
10477            return false;
10478        }
10479        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10480        versionedLib.remove(version);
10481        if (versionedLib.size() <= 0) {
10482            mSharedLibraries.remove(name);
10483            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10484                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10485                        .getPackageName());
10486            }
10487        }
10488        return true;
10489    }
10490
10491    /**
10492     * Adds a scanned package to the system. When this method is finished, the package will
10493     * be available for query, resolution, etc...
10494     */
10495    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10496            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10497        final String pkgName = pkg.packageName;
10498        if (mCustomResolverComponentName != null &&
10499                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10500            setUpCustomResolverActivity(pkg);
10501        }
10502
10503        if (pkg.packageName.equals("android")) {
10504            synchronized (mPackages) {
10505                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10506                    // Set up information for our fall-back user intent resolution activity.
10507                    mPlatformPackage = pkg;
10508                    pkg.mVersionCode = mSdkVersion;
10509                    mAndroidApplication = pkg.applicationInfo;
10510                    if (!mResolverReplaced) {
10511                        mResolveActivity.applicationInfo = mAndroidApplication;
10512                        mResolveActivity.name = ResolverActivity.class.getName();
10513                        mResolveActivity.packageName = mAndroidApplication.packageName;
10514                        mResolveActivity.processName = "system:ui";
10515                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10516                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10517                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10518                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10519                        mResolveActivity.exported = true;
10520                        mResolveActivity.enabled = true;
10521                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10522                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10523                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10524                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10525                                | ActivityInfo.CONFIG_ORIENTATION
10526                                | ActivityInfo.CONFIG_KEYBOARD
10527                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10528                        mResolveInfo.activityInfo = mResolveActivity;
10529                        mResolveInfo.priority = 0;
10530                        mResolveInfo.preferredOrder = 0;
10531                        mResolveInfo.match = 0;
10532                        mResolveComponentName = new ComponentName(
10533                                mAndroidApplication.packageName, mResolveActivity.name);
10534                    }
10535                }
10536            }
10537        }
10538
10539        ArrayList<PackageParser.Package> clientLibPkgs = null;
10540        // writer
10541        synchronized (mPackages) {
10542            boolean hasStaticSharedLibs = false;
10543
10544            // Any app can add new static shared libraries
10545            if (pkg.staticSharedLibName != null) {
10546                // Static shared libs don't allow renaming as they have synthetic package
10547                // names to allow install of multiple versions, so use name from manifest.
10548                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10549                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10550                        pkg.manifestPackageName, pkg.mVersionCode)) {
10551                    hasStaticSharedLibs = true;
10552                } else {
10553                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10554                                + pkg.staticSharedLibName + " already exists; skipping");
10555                }
10556                // Static shared libs cannot be updated once installed since they
10557                // use synthetic package name which includes the version code, so
10558                // not need to update other packages's shared lib dependencies.
10559            }
10560
10561            if (!hasStaticSharedLibs
10562                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10563                // Only system apps can add new dynamic shared libraries.
10564                if (pkg.libraryNames != null) {
10565                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10566                        String name = pkg.libraryNames.get(i);
10567                        boolean allowed = false;
10568                        if (pkg.isUpdatedSystemApp()) {
10569                            // New library entries can only be added through the
10570                            // system image.  This is important to get rid of a lot
10571                            // of nasty edge cases: for example if we allowed a non-
10572                            // system update of the app to add a library, then uninstalling
10573                            // the update would make the library go away, and assumptions
10574                            // we made such as through app install filtering would now
10575                            // have allowed apps on the device which aren't compatible
10576                            // with it.  Better to just have the restriction here, be
10577                            // conservative, and create many fewer cases that can negatively
10578                            // impact the user experience.
10579                            final PackageSetting sysPs = mSettings
10580                                    .getDisabledSystemPkgLPr(pkg.packageName);
10581                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10582                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10583                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10584                                        allowed = true;
10585                                        break;
10586                                    }
10587                                }
10588                            }
10589                        } else {
10590                            allowed = true;
10591                        }
10592                        if (allowed) {
10593                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10594                                    SharedLibraryInfo.VERSION_UNDEFINED,
10595                                    SharedLibraryInfo.TYPE_DYNAMIC,
10596                                    pkg.packageName, pkg.mVersionCode)) {
10597                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10598                                        + name + " already exists; skipping");
10599                            }
10600                        } else {
10601                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10602                                    + name + " that is not declared on system image; skipping");
10603                        }
10604                    }
10605
10606                    if ((scanFlags & SCAN_BOOTING) == 0) {
10607                        // If we are not booting, we need to update any applications
10608                        // that are clients of our shared library.  If we are booting,
10609                        // this will all be done once the scan is complete.
10610                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10611                    }
10612                }
10613            }
10614        }
10615
10616        if ((scanFlags & SCAN_BOOTING) != 0) {
10617            // No apps can run during boot scan, so they don't need to be frozen
10618        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10619            // Caller asked to not kill app, so it's probably not frozen
10620        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10621            // Caller asked us to ignore frozen check for some reason; they
10622            // probably didn't know the package name
10623        } else {
10624            // We're doing major surgery on this package, so it better be frozen
10625            // right now to keep it from launching
10626            checkPackageFrozen(pkgName);
10627        }
10628
10629        // Also need to kill any apps that are dependent on the library.
10630        if (clientLibPkgs != null) {
10631            for (int i=0; i<clientLibPkgs.size(); i++) {
10632                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10633                killApplication(clientPkg.applicationInfo.packageName,
10634                        clientPkg.applicationInfo.uid, "update lib");
10635            }
10636        }
10637
10638        // writer
10639        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10640
10641        synchronized (mPackages) {
10642            // We don't expect installation to fail beyond this point
10643
10644            // Add the new setting to mSettings
10645            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10646            // Add the new setting to mPackages
10647            mPackages.put(pkg.applicationInfo.packageName, pkg);
10648            // Make sure we don't accidentally delete its data.
10649            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10650            while (iter.hasNext()) {
10651                PackageCleanItem item = iter.next();
10652                if (pkgName.equals(item.packageName)) {
10653                    iter.remove();
10654                }
10655            }
10656
10657            // Add the package's KeySets to the global KeySetManagerService
10658            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10659            ksms.addScannedPackageLPw(pkg);
10660
10661            int N = pkg.providers.size();
10662            StringBuilder r = null;
10663            int i;
10664            for (i=0; i<N; i++) {
10665                PackageParser.Provider p = pkg.providers.get(i);
10666                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10667                        p.info.processName);
10668                mProviders.addProvider(p);
10669                p.syncable = p.info.isSyncable;
10670                if (p.info.authority != null) {
10671                    String names[] = p.info.authority.split(";");
10672                    p.info.authority = null;
10673                    for (int j = 0; j < names.length; j++) {
10674                        if (j == 1 && p.syncable) {
10675                            // We only want the first authority for a provider to possibly be
10676                            // syncable, so if we already added this provider using a different
10677                            // authority clear the syncable flag. We copy the provider before
10678                            // changing it because the mProviders object contains a reference
10679                            // to a provider that we don't want to change.
10680                            // Only do this for the second authority since the resulting provider
10681                            // object can be the same for all future authorities for this provider.
10682                            p = new PackageParser.Provider(p);
10683                            p.syncable = false;
10684                        }
10685                        if (!mProvidersByAuthority.containsKey(names[j])) {
10686                            mProvidersByAuthority.put(names[j], p);
10687                            if (p.info.authority == null) {
10688                                p.info.authority = names[j];
10689                            } else {
10690                                p.info.authority = p.info.authority + ";" + names[j];
10691                            }
10692                            if (DEBUG_PACKAGE_SCANNING) {
10693                                if (chatty)
10694                                    Log.d(TAG, "Registered content provider: " + names[j]
10695                                            + ", className = " + p.info.name + ", isSyncable = "
10696                                            + p.info.isSyncable);
10697                            }
10698                        } else {
10699                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10700                            Slog.w(TAG, "Skipping provider name " + names[j] +
10701                                    " (in package " + pkg.applicationInfo.packageName +
10702                                    "): name already used by "
10703                                    + ((other != null && other.getComponentName() != null)
10704                                            ? other.getComponentName().getPackageName() : "?"));
10705                        }
10706                    }
10707                }
10708                if (chatty) {
10709                    if (r == null) {
10710                        r = new StringBuilder(256);
10711                    } else {
10712                        r.append(' ');
10713                    }
10714                    r.append(p.info.name);
10715                }
10716            }
10717            if (r != null) {
10718                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10719            }
10720
10721            N = pkg.services.size();
10722            r = null;
10723            for (i=0; i<N; i++) {
10724                PackageParser.Service s = pkg.services.get(i);
10725                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10726                        s.info.processName);
10727                mServices.addService(s);
10728                if (chatty) {
10729                    if (r == null) {
10730                        r = new StringBuilder(256);
10731                    } else {
10732                        r.append(' ');
10733                    }
10734                    r.append(s.info.name);
10735                }
10736            }
10737            if (r != null) {
10738                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10739            }
10740
10741            N = pkg.receivers.size();
10742            r = null;
10743            for (i=0; i<N; i++) {
10744                PackageParser.Activity a = pkg.receivers.get(i);
10745                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10746                        a.info.processName);
10747                mReceivers.addActivity(a, "receiver");
10748                if (chatty) {
10749                    if (r == null) {
10750                        r = new StringBuilder(256);
10751                    } else {
10752                        r.append(' ');
10753                    }
10754                    r.append(a.info.name);
10755                }
10756            }
10757            if (r != null) {
10758                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10759            }
10760
10761            N = pkg.activities.size();
10762            r = null;
10763            for (i=0; i<N; i++) {
10764                PackageParser.Activity a = pkg.activities.get(i);
10765                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10766                        a.info.processName);
10767                mActivities.addActivity(a, "activity");
10768                if (chatty) {
10769                    if (r == null) {
10770                        r = new StringBuilder(256);
10771                    } else {
10772                        r.append(' ');
10773                    }
10774                    r.append(a.info.name);
10775                }
10776            }
10777            if (r != null) {
10778                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10779            }
10780
10781            N = pkg.permissionGroups.size();
10782            r = null;
10783            for (i=0; i<N; i++) {
10784                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10785                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10786                final String curPackageName = cur == null ? null : cur.info.packageName;
10787                // Dont allow ephemeral apps to define new permission groups.
10788                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10789                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10790                            + pg.info.packageName
10791                            + " ignored: instant apps cannot define new permission groups.");
10792                    continue;
10793                }
10794                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10795                if (cur == null || isPackageUpdate) {
10796                    mPermissionGroups.put(pg.info.name, pg);
10797                    if (chatty) {
10798                        if (r == null) {
10799                            r = new StringBuilder(256);
10800                        } else {
10801                            r.append(' ');
10802                        }
10803                        if (isPackageUpdate) {
10804                            r.append("UPD:");
10805                        }
10806                        r.append(pg.info.name);
10807                    }
10808                } else {
10809                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10810                            + pg.info.packageName + " ignored: original from "
10811                            + cur.info.packageName);
10812                    if (chatty) {
10813                        if (r == null) {
10814                            r = new StringBuilder(256);
10815                        } else {
10816                            r.append(' ');
10817                        }
10818                        r.append("DUP:");
10819                        r.append(pg.info.name);
10820                    }
10821                }
10822            }
10823            if (r != null) {
10824                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10825            }
10826
10827            N = pkg.permissions.size();
10828            r = null;
10829            for (i=0; i<N; i++) {
10830                PackageParser.Permission p = pkg.permissions.get(i);
10831
10832                // Dont allow ephemeral apps to define new permissions.
10833                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10834                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10835                            + p.info.packageName
10836                            + " ignored: instant apps cannot define new permissions.");
10837                    continue;
10838                }
10839
10840                // Assume by default that we did not install this permission into the system.
10841                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10842
10843                // Now that permission groups have a special meaning, we ignore permission
10844                // groups for legacy apps to prevent unexpected behavior. In particular,
10845                // permissions for one app being granted to someone just because they happen
10846                // to be in a group defined by another app (before this had no implications).
10847                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10848                    p.group = mPermissionGroups.get(p.info.group);
10849                    // Warn for a permission in an unknown group.
10850                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
10851                        Slog.i(TAG, "Permission " + p.info.name + " from package "
10852                                + p.info.packageName + " in an unknown group " + p.info.group);
10853                    }
10854                }
10855
10856                ArrayMap<String, BasePermission> permissionMap =
10857                        p.tree ? mSettings.mPermissionTrees
10858                                : mSettings.mPermissions;
10859                BasePermission bp = permissionMap.get(p.info.name);
10860
10861                // Allow system apps to redefine non-system permissions
10862                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10863                    final boolean currentOwnerIsSystem = (bp.perm != null
10864                            && isSystemApp(bp.perm.owner));
10865                    if (isSystemApp(p.owner)) {
10866                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10867                            // It's a built-in permission and no owner, take ownership now
10868                            bp.packageSetting = pkgSetting;
10869                            bp.perm = p;
10870                            bp.uid = pkg.applicationInfo.uid;
10871                            bp.sourcePackage = p.info.packageName;
10872                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10873                        } else if (!currentOwnerIsSystem) {
10874                            String msg = "New decl " + p.owner + " of permission  "
10875                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10876                            reportSettingsProblem(Log.WARN, msg);
10877                            bp = null;
10878                        }
10879                    }
10880                }
10881
10882                if (bp == null) {
10883                    bp = new BasePermission(p.info.name, p.info.packageName,
10884                            BasePermission.TYPE_NORMAL);
10885                    permissionMap.put(p.info.name, bp);
10886                }
10887
10888                if (bp.perm == null) {
10889                    if (bp.sourcePackage == null
10890                            || bp.sourcePackage.equals(p.info.packageName)) {
10891                        BasePermission tree = findPermissionTreeLP(p.info.name);
10892                        if (tree == null
10893                                || tree.sourcePackage.equals(p.info.packageName)) {
10894                            bp.packageSetting = pkgSetting;
10895                            bp.perm = p;
10896                            bp.uid = pkg.applicationInfo.uid;
10897                            bp.sourcePackage = p.info.packageName;
10898                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10899                            if (chatty) {
10900                                if (r == null) {
10901                                    r = new StringBuilder(256);
10902                                } else {
10903                                    r.append(' ');
10904                                }
10905                                r.append(p.info.name);
10906                            }
10907                        } else {
10908                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10909                                    + p.info.packageName + " ignored: base tree "
10910                                    + tree.name + " is from package "
10911                                    + tree.sourcePackage);
10912                        }
10913                    } else {
10914                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10915                                + p.info.packageName + " ignored: original from "
10916                                + bp.sourcePackage);
10917                    }
10918                } else if (chatty) {
10919                    if (r == null) {
10920                        r = new StringBuilder(256);
10921                    } else {
10922                        r.append(' ');
10923                    }
10924                    r.append("DUP:");
10925                    r.append(p.info.name);
10926                }
10927                if (bp.perm == p) {
10928                    bp.protectionLevel = p.info.protectionLevel;
10929                }
10930            }
10931
10932            if (r != null) {
10933                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10934            }
10935
10936            N = pkg.instrumentation.size();
10937            r = null;
10938            for (i=0; i<N; i++) {
10939                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10940                a.info.packageName = pkg.applicationInfo.packageName;
10941                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10942                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10943                a.info.splitNames = pkg.splitNames;
10944                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10945                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10946                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10947                a.info.dataDir = pkg.applicationInfo.dataDir;
10948                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10949                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10950                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10951                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10952                mInstrumentation.put(a.getComponentName(), a);
10953                if (chatty) {
10954                    if (r == null) {
10955                        r = new StringBuilder(256);
10956                    } else {
10957                        r.append(' ');
10958                    }
10959                    r.append(a.info.name);
10960                }
10961            }
10962            if (r != null) {
10963                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10964            }
10965
10966            if (pkg.protectedBroadcasts != null) {
10967                N = pkg.protectedBroadcasts.size();
10968                for (i=0; i<N; i++) {
10969                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10970                }
10971            }
10972        }
10973
10974        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10975    }
10976
10977    /**
10978     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10979     * is derived purely on the basis of the contents of {@code scanFile} and
10980     * {@code cpuAbiOverride}.
10981     *
10982     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10983     */
10984    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10985                                 String cpuAbiOverride, boolean extractLibs,
10986                                 File appLib32InstallDir)
10987            throws PackageManagerException {
10988        // Give ourselves some initial paths; we'll come back for another
10989        // pass once we've determined ABI below.
10990        setNativeLibraryPaths(pkg, appLib32InstallDir);
10991
10992        // We would never need to extract libs for forward-locked and external packages,
10993        // since the container service will do it for us. We shouldn't attempt to
10994        // extract libs from system app when it was not updated.
10995        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10996                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10997            extractLibs = false;
10998        }
10999
11000        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11001        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11002
11003        NativeLibraryHelper.Handle handle = null;
11004        try {
11005            handle = NativeLibraryHelper.Handle.create(pkg);
11006            // TODO(multiArch): This can be null for apps that didn't go through the
11007            // usual installation process. We can calculate it again, like we
11008            // do during install time.
11009            //
11010            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11011            // unnecessary.
11012            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11013
11014            // Null out the abis so that they can be recalculated.
11015            pkg.applicationInfo.primaryCpuAbi = null;
11016            pkg.applicationInfo.secondaryCpuAbi = null;
11017            if (isMultiArch(pkg.applicationInfo)) {
11018                // Warn if we've set an abiOverride for multi-lib packages..
11019                // By definition, we need to copy both 32 and 64 bit libraries for
11020                // such packages.
11021                if (pkg.cpuAbiOverride != null
11022                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11023                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11024                }
11025
11026                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11027                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11028                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11029                    if (extractLibs) {
11030                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11031                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11032                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11033                                useIsaSpecificSubdirs);
11034                    } else {
11035                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11036                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11037                    }
11038                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11039                }
11040
11041                maybeThrowExceptionForMultiArchCopy(
11042                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11043
11044                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11045                    if (extractLibs) {
11046                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11047                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11048                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11049                                useIsaSpecificSubdirs);
11050                    } else {
11051                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11052                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11053                    }
11054                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11055                }
11056
11057                maybeThrowExceptionForMultiArchCopy(
11058                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11059
11060                if (abi64 >= 0) {
11061                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11062                }
11063
11064                if (abi32 >= 0) {
11065                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11066                    if (abi64 >= 0) {
11067                        if (pkg.use32bitAbi) {
11068                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11069                            pkg.applicationInfo.primaryCpuAbi = abi;
11070                        } else {
11071                            pkg.applicationInfo.secondaryCpuAbi = abi;
11072                        }
11073                    } else {
11074                        pkg.applicationInfo.primaryCpuAbi = abi;
11075                    }
11076                }
11077
11078            } else {
11079                String[] abiList = (cpuAbiOverride != null) ?
11080                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11081
11082                // Enable gross and lame hacks for apps that are built with old
11083                // SDK tools. We must scan their APKs for renderscript bitcode and
11084                // not launch them if it's present. Don't bother checking on devices
11085                // that don't have 64 bit support.
11086                boolean needsRenderScriptOverride = false;
11087                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11088                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11089                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11090                    needsRenderScriptOverride = true;
11091                }
11092
11093                final int copyRet;
11094                if (extractLibs) {
11095                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11096                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11097                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11098                } else {
11099                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11100                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11101                }
11102                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11103
11104                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11105                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11106                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11107                }
11108
11109                if (copyRet >= 0) {
11110                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11111                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11112                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11113                } else if (needsRenderScriptOverride) {
11114                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11115                }
11116            }
11117        } catch (IOException ioe) {
11118            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11119        } finally {
11120            IoUtils.closeQuietly(handle);
11121        }
11122
11123        // Now that we've calculated the ABIs and determined if it's an internal app,
11124        // we will go ahead and populate the nativeLibraryPath.
11125        setNativeLibraryPaths(pkg, appLib32InstallDir);
11126    }
11127
11128    /**
11129     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11130     * i.e, so that all packages can be run inside a single process if required.
11131     *
11132     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11133     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11134     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11135     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11136     * updating a package that belongs to a shared user.
11137     *
11138     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11139     * adds unnecessary complexity.
11140     */
11141    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11142            PackageParser.Package scannedPackage) {
11143        String requiredInstructionSet = null;
11144        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11145            requiredInstructionSet = VMRuntime.getInstructionSet(
11146                     scannedPackage.applicationInfo.primaryCpuAbi);
11147        }
11148
11149        PackageSetting requirer = null;
11150        for (PackageSetting ps : packagesForUser) {
11151            // If packagesForUser contains scannedPackage, we skip it. This will happen
11152            // when scannedPackage is an update of an existing package. Without this check,
11153            // we will never be able to change the ABI of any package belonging to a shared
11154            // user, even if it's compatible with other packages.
11155            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11156                if (ps.primaryCpuAbiString == null) {
11157                    continue;
11158                }
11159
11160                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11161                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11162                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11163                    // this but there's not much we can do.
11164                    String errorMessage = "Instruction set mismatch, "
11165                            + ((requirer == null) ? "[caller]" : requirer)
11166                            + " requires " + requiredInstructionSet + " whereas " + ps
11167                            + " requires " + instructionSet;
11168                    Slog.w(TAG, errorMessage);
11169                }
11170
11171                if (requiredInstructionSet == null) {
11172                    requiredInstructionSet = instructionSet;
11173                    requirer = ps;
11174                }
11175            }
11176        }
11177
11178        if (requiredInstructionSet != null) {
11179            String adjustedAbi;
11180            if (requirer != null) {
11181                // requirer != null implies that either scannedPackage was null or that scannedPackage
11182                // did not require an ABI, in which case we have to adjust scannedPackage to match
11183                // the ABI of the set (which is the same as requirer's ABI)
11184                adjustedAbi = requirer.primaryCpuAbiString;
11185                if (scannedPackage != null) {
11186                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11187                }
11188            } else {
11189                // requirer == null implies that we're updating all ABIs in the set to
11190                // match scannedPackage.
11191                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11192            }
11193
11194            for (PackageSetting ps : packagesForUser) {
11195                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11196                    if (ps.primaryCpuAbiString != null) {
11197                        continue;
11198                    }
11199
11200                    ps.primaryCpuAbiString = adjustedAbi;
11201                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11202                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11203                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11204                        if (DEBUG_ABI_SELECTION) {
11205                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11206                                    + " (requirer="
11207                                    + (requirer != null ? requirer.pkg : "null")
11208                                    + ", scannedPackage="
11209                                    + (scannedPackage != null ? scannedPackage : "null")
11210                                    + ")");
11211                        }
11212                        try {
11213                            mInstaller.rmdex(ps.codePathString,
11214                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11215                        } catch (InstallerException ignored) {
11216                        }
11217                    }
11218                }
11219            }
11220        }
11221    }
11222
11223    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11224        synchronized (mPackages) {
11225            mResolverReplaced = true;
11226            // Set up information for custom user intent resolution activity.
11227            mResolveActivity.applicationInfo = pkg.applicationInfo;
11228            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11229            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11230            mResolveActivity.processName = pkg.applicationInfo.packageName;
11231            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11232            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11233                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11234            mResolveActivity.theme = 0;
11235            mResolveActivity.exported = true;
11236            mResolveActivity.enabled = true;
11237            mResolveInfo.activityInfo = mResolveActivity;
11238            mResolveInfo.priority = 0;
11239            mResolveInfo.preferredOrder = 0;
11240            mResolveInfo.match = 0;
11241            mResolveComponentName = mCustomResolverComponentName;
11242            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11243                    mResolveComponentName);
11244        }
11245    }
11246
11247    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11248        if (installerActivity == null) {
11249            if (DEBUG_EPHEMERAL) {
11250                Slog.d(TAG, "Clear ephemeral installer activity");
11251            }
11252            mInstantAppInstallerActivity = null;
11253            return;
11254        }
11255
11256        if (DEBUG_EPHEMERAL) {
11257            Slog.d(TAG, "Set ephemeral installer activity: "
11258                    + installerActivity.getComponentName());
11259        }
11260        // Set up information for ephemeral installer activity
11261        mInstantAppInstallerActivity = installerActivity;
11262        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11263                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11264        mInstantAppInstallerActivity.exported = true;
11265        mInstantAppInstallerActivity.enabled = true;
11266        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11267        mInstantAppInstallerInfo.priority = 0;
11268        mInstantAppInstallerInfo.preferredOrder = 1;
11269        mInstantAppInstallerInfo.isDefault = true;
11270        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11271                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11272    }
11273
11274    private static String calculateBundledApkRoot(final String codePathString) {
11275        final File codePath = new File(codePathString);
11276        final File codeRoot;
11277        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11278            codeRoot = Environment.getRootDirectory();
11279        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11280            codeRoot = Environment.getOemDirectory();
11281        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11282            codeRoot = Environment.getVendorDirectory();
11283        } else {
11284            // Unrecognized code path; take its top real segment as the apk root:
11285            // e.g. /something/app/blah.apk => /something
11286            try {
11287                File f = codePath.getCanonicalFile();
11288                File parent = f.getParentFile();    // non-null because codePath is a file
11289                File tmp;
11290                while ((tmp = parent.getParentFile()) != null) {
11291                    f = parent;
11292                    parent = tmp;
11293                }
11294                codeRoot = f;
11295                Slog.w(TAG, "Unrecognized code path "
11296                        + codePath + " - using " + codeRoot);
11297            } catch (IOException e) {
11298                // Can't canonicalize the code path -- shenanigans?
11299                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11300                return Environment.getRootDirectory().getPath();
11301            }
11302        }
11303        return codeRoot.getPath();
11304    }
11305
11306    /**
11307     * Derive and set the location of native libraries for the given package,
11308     * which varies depending on where and how the package was installed.
11309     */
11310    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11311        final ApplicationInfo info = pkg.applicationInfo;
11312        final String codePath = pkg.codePath;
11313        final File codeFile = new File(codePath);
11314        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11315        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11316
11317        info.nativeLibraryRootDir = null;
11318        info.nativeLibraryRootRequiresIsa = false;
11319        info.nativeLibraryDir = null;
11320        info.secondaryNativeLibraryDir = null;
11321
11322        if (isApkFile(codeFile)) {
11323            // Monolithic install
11324            if (bundledApp) {
11325                // If "/system/lib64/apkname" exists, assume that is the per-package
11326                // native library directory to use; otherwise use "/system/lib/apkname".
11327                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11328                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11329                        getPrimaryInstructionSet(info));
11330
11331                // This is a bundled system app so choose the path based on the ABI.
11332                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11333                // is just the default path.
11334                final String apkName = deriveCodePathName(codePath);
11335                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11336                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11337                        apkName).getAbsolutePath();
11338
11339                if (info.secondaryCpuAbi != null) {
11340                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11341                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11342                            secondaryLibDir, apkName).getAbsolutePath();
11343                }
11344            } else if (asecApp) {
11345                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11346                        .getAbsolutePath();
11347            } else {
11348                final String apkName = deriveCodePathName(codePath);
11349                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11350                        .getAbsolutePath();
11351            }
11352
11353            info.nativeLibraryRootRequiresIsa = false;
11354            info.nativeLibraryDir = info.nativeLibraryRootDir;
11355        } else {
11356            // Cluster install
11357            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11358            info.nativeLibraryRootRequiresIsa = true;
11359
11360            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11361                    getPrimaryInstructionSet(info)).getAbsolutePath();
11362
11363            if (info.secondaryCpuAbi != null) {
11364                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11365                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11366            }
11367        }
11368    }
11369
11370    /**
11371     * Calculate the abis and roots for a bundled app. These can uniquely
11372     * be determined from the contents of the system partition, i.e whether
11373     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11374     * of this information, and instead assume that the system was built
11375     * sensibly.
11376     */
11377    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11378                                           PackageSetting pkgSetting) {
11379        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11380
11381        // If "/system/lib64/apkname" exists, assume that is the per-package
11382        // native library directory to use; otherwise use "/system/lib/apkname".
11383        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11384        setBundledAppAbi(pkg, apkRoot, apkName);
11385        // pkgSetting might be null during rescan following uninstall of updates
11386        // to a bundled app, so accommodate that possibility.  The settings in
11387        // that case will be established later from the parsed package.
11388        //
11389        // If the settings aren't null, sync them up with what we've just derived.
11390        // note that apkRoot isn't stored in the package settings.
11391        if (pkgSetting != null) {
11392            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11393            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11394        }
11395    }
11396
11397    /**
11398     * Deduces the ABI of a bundled app and sets the relevant fields on the
11399     * parsed pkg object.
11400     *
11401     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11402     *        under which system libraries are installed.
11403     * @param apkName the name of the installed package.
11404     */
11405    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11406        final File codeFile = new File(pkg.codePath);
11407
11408        final boolean has64BitLibs;
11409        final boolean has32BitLibs;
11410        if (isApkFile(codeFile)) {
11411            // Monolithic install
11412            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11413            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11414        } else {
11415            // Cluster install
11416            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11417            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11418                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11419                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11420                has64BitLibs = (new File(rootDir, isa)).exists();
11421            } else {
11422                has64BitLibs = false;
11423            }
11424            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11425                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11426                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11427                has32BitLibs = (new File(rootDir, isa)).exists();
11428            } else {
11429                has32BitLibs = false;
11430            }
11431        }
11432
11433        if (has64BitLibs && !has32BitLibs) {
11434            // The package has 64 bit libs, but not 32 bit libs. Its primary
11435            // ABI should be 64 bit. We can safely assume here that the bundled
11436            // native libraries correspond to the most preferred ABI in the list.
11437
11438            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11439            pkg.applicationInfo.secondaryCpuAbi = null;
11440        } else if (has32BitLibs && !has64BitLibs) {
11441            // The package has 32 bit libs but not 64 bit libs. Its primary
11442            // ABI should be 32 bit.
11443
11444            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11445            pkg.applicationInfo.secondaryCpuAbi = null;
11446        } else if (has32BitLibs && has64BitLibs) {
11447            // The application has both 64 and 32 bit bundled libraries. We check
11448            // here that the app declares multiArch support, and warn if it doesn't.
11449            //
11450            // We will be lenient here and record both ABIs. The primary will be the
11451            // ABI that's higher on the list, i.e, a device that's configured to prefer
11452            // 64 bit apps will see a 64 bit primary ABI,
11453
11454            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11455                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11456            }
11457
11458            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11459                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11460                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11461            } else {
11462                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11463                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11464            }
11465        } else {
11466            pkg.applicationInfo.primaryCpuAbi = null;
11467            pkg.applicationInfo.secondaryCpuAbi = null;
11468        }
11469    }
11470
11471    private void killApplication(String pkgName, int appId, String reason) {
11472        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11473    }
11474
11475    private void killApplication(String pkgName, int appId, int userId, String reason) {
11476        // Request the ActivityManager to kill the process(only for existing packages)
11477        // so that we do not end up in a confused state while the user is still using the older
11478        // version of the application while the new one gets installed.
11479        final long token = Binder.clearCallingIdentity();
11480        try {
11481            IActivityManager am = ActivityManager.getService();
11482            if (am != null) {
11483                try {
11484                    am.killApplication(pkgName, appId, userId, reason);
11485                } catch (RemoteException e) {
11486                }
11487            }
11488        } finally {
11489            Binder.restoreCallingIdentity(token);
11490        }
11491    }
11492
11493    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11494        // Remove the parent package setting
11495        PackageSetting ps = (PackageSetting) pkg.mExtras;
11496        if (ps != null) {
11497            removePackageLI(ps, chatty);
11498        }
11499        // Remove the child package setting
11500        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11501        for (int i = 0; i < childCount; i++) {
11502            PackageParser.Package childPkg = pkg.childPackages.get(i);
11503            ps = (PackageSetting) childPkg.mExtras;
11504            if (ps != null) {
11505                removePackageLI(ps, chatty);
11506            }
11507        }
11508    }
11509
11510    void removePackageLI(PackageSetting ps, boolean chatty) {
11511        if (DEBUG_INSTALL) {
11512            if (chatty)
11513                Log.d(TAG, "Removing package " + ps.name);
11514        }
11515
11516        // writer
11517        synchronized (mPackages) {
11518            mPackages.remove(ps.name);
11519            final PackageParser.Package pkg = ps.pkg;
11520            if (pkg != null) {
11521                cleanPackageDataStructuresLILPw(pkg, chatty);
11522            }
11523        }
11524    }
11525
11526    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11527        if (DEBUG_INSTALL) {
11528            if (chatty)
11529                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11530        }
11531
11532        // writer
11533        synchronized (mPackages) {
11534            // Remove the parent package
11535            mPackages.remove(pkg.applicationInfo.packageName);
11536            cleanPackageDataStructuresLILPw(pkg, chatty);
11537
11538            // Remove the child packages
11539            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11540            for (int i = 0; i < childCount; i++) {
11541                PackageParser.Package childPkg = pkg.childPackages.get(i);
11542                mPackages.remove(childPkg.applicationInfo.packageName);
11543                cleanPackageDataStructuresLILPw(childPkg, chatty);
11544            }
11545        }
11546    }
11547
11548    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11549        int N = pkg.providers.size();
11550        StringBuilder r = null;
11551        int i;
11552        for (i=0; i<N; i++) {
11553            PackageParser.Provider p = pkg.providers.get(i);
11554            mProviders.removeProvider(p);
11555            if (p.info.authority == null) {
11556
11557                /* There was another ContentProvider with this authority when
11558                 * this app was installed so this authority is null,
11559                 * Ignore it as we don't have to unregister the provider.
11560                 */
11561                continue;
11562            }
11563            String names[] = p.info.authority.split(";");
11564            for (int j = 0; j < names.length; j++) {
11565                if (mProvidersByAuthority.get(names[j]) == p) {
11566                    mProvidersByAuthority.remove(names[j]);
11567                    if (DEBUG_REMOVE) {
11568                        if (chatty)
11569                            Log.d(TAG, "Unregistered content provider: " + names[j]
11570                                    + ", className = " + p.info.name + ", isSyncable = "
11571                                    + p.info.isSyncable);
11572                    }
11573                }
11574            }
11575            if (DEBUG_REMOVE && chatty) {
11576                if (r == null) {
11577                    r = new StringBuilder(256);
11578                } else {
11579                    r.append(' ');
11580                }
11581                r.append(p.info.name);
11582            }
11583        }
11584        if (r != null) {
11585            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11586        }
11587
11588        N = pkg.services.size();
11589        r = null;
11590        for (i=0; i<N; i++) {
11591            PackageParser.Service s = pkg.services.get(i);
11592            mServices.removeService(s);
11593            if (chatty) {
11594                if (r == null) {
11595                    r = new StringBuilder(256);
11596                } else {
11597                    r.append(' ');
11598                }
11599                r.append(s.info.name);
11600            }
11601        }
11602        if (r != null) {
11603            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11604        }
11605
11606        N = pkg.receivers.size();
11607        r = null;
11608        for (i=0; i<N; i++) {
11609            PackageParser.Activity a = pkg.receivers.get(i);
11610            mReceivers.removeActivity(a, "receiver");
11611            if (DEBUG_REMOVE && chatty) {
11612                if (r == null) {
11613                    r = new StringBuilder(256);
11614                } else {
11615                    r.append(' ');
11616                }
11617                r.append(a.info.name);
11618            }
11619        }
11620        if (r != null) {
11621            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11622        }
11623
11624        N = pkg.activities.size();
11625        r = null;
11626        for (i=0; i<N; i++) {
11627            PackageParser.Activity a = pkg.activities.get(i);
11628            mActivities.removeActivity(a, "activity");
11629            if (DEBUG_REMOVE && chatty) {
11630                if (r == null) {
11631                    r = new StringBuilder(256);
11632                } else {
11633                    r.append(' ');
11634                }
11635                r.append(a.info.name);
11636            }
11637        }
11638        if (r != null) {
11639            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11640        }
11641
11642        N = pkg.permissions.size();
11643        r = null;
11644        for (i=0; i<N; i++) {
11645            PackageParser.Permission p = pkg.permissions.get(i);
11646            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11647            if (bp == null) {
11648                bp = mSettings.mPermissionTrees.get(p.info.name);
11649            }
11650            if (bp != null && bp.perm == p) {
11651                bp.perm = null;
11652                if (DEBUG_REMOVE && chatty) {
11653                    if (r == null) {
11654                        r = new StringBuilder(256);
11655                    } else {
11656                        r.append(' ');
11657                    }
11658                    r.append(p.info.name);
11659                }
11660            }
11661            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11662                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11663                if (appOpPkgs != null) {
11664                    appOpPkgs.remove(pkg.packageName);
11665                }
11666            }
11667        }
11668        if (r != null) {
11669            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11670        }
11671
11672        N = pkg.requestedPermissions.size();
11673        r = null;
11674        for (i=0; i<N; i++) {
11675            String perm = pkg.requestedPermissions.get(i);
11676            BasePermission bp = mSettings.mPermissions.get(perm);
11677            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11678                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11679                if (appOpPkgs != null) {
11680                    appOpPkgs.remove(pkg.packageName);
11681                    if (appOpPkgs.isEmpty()) {
11682                        mAppOpPermissionPackages.remove(perm);
11683                    }
11684                }
11685            }
11686        }
11687        if (r != null) {
11688            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11689        }
11690
11691        N = pkg.instrumentation.size();
11692        r = null;
11693        for (i=0; i<N; i++) {
11694            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11695            mInstrumentation.remove(a.getComponentName());
11696            if (DEBUG_REMOVE && chatty) {
11697                if (r == null) {
11698                    r = new StringBuilder(256);
11699                } else {
11700                    r.append(' ');
11701                }
11702                r.append(a.info.name);
11703            }
11704        }
11705        if (r != null) {
11706            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11707        }
11708
11709        r = null;
11710        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11711            // Only system apps can hold shared libraries.
11712            if (pkg.libraryNames != null) {
11713                for (i = 0; i < pkg.libraryNames.size(); i++) {
11714                    String name = pkg.libraryNames.get(i);
11715                    if (removeSharedLibraryLPw(name, 0)) {
11716                        if (DEBUG_REMOVE && chatty) {
11717                            if (r == null) {
11718                                r = new StringBuilder(256);
11719                            } else {
11720                                r.append(' ');
11721                            }
11722                            r.append(name);
11723                        }
11724                    }
11725                }
11726            }
11727        }
11728
11729        r = null;
11730
11731        // Any package can hold static shared libraries.
11732        if (pkg.staticSharedLibName != null) {
11733            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11734                if (DEBUG_REMOVE && chatty) {
11735                    if (r == null) {
11736                        r = new StringBuilder(256);
11737                    } else {
11738                        r.append(' ');
11739                    }
11740                    r.append(pkg.staticSharedLibName);
11741                }
11742            }
11743        }
11744
11745        if (r != null) {
11746            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11747        }
11748    }
11749
11750    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11751        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11752            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11753                return true;
11754            }
11755        }
11756        return false;
11757    }
11758
11759    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11760    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11761    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11762
11763    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11764        // Update the parent permissions
11765        updatePermissionsLPw(pkg.packageName, pkg, flags);
11766        // Update the child permissions
11767        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11768        for (int i = 0; i < childCount; i++) {
11769            PackageParser.Package childPkg = pkg.childPackages.get(i);
11770            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11771        }
11772    }
11773
11774    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11775            int flags) {
11776        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11777        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11778    }
11779
11780    private void updatePermissionsLPw(String changingPkg,
11781            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11782        // Make sure there are no dangling permission trees.
11783        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11784        while (it.hasNext()) {
11785            final BasePermission bp = it.next();
11786            if (bp.packageSetting == null) {
11787                // We may not yet have parsed the package, so just see if
11788                // we still know about its settings.
11789                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11790            }
11791            if (bp.packageSetting == null) {
11792                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11793                        + " from package " + bp.sourcePackage);
11794                it.remove();
11795            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11796                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11797                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11798                            + " from package " + bp.sourcePackage);
11799                    flags |= UPDATE_PERMISSIONS_ALL;
11800                    it.remove();
11801                }
11802            }
11803        }
11804
11805        // Make sure all dynamic permissions have been assigned to a package,
11806        // and make sure there are no dangling permissions.
11807        it = mSettings.mPermissions.values().iterator();
11808        while (it.hasNext()) {
11809            final BasePermission bp = it.next();
11810            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11811                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11812                        + bp.name + " pkg=" + bp.sourcePackage
11813                        + " info=" + bp.pendingInfo);
11814                if (bp.packageSetting == null && bp.pendingInfo != null) {
11815                    final BasePermission tree = findPermissionTreeLP(bp.name);
11816                    if (tree != null && tree.perm != null) {
11817                        bp.packageSetting = tree.packageSetting;
11818                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11819                                new PermissionInfo(bp.pendingInfo));
11820                        bp.perm.info.packageName = tree.perm.info.packageName;
11821                        bp.perm.info.name = bp.name;
11822                        bp.uid = tree.uid;
11823                    }
11824                }
11825            }
11826            if (bp.packageSetting == null) {
11827                // We may not yet have parsed the package, so just see if
11828                // we still know about its settings.
11829                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11830            }
11831            if (bp.packageSetting == null) {
11832                Slog.w(TAG, "Removing dangling permission: " + bp.name
11833                        + " from package " + bp.sourcePackage);
11834                it.remove();
11835            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11836                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11837                    Slog.i(TAG, "Removing old permission: " + bp.name
11838                            + " from package " + bp.sourcePackage);
11839                    flags |= UPDATE_PERMISSIONS_ALL;
11840                    it.remove();
11841                }
11842            }
11843        }
11844
11845        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11846        // Now update the permissions for all packages, in particular
11847        // replace the granted permissions of the system packages.
11848        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11849            for (PackageParser.Package pkg : mPackages.values()) {
11850                if (pkg != pkgInfo) {
11851                    // Only replace for packages on requested volume
11852                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11853                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11854                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11855                    grantPermissionsLPw(pkg, replace, changingPkg);
11856                }
11857            }
11858        }
11859
11860        if (pkgInfo != null) {
11861            // Only replace for packages on requested volume
11862            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11863            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11864                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11865            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11866        }
11867        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11868    }
11869
11870    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11871            String packageOfInterest) {
11872        // IMPORTANT: There are two types of permissions: install and runtime.
11873        // Install time permissions are granted when the app is installed to
11874        // all device users and users added in the future. Runtime permissions
11875        // are granted at runtime explicitly to specific users. Normal and signature
11876        // protected permissions are install time permissions. Dangerous permissions
11877        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11878        // otherwise they are runtime permissions. This function does not manage
11879        // runtime permissions except for the case an app targeting Lollipop MR1
11880        // being upgraded to target a newer SDK, in which case dangerous permissions
11881        // are transformed from install time to runtime ones.
11882
11883        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11884        if (ps == null) {
11885            return;
11886        }
11887
11888        PermissionsState permissionsState = ps.getPermissionsState();
11889        PermissionsState origPermissions = permissionsState;
11890
11891        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11892
11893        boolean runtimePermissionsRevoked = false;
11894        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11895
11896        boolean changedInstallPermission = false;
11897
11898        if (replace) {
11899            ps.installPermissionsFixed = false;
11900            if (!ps.isSharedUser()) {
11901                origPermissions = new PermissionsState(permissionsState);
11902                permissionsState.reset();
11903            } else {
11904                // We need to know only about runtime permission changes since the
11905                // calling code always writes the install permissions state but
11906                // the runtime ones are written only if changed. The only cases of
11907                // changed runtime permissions here are promotion of an install to
11908                // runtime and revocation of a runtime from a shared user.
11909                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11910                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11911                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11912                    runtimePermissionsRevoked = true;
11913                }
11914            }
11915        }
11916
11917        permissionsState.setGlobalGids(mGlobalGids);
11918
11919        final int N = pkg.requestedPermissions.size();
11920        for (int i=0; i<N; i++) {
11921            final String name = pkg.requestedPermissions.get(i);
11922            final BasePermission bp = mSettings.mPermissions.get(name);
11923            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11924                    >= Build.VERSION_CODES.M;
11925
11926            if (DEBUG_INSTALL) {
11927                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11928            }
11929
11930            if (bp == null || bp.packageSetting == null) {
11931                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11932                    if (DEBUG_PERMISSIONS) {
11933                        Slog.i(TAG, "Unknown permission " + name
11934                                + " in package " + pkg.packageName);
11935                    }
11936                }
11937                continue;
11938            }
11939
11940
11941            // Limit ephemeral apps to ephemeral allowed permissions.
11942            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11943                if (DEBUG_PERMISSIONS) {
11944                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11945                            + pkg.packageName);
11946                }
11947                continue;
11948            }
11949
11950            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11951                if (DEBUG_PERMISSIONS) {
11952                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11953                            + pkg.packageName);
11954                }
11955                continue;
11956            }
11957
11958            final String perm = bp.name;
11959            boolean allowedSig = false;
11960            int grant = GRANT_DENIED;
11961
11962            // Keep track of app op permissions.
11963            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11964                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11965                if (pkgs == null) {
11966                    pkgs = new ArraySet<>();
11967                    mAppOpPermissionPackages.put(bp.name, pkgs);
11968                }
11969                pkgs.add(pkg.packageName);
11970            }
11971
11972            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11973            switch (level) {
11974                case PermissionInfo.PROTECTION_NORMAL: {
11975                    // For all apps normal permissions are install time ones.
11976                    grant = GRANT_INSTALL;
11977                } break;
11978
11979                case PermissionInfo.PROTECTION_DANGEROUS: {
11980                    // If a permission review is required for legacy apps we represent
11981                    // their permissions as always granted runtime ones since we need
11982                    // to keep the review required permission flag per user while an
11983                    // install permission's state is shared across all users.
11984                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11985                        // For legacy apps dangerous permissions are install time ones.
11986                        grant = GRANT_INSTALL;
11987                    } else if (origPermissions.hasInstallPermission(bp.name)) {
11988                        // For legacy apps that became modern, install becomes runtime.
11989                        grant = GRANT_UPGRADE;
11990                    } else if (mPromoteSystemApps
11991                            && isSystemApp(ps)
11992                            && mExistingSystemPackages.contains(ps.name)) {
11993                        // For legacy system apps, install becomes runtime.
11994                        // We cannot check hasInstallPermission() for system apps since those
11995                        // permissions were granted implicitly and not persisted pre-M.
11996                        grant = GRANT_UPGRADE;
11997                    } else {
11998                        // For modern apps keep runtime permissions unchanged.
11999                        grant = GRANT_RUNTIME;
12000                    }
12001                } break;
12002
12003                case PermissionInfo.PROTECTION_SIGNATURE: {
12004                    // For all apps signature permissions are install time ones.
12005                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12006                    if (allowedSig) {
12007                        grant = GRANT_INSTALL;
12008                    }
12009                } break;
12010            }
12011
12012            if (DEBUG_PERMISSIONS) {
12013                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12014            }
12015
12016            if (grant != GRANT_DENIED) {
12017                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12018                    // If this is an existing, non-system package, then
12019                    // we can't add any new permissions to it.
12020                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12021                        // Except...  if this is a permission that was added
12022                        // to the platform (note: need to only do this when
12023                        // updating the platform).
12024                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12025                            grant = GRANT_DENIED;
12026                        }
12027                    }
12028                }
12029
12030                switch (grant) {
12031                    case GRANT_INSTALL: {
12032                        // Revoke this as runtime permission to handle the case of
12033                        // a runtime permission being downgraded to an install one.
12034                        // Also in permission review mode we keep dangerous permissions
12035                        // for legacy apps
12036                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12037                            if (origPermissions.getRuntimePermissionState(
12038                                    bp.name, userId) != null) {
12039                                // Revoke the runtime permission and clear the flags.
12040                                origPermissions.revokeRuntimePermission(bp, userId);
12041                                origPermissions.updatePermissionFlags(bp, userId,
12042                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12043                                // If we revoked a permission permission, we have to write.
12044                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12045                                        changedRuntimePermissionUserIds, userId);
12046                            }
12047                        }
12048                        // Grant an install permission.
12049                        if (permissionsState.grantInstallPermission(bp) !=
12050                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12051                            changedInstallPermission = true;
12052                        }
12053                    } break;
12054
12055                    case GRANT_RUNTIME: {
12056                        // Grant previously granted runtime permissions.
12057                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12058                            PermissionState permissionState = origPermissions
12059                                    .getRuntimePermissionState(bp.name, userId);
12060                            int flags = permissionState != null
12061                                    ? permissionState.getFlags() : 0;
12062                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12063                                // Don't propagate the permission in a permission review mode if
12064                                // the former was revoked, i.e. marked to not propagate on upgrade.
12065                                // Note that in a permission review mode install permissions are
12066                                // represented as constantly granted runtime ones since we need to
12067                                // keep a per user state associated with the permission. Also the
12068                                // revoke on upgrade flag is no longer applicable and is reset.
12069                                final boolean revokeOnUpgrade = (flags & PackageManager
12070                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12071                                if (revokeOnUpgrade) {
12072                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12073                                    // Since we changed the flags, we have to write.
12074                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12075                                            changedRuntimePermissionUserIds, userId);
12076                                }
12077                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12078                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12079                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12080                                        // If we cannot put the permission as it was,
12081                                        // we have to write.
12082                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12083                                                changedRuntimePermissionUserIds, userId);
12084                                    }
12085                                }
12086
12087                                // If the app supports runtime permissions no need for a review.
12088                                if (mPermissionReviewRequired
12089                                        && appSupportsRuntimePermissions
12090                                        && (flags & PackageManager
12091                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12092                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12093                                    // Since we changed the flags, we have to write.
12094                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12095                                            changedRuntimePermissionUserIds, userId);
12096                                }
12097                            } else if (mPermissionReviewRequired
12098                                    && !appSupportsRuntimePermissions) {
12099                                // For legacy apps that need a permission review, every new
12100                                // runtime permission is granted but it is pending a review.
12101                                // We also need to review only platform defined runtime
12102                                // permissions as these are the only ones the platform knows
12103                                // how to disable the API to simulate revocation as legacy
12104                                // apps don't expect to run with revoked permissions.
12105                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12106                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12107                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12108                                        // We changed the flags, hence have to write.
12109                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12110                                                changedRuntimePermissionUserIds, userId);
12111                                    }
12112                                }
12113                                if (permissionsState.grantRuntimePermission(bp, userId)
12114                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12115                                    // We changed the permission, hence have to write.
12116                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12117                                            changedRuntimePermissionUserIds, userId);
12118                                }
12119                            }
12120                            // Propagate the permission flags.
12121                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12122                        }
12123                    } break;
12124
12125                    case GRANT_UPGRADE: {
12126                        // Grant runtime permissions for a previously held install permission.
12127                        PermissionState permissionState = origPermissions
12128                                .getInstallPermissionState(bp.name);
12129                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12130
12131                        if (origPermissions.revokeInstallPermission(bp)
12132                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12133                            // We will be transferring the permission flags, so clear them.
12134                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12135                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12136                            changedInstallPermission = true;
12137                        }
12138
12139                        // If the permission is not to be promoted to runtime we ignore it and
12140                        // also its other flags as they are not applicable to install permissions.
12141                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12142                            for (int userId : currentUserIds) {
12143                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12144                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12145                                    // Transfer the permission flags.
12146                                    permissionsState.updatePermissionFlags(bp, userId,
12147                                            flags, flags);
12148                                    // If we granted the permission, we have to write.
12149                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12150                                            changedRuntimePermissionUserIds, userId);
12151                                }
12152                            }
12153                        }
12154                    } break;
12155
12156                    default: {
12157                        if (packageOfInterest == null
12158                                || packageOfInterest.equals(pkg.packageName)) {
12159                            if (DEBUG_PERMISSIONS) {
12160                                Slog.i(TAG, "Not granting permission " + perm
12161                                        + " to package " + pkg.packageName
12162                                        + " because it was previously installed without");
12163                            }
12164                        }
12165                    } break;
12166                }
12167            } else {
12168                if (permissionsState.revokeInstallPermission(bp) !=
12169                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12170                    // Also drop the permission flags.
12171                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12172                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12173                    changedInstallPermission = true;
12174                    Slog.i(TAG, "Un-granting permission " + perm
12175                            + " from package " + pkg.packageName
12176                            + " (protectionLevel=" + bp.protectionLevel
12177                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12178                            + ")");
12179                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12180                    // Don't print warning for app op permissions, since it is fine for them
12181                    // not to be granted, there is a UI for the user to decide.
12182                    if (DEBUG_PERMISSIONS
12183                            && (packageOfInterest == null
12184                                    || packageOfInterest.equals(pkg.packageName))) {
12185                        Slog.i(TAG, "Not granting permission " + perm
12186                                + " to package " + pkg.packageName
12187                                + " (protectionLevel=" + bp.protectionLevel
12188                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12189                                + ")");
12190                    }
12191                }
12192            }
12193        }
12194
12195        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12196                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12197            // This is the first that we have heard about this package, so the
12198            // permissions we have now selected are fixed until explicitly
12199            // changed.
12200            ps.installPermissionsFixed = true;
12201        }
12202
12203        // Persist the runtime permissions state for users with changes. If permissions
12204        // were revoked because no app in the shared user declares them we have to
12205        // write synchronously to avoid losing runtime permissions state.
12206        for (int userId : changedRuntimePermissionUserIds) {
12207            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
12208        }
12209    }
12210
12211    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
12212        boolean allowed = false;
12213        final int NP = PackageParser.NEW_PERMISSIONS.length;
12214        for (int ip=0; ip<NP; ip++) {
12215            final PackageParser.NewPermissionInfo npi
12216                    = PackageParser.NEW_PERMISSIONS[ip];
12217            if (npi.name.equals(perm)
12218                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
12219                allowed = true;
12220                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
12221                        + pkg.packageName);
12222                break;
12223            }
12224        }
12225        return allowed;
12226    }
12227
12228    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
12229            BasePermission bp, PermissionsState origPermissions) {
12230        boolean privilegedPermission = (bp.protectionLevel
12231                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
12232        boolean privappPermissionsDisable =
12233                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
12234        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
12235        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
12236        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
12237                && !platformPackage && platformPermission) {
12238            ArraySet<String> wlPermissions = SystemConfig.getInstance()
12239                    .getPrivAppPermissions(pkg.packageName);
12240            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
12241            if (!whitelisted) {
12242                Slog.w(TAG, "Privileged permission " + perm + " for package "
12243                        + pkg.packageName + " - not in privapp-permissions whitelist");
12244                // Only report violations for apps on system image
12245                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
12246                    if (mPrivappPermissionsViolations == null) {
12247                        mPrivappPermissionsViolations = new ArraySet<>();
12248                    }
12249                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
12250                }
12251                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
12252                    return false;
12253                }
12254            }
12255        }
12256        boolean allowed = (compareSignatures(
12257                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
12258                        == PackageManager.SIGNATURE_MATCH)
12259                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
12260                        == PackageManager.SIGNATURE_MATCH);
12261        if (!allowed && privilegedPermission) {
12262            if (isSystemApp(pkg)) {
12263                // For updated system applications, a system permission
12264                // is granted only if it had been defined by the original application.
12265                if (pkg.isUpdatedSystemApp()) {
12266                    final PackageSetting sysPs = mSettings
12267                            .getDisabledSystemPkgLPr(pkg.packageName);
12268                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
12269                        // If the original was granted this permission, we take
12270                        // that grant decision as read and propagate it to the
12271                        // update.
12272                        if (sysPs.isPrivileged()) {
12273                            allowed = true;
12274                        }
12275                    } else {
12276                        // The system apk may have been updated with an older
12277                        // version of the one on the data partition, but which
12278                        // granted a new system permission that it didn't have
12279                        // before.  In this case we do want to allow the app to
12280                        // now get the new permission if the ancestral apk is
12281                        // privileged to get it.
12282                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
12283                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
12284                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
12285                                    allowed = true;
12286                                    break;
12287                                }
12288                            }
12289                        }
12290                        // Also if a privileged parent package on the system image or any of
12291                        // its children requested a privileged permission, the updated child
12292                        // packages can also get the permission.
12293                        if (pkg.parentPackage != null) {
12294                            final PackageSetting disabledSysParentPs = mSettings
12295                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
12296                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
12297                                    && disabledSysParentPs.isPrivileged()) {
12298                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
12299                                    allowed = true;
12300                                } else if (disabledSysParentPs.pkg.childPackages != null) {
12301                                    final int count = disabledSysParentPs.pkg.childPackages.size();
12302                                    for (int i = 0; i < count; i++) {
12303                                        PackageParser.Package disabledSysChildPkg =
12304                                                disabledSysParentPs.pkg.childPackages.get(i);
12305                                        if (isPackageRequestingPermission(disabledSysChildPkg,
12306                                                perm)) {
12307                                            allowed = true;
12308                                            break;
12309                                        }
12310                                    }
12311                                }
12312                            }
12313                        }
12314                    }
12315                } else {
12316                    allowed = isPrivilegedApp(pkg);
12317                }
12318            }
12319        }
12320        if (!allowed) {
12321            if (!allowed && (bp.protectionLevel
12322                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
12323                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
12324                // If this was a previously normal/dangerous permission that got moved
12325                // to a system permission as part of the runtime permission redesign, then
12326                // we still want to blindly grant it to old apps.
12327                allowed = true;
12328            }
12329            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
12330                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
12331                // If this permission is to be granted to the system installer and
12332                // this app is an installer, then it gets the permission.
12333                allowed = true;
12334            }
12335            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
12336                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
12337                // If this permission is to be granted to the system verifier and
12338                // this app is a verifier, then it gets the permission.
12339                allowed = true;
12340            }
12341            if (!allowed && (bp.protectionLevel
12342                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
12343                    && isSystemApp(pkg)) {
12344                // Any pre-installed system app is allowed to get this permission.
12345                allowed = true;
12346            }
12347            if (!allowed && (bp.protectionLevel
12348                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
12349                // For development permissions, a development permission
12350                // is granted only if it was already granted.
12351                allowed = origPermissions.hasInstallPermission(perm);
12352            }
12353            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
12354                    && pkg.packageName.equals(mSetupWizardPackage)) {
12355                // If this permission is to be granted to the system setup wizard and
12356                // this app is a setup wizard, then it gets the permission.
12357                allowed = true;
12358            }
12359        }
12360        return allowed;
12361    }
12362
12363    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
12364        final int permCount = pkg.requestedPermissions.size();
12365        for (int j = 0; j < permCount; j++) {
12366            String requestedPermission = pkg.requestedPermissions.get(j);
12367            if (permission.equals(requestedPermission)) {
12368                return true;
12369            }
12370        }
12371        return false;
12372    }
12373
12374    final class ActivityIntentResolver
12375            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12376        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12377                boolean defaultOnly, int userId) {
12378            if (!sUserManager.exists(userId)) return null;
12379            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12380            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12381        }
12382
12383        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12384                int userId) {
12385            if (!sUserManager.exists(userId)) return null;
12386            mFlags = flags;
12387            return super.queryIntent(intent, resolvedType,
12388                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12389                    userId);
12390        }
12391
12392        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12393                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12394            if (!sUserManager.exists(userId)) return null;
12395            if (packageActivities == null) {
12396                return null;
12397            }
12398            mFlags = flags;
12399            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12400            final int N = packageActivities.size();
12401            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12402                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12403
12404            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12405            for (int i = 0; i < N; ++i) {
12406                intentFilters = packageActivities.get(i).intents;
12407                if (intentFilters != null && intentFilters.size() > 0) {
12408                    PackageParser.ActivityIntentInfo[] array =
12409                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12410                    intentFilters.toArray(array);
12411                    listCut.add(array);
12412                }
12413            }
12414            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12415        }
12416
12417        /**
12418         * Finds a privileged activity that matches the specified activity names.
12419         */
12420        private PackageParser.Activity findMatchingActivity(
12421                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12422            for (PackageParser.Activity sysActivity : activityList) {
12423                if (sysActivity.info.name.equals(activityInfo.name)) {
12424                    return sysActivity;
12425                }
12426                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12427                    return sysActivity;
12428                }
12429                if (sysActivity.info.targetActivity != null) {
12430                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12431                        return sysActivity;
12432                    }
12433                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12434                        return sysActivity;
12435                    }
12436                }
12437            }
12438            return null;
12439        }
12440
12441        public class IterGenerator<E> {
12442            public Iterator<E> generate(ActivityIntentInfo info) {
12443                return null;
12444            }
12445        }
12446
12447        public class ActionIterGenerator extends IterGenerator<String> {
12448            @Override
12449            public Iterator<String> generate(ActivityIntentInfo info) {
12450                return info.actionsIterator();
12451            }
12452        }
12453
12454        public class CategoriesIterGenerator extends IterGenerator<String> {
12455            @Override
12456            public Iterator<String> generate(ActivityIntentInfo info) {
12457                return info.categoriesIterator();
12458            }
12459        }
12460
12461        public class SchemesIterGenerator extends IterGenerator<String> {
12462            @Override
12463            public Iterator<String> generate(ActivityIntentInfo info) {
12464                return info.schemesIterator();
12465            }
12466        }
12467
12468        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12469            @Override
12470            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12471                return info.authoritiesIterator();
12472            }
12473        }
12474
12475        /**
12476         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12477         * MODIFIED. Do not pass in a list that should not be changed.
12478         */
12479        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12480                IterGenerator<T> generator, Iterator<T> searchIterator) {
12481            // loop through the set of actions; every one must be found in the intent filter
12482            while (searchIterator.hasNext()) {
12483                // we must have at least one filter in the list to consider a match
12484                if (intentList.size() == 0) {
12485                    break;
12486                }
12487
12488                final T searchAction = searchIterator.next();
12489
12490                // loop through the set of intent filters
12491                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12492                while (intentIter.hasNext()) {
12493                    final ActivityIntentInfo intentInfo = intentIter.next();
12494                    boolean selectionFound = false;
12495
12496                    // loop through the intent filter's selection criteria; at least one
12497                    // of them must match the searched criteria
12498                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12499                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12500                        final T intentSelection = intentSelectionIter.next();
12501                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12502                            selectionFound = true;
12503                            break;
12504                        }
12505                    }
12506
12507                    // the selection criteria wasn't found in this filter's set; this filter
12508                    // is not a potential match
12509                    if (!selectionFound) {
12510                        intentIter.remove();
12511                    }
12512                }
12513            }
12514        }
12515
12516        private boolean isProtectedAction(ActivityIntentInfo filter) {
12517            final Iterator<String> actionsIter = filter.actionsIterator();
12518            while (actionsIter != null && actionsIter.hasNext()) {
12519                final String filterAction = actionsIter.next();
12520                if (PROTECTED_ACTIONS.contains(filterAction)) {
12521                    return true;
12522                }
12523            }
12524            return false;
12525        }
12526
12527        /**
12528         * Adjusts the priority of the given intent filter according to policy.
12529         * <p>
12530         * <ul>
12531         * <li>The priority for non privileged applications is capped to '0'</li>
12532         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12533         * <li>The priority for unbundled updates to privileged applications is capped to the
12534         *      priority defined on the system partition</li>
12535         * </ul>
12536         * <p>
12537         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12538         * allowed to obtain any priority on any action.
12539         */
12540        private void adjustPriority(
12541                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12542            // nothing to do; priority is fine as-is
12543            if (intent.getPriority() <= 0) {
12544                return;
12545            }
12546
12547            final ActivityInfo activityInfo = intent.activity.info;
12548            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12549
12550            final boolean privilegedApp =
12551                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12552            if (!privilegedApp) {
12553                // non-privileged applications can never define a priority >0
12554                if (DEBUG_FILTERS) {
12555                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12556                            + " package: " + applicationInfo.packageName
12557                            + " activity: " + intent.activity.className
12558                            + " origPrio: " + intent.getPriority());
12559                }
12560                intent.setPriority(0);
12561                return;
12562            }
12563
12564            if (systemActivities == null) {
12565                // the system package is not disabled; we're parsing the system partition
12566                if (isProtectedAction(intent)) {
12567                    if (mDeferProtectedFilters) {
12568                        // We can't deal with these just yet. No component should ever obtain a
12569                        // >0 priority for a protected actions, with ONE exception -- the setup
12570                        // wizard. The setup wizard, however, cannot be known until we're able to
12571                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12572                        // until all intent filters have been processed. Chicken, meet egg.
12573                        // Let the filter temporarily have a high priority and rectify the
12574                        // priorities after all system packages have been scanned.
12575                        mProtectedFilters.add(intent);
12576                        if (DEBUG_FILTERS) {
12577                            Slog.i(TAG, "Protected action; save for later;"
12578                                    + " package: " + applicationInfo.packageName
12579                                    + " activity: " + intent.activity.className
12580                                    + " origPrio: " + intent.getPriority());
12581                        }
12582                        return;
12583                    } else {
12584                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12585                            Slog.i(TAG, "No setup wizard;"
12586                                + " All protected intents capped to priority 0");
12587                        }
12588                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12589                            if (DEBUG_FILTERS) {
12590                                Slog.i(TAG, "Found setup wizard;"
12591                                    + " allow priority " + intent.getPriority() + ";"
12592                                    + " package: " + intent.activity.info.packageName
12593                                    + " activity: " + intent.activity.className
12594                                    + " priority: " + intent.getPriority());
12595                            }
12596                            // setup wizard gets whatever it wants
12597                            return;
12598                        }
12599                        if (DEBUG_FILTERS) {
12600                            Slog.i(TAG, "Protected action; cap priority to 0;"
12601                                    + " package: " + intent.activity.info.packageName
12602                                    + " activity: " + intent.activity.className
12603                                    + " origPrio: " + intent.getPriority());
12604                        }
12605                        intent.setPriority(0);
12606                        return;
12607                    }
12608                }
12609                // privileged apps on the system image get whatever priority they request
12610                return;
12611            }
12612
12613            // privileged app unbundled update ... try to find the same activity
12614            final PackageParser.Activity foundActivity =
12615                    findMatchingActivity(systemActivities, activityInfo);
12616            if (foundActivity == null) {
12617                // this is a new activity; it cannot obtain >0 priority
12618                if (DEBUG_FILTERS) {
12619                    Slog.i(TAG, "New activity; cap priority to 0;"
12620                            + " package: " + applicationInfo.packageName
12621                            + " activity: " + intent.activity.className
12622                            + " origPrio: " + intent.getPriority());
12623                }
12624                intent.setPriority(0);
12625                return;
12626            }
12627
12628            // found activity, now check for filter equivalence
12629
12630            // a shallow copy is enough; we modify the list, not its contents
12631            final List<ActivityIntentInfo> intentListCopy =
12632                    new ArrayList<>(foundActivity.intents);
12633            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12634
12635            // find matching action subsets
12636            final Iterator<String> actionsIterator = intent.actionsIterator();
12637            if (actionsIterator != null) {
12638                getIntentListSubset(
12639                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12640                if (intentListCopy.size() == 0) {
12641                    // no more intents to match; we're not equivalent
12642                    if (DEBUG_FILTERS) {
12643                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12644                                + " package: " + applicationInfo.packageName
12645                                + " activity: " + intent.activity.className
12646                                + " origPrio: " + intent.getPriority());
12647                    }
12648                    intent.setPriority(0);
12649                    return;
12650                }
12651            }
12652
12653            // find matching category subsets
12654            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12655            if (categoriesIterator != null) {
12656                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12657                        categoriesIterator);
12658                if (intentListCopy.size() == 0) {
12659                    // no more intents to match; we're not equivalent
12660                    if (DEBUG_FILTERS) {
12661                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12662                                + " package: " + applicationInfo.packageName
12663                                + " activity: " + intent.activity.className
12664                                + " origPrio: " + intent.getPriority());
12665                    }
12666                    intent.setPriority(0);
12667                    return;
12668                }
12669            }
12670
12671            // find matching schemes subsets
12672            final Iterator<String> schemesIterator = intent.schemesIterator();
12673            if (schemesIterator != null) {
12674                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12675                        schemesIterator);
12676                if (intentListCopy.size() == 0) {
12677                    // no more intents to match; we're not equivalent
12678                    if (DEBUG_FILTERS) {
12679                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12680                                + " package: " + applicationInfo.packageName
12681                                + " activity: " + intent.activity.className
12682                                + " origPrio: " + intent.getPriority());
12683                    }
12684                    intent.setPriority(0);
12685                    return;
12686                }
12687            }
12688
12689            // find matching authorities subsets
12690            final Iterator<IntentFilter.AuthorityEntry>
12691                    authoritiesIterator = intent.authoritiesIterator();
12692            if (authoritiesIterator != null) {
12693                getIntentListSubset(intentListCopy,
12694                        new AuthoritiesIterGenerator(),
12695                        authoritiesIterator);
12696                if (intentListCopy.size() == 0) {
12697                    // no more intents to match; we're not equivalent
12698                    if (DEBUG_FILTERS) {
12699                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12700                                + " package: " + applicationInfo.packageName
12701                                + " activity: " + intent.activity.className
12702                                + " origPrio: " + intent.getPriority());
12703                    }
12704                    intent.setPriority(0);
12705                    return;
12706                }
12707            }
12708
12709            // we found matching filter(s); app gets the max priority of all intents
12710            int cappedPriority = 0;
12711            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12712                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12713            }
12714            if (intent.getPriority() > cappedPriority) {
12715                if (DEBUG_FILTERS) {
12716                    Slog.i(TAG, "Found matching filter(s);"
12717                            + " cap priority to " + cappedPriority + ";"
12718                            + " package: " + applicationInfo.packageName
12719                            + " activity: " + intent.activity.className
12720                            + " origPrio: " + intent.getPriority());
12721                }
12722                intent.setPriority(cappedPriority);
12723                return;
12724            }
12725            // all this for nothing; the requested priority was <= what was on the system
12726        }
12727
12728        public final void addActivity(PackageParser.Activity a, String type) {
12729            mActivities.put(a.getComponentName(), a);
12730            if (DEBUG_SHOW_INFO)
12731                Log.v(
12732                TAG, "  " + type + " " +
12733                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12734            if (DEBUG_SHOW_INFO)
12735                Log.v(TAG, "    Class=" + a.info.name);
12736            final int NI = a.intents.size();
12737            for (int j=0; j<NI; j++) {
12738                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12739                if ("activity".equals(type)) {
12740                    final PackageSetting ps =
12741                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12742                    final List<PackageParser.Activity> systemActivities =
12743                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12744                    adjustPriority(systemActivities, intent);
12745                }
12746                if (DEBUG_SHOW_INFO) {
12747                    Log.v(TAG, "    IntentFilter:");
12748                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12749                }
12750                if (!intent.debugCheck()) {
12751                    Log.w(TAG, "==> For Activity " + a.info.name);
12752                }
12753                addFilter(intent);
12754            }
12755        }
12756
12757        public final void removeActivity(PackageParser.Activity a, String type) {
12758            mActivities.remove(a.getComponentName());
12759            if (DEBUG_SHOW_INFO) {
12760                Log.v(TAG, "  " + type + " "
12761                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12762                                : a.info.name) + ":");
12763                Log.v(TAG, "    Class=" + a.info.name);
12764            }
12765            final int NI = a.intents.size();
12766            for (int j=0; j<NI; j++) {
12767                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12768                if (DEBUG_SHOW_INFO) {
12769                    Log.v(TAG, "    IntentFilter:");
12770                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12771                }
12772                removeFilter(intent);
12773            }
12774        }
12775
12776        @Override
12777        protected boolean allowFilterResult(
12778                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12779            ActivityInfo filterAi = filter.activity.info;
12780            for (int i=dest.size()-1; i>=0; i--) {
12781                ActivityInfo destAi = dest.get(i).activityInfo;
12782                if (destAi.name == filterAi.name
12783                        && destAi.packageName == filterAi.packageName) {
12784                    return false;
12785                }
12786            }
12787            return true;
12788        }
12789
12790        @Override
12791        protected ActivityIntentInfo[] newArray(int size) {
12792            return new ActivityIntentInfo[size];
12793        }
12794
12795        @Override
12796        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12797            if (!sUserManager.exists(userId)) return true;
12798            PackageParser.Package p = filter.activity.owner;
12799            if (p != null) {
12800                PackageSetting ps = (PackageSetting)p.mExtras;
12801                if (ps != null) {
12802                    // System apps are never considered stopped for purposes of
12803                    // filtering, because there may be no way for the user to
12804                    // actually re-launch them.
12805                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12806                            && ps.getStopped(userId);
12807                }
12808            }
12809            return false;
12810        }
12811
12812        @Override
12813        protected boolean isPackageForFilter(String packageName,
12814                PackageParser.ActivityIntentInfo info) {
12815            return packageName.equals(info.activity.owner.packageName);
12816        }
12817
12818        @Override
12819        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12820                int match, int userId) {
12821            if (!sUserManager.exists(userId)) return null;
12822            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12823                return null;
12824            }
12825            final PackageParser.Activity activity = info.activity;
12826            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12827            if (ps == null) {
12828                return null;
12829            }
12830            final PackageUserState userState = ps.readUserState(userId);
12831            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12832            if (ai == null) {
12833                return null;
12834            }
12835            final boolean matchExplicitlyVisibleOnly =
12836                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12837            final boolean matchVisibleToInstantApp =
12838                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12839            final boolean componentVisible =
12840                    matchVisibleToInstantApp
12841                    && info.isVisibleToInstantApp()
12842                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12843            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12844            // throw out filters that aren't visible to ephemeral apps
12845            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12846                return null;
12847            }
12848            // throw out instant app filters if we're not explicitly requesting them
12849            if (!matchInstantApp && userState.instantApp) {
12850                return null;
12851            }
12852            // throw out instant app filters if updates are available; will trigger
12853            // instant app resolution
12854            if (userState.instantApp && ps.isUpdateAvailable()) {
12855                return null;
12856            }
12857            final ResolveInfo res = new ResolveInfo();
12858            res.activityInfo = ai;
12859            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12860                res.filter = info;
12861            }
12862            if (info != null) {
12863                res.handleAllWebDataURI = info.handleAllWebDataURI();
12864            }
12865            res.priority = info.getPriority();
12866            res.preferredOrder = activity.owner.mPreferredOrder;
12867            //System.out.println("Result: " + res.activityInfo.className +
12868            //                   " = " + res.priority);
12869            res.match = match;
12870            res.isDefault = info.hasDefault;
12871            res.labelRes = info.labelRes;
12872            res.nonLocalizedLabel = info.nonLocalizedLabel;
12873            if (userNeedsBadging(userId)) {
12874                res.noResourceId = true;
12875            } else {
12876                res.icon = info.icon;
12877            }
12878            res.iconResourceId = info.icon;
12879            res.system = res.activityInfo.applicationInfo.isSystemApp();
12880            res.isInstantAppAvailable = userState.instantApp;
12881            return res;
12882        }
12883
12884        @Override
12885        protected void sortResults(List<ResolveInfo> results) {
12886            Collections.sort(results, mResolvePrioritySorter);
12887        }
12888
12889        @Override
12890        protected void dumpFilter(PrintWriter out, String prefix,
12891                PackageParser.ActivityIntentInfo filter) {
12892            out.print(prefix); out.print(
12893                    Integer.toHexString(System.identityHashCode(filter.activity)));
12894                    out.print(' ');
12895                    filter.activity.printComponentShortName(out);
12896                    out.print(" filter ");
12897                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12898        }
12899
12900        @Override
12901        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12902            return filter.activity;
12903        }
12904
12905        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12906            PackageParser.Activity activity = (PackageParser.Activity)label;
12907            out.print(prefix); out.print(
12908                    Integer.toHexString(System.identityHashCode(activity)));
12909                    out.print(' ');
12910                    activity.printComponentShortName(out);
12911            if (count > 1) {
12912                out.print(" ("); out.print(count); out.print(" filters)");
12913            }
12914            out.println();
12915        }
12916
12917        // Keys are String (activity class name), values are Activity.
12918        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12919                = new ArrayMap<ComponentName, PackageParser.Activity>();
12920        private int mFlags;
12921    }
12922
12923    private final class ServiceIntentResolver
12924            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12925        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12926                boolean defaultOnly, int userId) {
12927            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12928            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12929        }
12930
12931        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12932                int userId) {
12933            if (!sUserManager.exists(userId)) return null;
12934            mFlags = flags;
12935            return super.queryIntent(intent, resolvedType,
12936                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12937                    userId);
12938        }
12939
12940        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12941                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12942            if (!sUserManager.exists(userId)) return null;
12943            if (packageServices == null) {
12944                return null;
12945            }
12946            mFlags = flags;
12947            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12948            final int N = packageServices.size();
12949            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12950                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12951
12952            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12953            for (int i = 0; i < N; ++i) {
12954                intentFilters = packageServices.get(i).intents;
12955                if (intentFilters != null && intentFilters.size() > 0) {
12956                    PackageParser.ServiceIntentInfo[] array =
12957                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12958                    intentFilters.toArray(array);
12959                    listCut.add(array);
12960                }
12961            }
12962            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12963        }
12964
12965        public final void addService(PackageParser.Service s) {
12966            mServices.put(s.getComponentName(), s);
12967            if (DEBUG_SHOW_INFO) {
12968                Log.v(TAG, "  "
12969                        + (s.info.nonLocalizedLabel != null
12970                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12971                Log.v(TAG, "    Class=" + s.info.name);
12972            }
12973            final int NI = s.intents.size();
12974            int j;
12975            for (j=0; j<NI; j++) {
12976                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12977                if (DEBUG_SHOW_INFO) {
12978                    Log.v(TAG, "    IntentFilter:");
12979                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12980                }
12981                if (!intent.debugCheck()) {
12982                    Log.w(TAG, "==> For Service " + s.info.name);
12983                }
12984                addFilter(intent);
12985            }
12986        }
12987
12988        public final void removeService(PackageParser.Service s) {
12989            mServices.remove(s.getComponentName());
12990            if (DEBUG_SHOW_INFO) {
12991                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12992                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12993                Log.v(TAG, "    Class=" + s.info.name);
12994            }
12995            final int NI = s.intents.size();
12996            int j;
12997            for (j=0; j<NI; j++) {
12998                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12999                if (DEBUG_SHOW_INFO) {
13000                    Log.v(TAG, "    IntentFilter:");
13001                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13002                }
13003                removeFilter(intent);
13004            }
13005        }
13006
13007        @Override
13008        protected boolean allowFilterResult(
13009                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13010            ServiceInfo filterSi = filter.service.info;
13011            for (int i=dest.size()-1; i>=0; i--) {
13012                ServiceInfo destAi = dest.get(i).serviceInfo;
13013                if (destAi.name == filterSi.name
13014                        && destAi.packageName == filterSi.packageName) {
13015                    return false;
13016                }
13017            }
13018            return true;
13019        }
13020
13021        @Override
13022        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13023            return new PackageParser.ServiceIntentInfo[size];
13024        }
13025
13026        @Override
13027        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13028            if (!sUserManager.exists(userId)) return true;
13029            PackageParser.Package p = filter.service.owner;
13030            if (p != null) {
13031                PackageSetting ps = (PackageSetting)p.mExtras;
13032                if (ps != null) {
13033                    // System apps are never considered stopped for purposes of
13034                    // filtering, because there may be no way for the user to
13035                    // actually re-launch them.
13036                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13037                            && ps.getStopped(userId);
13038                }
13039            }
13040            return false;
13041        }
13042
13043        @Override
13044        protected boolean isPackageForFilter(String packageName,
13045                PackageParser.ServiceIntentInfo info) {
13046            return packageName.equals(info.service.owner.packageName);
13047        }
13048
13049        @Override
13050        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13051                int match, int userId) {
13052            if (!sUserManager.exists(userId)) return null;
13053            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13054            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13055                return null;
13056            }
13057            final PackageParser.Service service = info.service;
13058            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13059            if (ps == null) {
13060                return null;
13061            }
13062            final PackageUserState userState = ps.readUserState(userId);
13063            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13064                    userState, userId);
13065            if (si == null) {
13066                return null;
13067            }
13068            final boolean matchVisibleToInstantApp =
13069                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13070            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13071            // throw out filters that aren't visible to ephemeral apps
13072            if (matchVisibleToInstantApp
13073                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13074                return null;
13075            }
13076            // throw out ephemeral filters if we're not explicitly requesting them
13077            if (!isInstantApp && userState.instantApp) {
13078                return null;
13079            }
13080            // throw out instant app filters if updates are available; will trigger
13081            // instant app resolution
13082            if (userState.instantApp && ps.isUpdateAvailable()) {
13083                return null;
13084            }
13085            final ResolveInfo res = new ResolveInfo();
13086            res.serviceInfo = si;
13087            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13088                res.filter = filter;
13089            }
13090            res.priority = info.getPriority();
13091            res.preferredOrder = service.owner.mPreferredOrder;
13092            res.match = match;
13093            res.isDefault = info.hasDefault;
13094            res.labelRes = info.labelRes;
13095            res.nonLocalizedLabel = info.nonLocalizedLabel;
13096            res.icon = info.icon;
13097            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13098            return res;
13099        }
13100
13101        @Override
13102        protected void sortResults(List<ResolveInfo> results) {
13103            Collections.sort(results, mResolvePrioritySorter);
13104        }
13105
13106        @Override
13107        protected void dumpFilter(PrintWriter out, String prefix,
13108                PackageParser.ServiceIntentInfo filter) {
13109            out.print(prefix); out.print(
13110                    Integer.toHexString(System.identityHashCode(filter.service)));
13111                    out.print(' ');
13112                    filter.service.printComponentShortName(out);
13113                    out.print(" filter ");
13114                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13115        }
13116
13117        @Override
13118        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13119            return filter.service;
13120        }
13121
13122        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13123            PackageParser.Service service = (PackageParser.Service)label;
13124            out.print(prefix); out.print(
13125                    Integer.toHexString(System.identityHashCode(service)));
13126                    out.print(' ');
13127                    service.printComponentShortName(out);
13128            if (count > 1) {
13129                out.print(" ("); out.print(count); out.print(" filters)");
13130            }
13131            out.println();
13132        }
13133
13134//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13135//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13136//            final List<ResolveInfo> retList = Lists.newArrayList();
13137//            while (i.hasNext()) {
13138//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13139//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13140//                    retList.add(resolveInfo);
13141//                }
13142//            }
13143//            return retList;
13144//        }
13145
13146        // Keys are String (activity class name), values are Activity.
13147        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13148                = new ArrayMap<ComponentName, PackageParser.Service>();
13149        private int mFlags;
13150    }
13151
13152    private final class ProviderIntentResolver
13153            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13154        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13155                boolean defaultOnly, int userId) {
13156            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13157            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13158        }
13159
13160        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13161                int userId) {
13162            if (!sUserManager.exists(userId))
13163                return null;
13164            mFlags = flags;
13165            return super.queryIntent(intent, resolvedType,
13166                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13167                    userId);
13168        }
13169
13170        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13171                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13172            if (!sUserManager.exists(userId))
13173                return null;
13174            if (packageProviders == null) {
13175                return null;
13176            }
13177            mFlags = flags;
13178            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13179            final int N = packageProviders.size();
13180            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13181                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13182
13183            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13184            for (int i = 0; i < N; ++i) {
13185                intentFilters = packageProviders.get(i).intents;
13186                if (intentFilters != null && intentFilters.size() > 0) {
13187                    PackageParser.ProviderIntentInfo[] array =
13188                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13189                    intentFilters.toArray(array);
13190                    listCut.add(array);
13191                }
13192            }
13193            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13194        }
13195
13196        public final void addProvider(PackageParser.Provider p) {
13197            if (mProviders.containsKey(p.getComponentName())) {
13198                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13199                return;
13200            }
13201
13202            mProviders.put(p.getComponentName(), p);
13203            if (DEBUG_SHOW_INFO) {
13204                Log.v(TAG, "  "
13205                        + (p.info.nonLocalizedLabel != null
13206                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13207                Log.v(TAG, "    Class=" + p.info.name);
13208            }
13209            final int NI = p.intents.size();
13210            int j;
13211            for (j = 0; j < NI; j++) {
13212                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13213                if (DEBUG_SHOW_INFO) {
13214                    Log.v(TAG, "    IntentFilter:");
13215                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13216                }
13217                if (!intent.debugCheck()) {
13218                    Log.w(TAG, "==> For Provider " + p.info.name);
13219                }
13220                addFilter(intent);
13221            }
13222        }
13223
13224        public final void removeProvider(PackageParser.Provider p) {
13225            mProviders.remove(p.getComponentName());
13226            if (DEBUG_SHOW_INFO) {
13227                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13228                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13229                Log.v(TAG, "    Class=" + p.info.name);
13230            }
13231            final int NI = p.intents.size();
13232            int j;
13233            for (j = 0; j < NI; j++) {
13234                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13235                if (DEBUG_SHOW_INFO) {
13236                    Log.v(TAG, "    IntentFilter:");
13237                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13238                }
13239                removeFilter(intent);
13240            }
13241        }
13242
13243        @Override
13244        protected boolean allowFilterResult(
13245                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13246            ProviderInfo filterPi = filter.provider.info;
13247            for (int i = dest.size() - 1; i >= 0; i--) {
13248                ProviderInfo destPi = dest.get(i).providerInfo;
13249                if (destPi.name == filterPi.name
13250                        && destPi.packageName == filterPi.packageName) {
13251                    return false;
13252                }
13253            }
13254            return true;
13255        }
13256
13257        @Override
13258        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13259            return new PackageParser.ProviderIntentInfo[size];
13260        }
13261
13262        @Override
13263        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13264            if (!sUserManager.exists(userId))
13265                return true;
13266            PackageParser.Package p = filter.provider.owner;
13267            if (p != null) {
13268                PackageSetting ps = (PackageSetting) p.mExtras;
13269                if (ps != null) {
13270                    // System apps are never considered stopped for purposes of
13271                    // filtering, because there may be no way for the user to
13272                    // actually re-launch them.
13273                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13274                            && ps.getStopped(userId);
13275                }
13276            }
13277            return false;
13278        }
13279
13280        @Override
13281        protected boolean isPackageForFilter(String packageName,
13282                PackageParser.ProviderIntentInfo info) {
13283            return packageName.equals(info.provider.owner.packageName);
13284        }
13285
13286        @Override
13287        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13288                int match, int userId) {
13289            if (!sUserManager.exists(userId))
13290                return null;
13291            final PackageParser.ProviderIntentInfo info = filter;
13292            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13293                return null;
13294            }
13295            final PackageParser.Provider provider = info.provider;
13296            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13297            if (ps == null) {
13298                return null;
13299            }
13300            final PackageUserState userState = ps.readUserState(userId);
13301            final boolean matchVisibleToInstantApp =
13302                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13303            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13304            // throw out filters that aren't visible to instant applications
13305            if (matchVisibleToInstantApp
13306                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13307                return null;
13308            }
13309            // throw out instant application filters if we're not explicitly requesting them
13310            if (!isInstantApp && userState.instantApp) {
13311                return null;
13312            }
13313            // throw out instant application filters if updates are available; will trigger
13314            // instant application resolution
13315            if (userState.instantApp && ps.isUpdateAvailable()) {
13316                return null;
13317            }
13318            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13319                    userState, userId);
13320            if (pi == null) {
13321                return null;
13322            }
13323            final ResolveInfo res = new ResolveInfo();
13324            res.providerInfo = pi;
13325            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13326                res.filter = filter;
13327            }
13328            res.priority = info.getPriority();
13329            res.preferredOrder = provider.owner.mPreferredOrder;
13330            res.match = match;
13331            res.isDefault = info.hasDefault;
13332            res.labelRes = info.labelRes;
13333            res.nonLocalizedLabel = info.nonLocalizedLabel;
13334            res.icon = info.icon;
13335            res.system = res.providerInfo.applicationInfo.isSystemApp();
13336            return res;
13337        }
13338
13339        @Override
13340        protected void sortResults(List<ResolveInfo> results) {
13341            Collections.sort(results, mResolvePrioritySorter);
13342        }
13343
13344        @Override
13345        protected void dumpFilter(PrintWriter out, String prefix,
13346                PackageParser.ProviderIntentInfo filter) {
13347            out.print(prefix);
13348            out.print(
13349                    Integer.toHexString(System.identityHashCode(filter.provider)));
13350            out.print(' ');
13351            filter.provider.printComponentShortName(out);
13352            out.print(" filter ");
13353            out.println(Integer.toHexString(System.identityHashCode(filter)));
13354        }
13355
13356        @Override
13357        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13358            return filter.provider;
13359        }
13360
13361        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13362            PackageParser.Provider provider = (PackageParser.Provider)label;
13363            out.print(prefix); out.print(
13364                    Integer.toHexString(System.identityHashCode(provider)));
13365                    out.print(' ');
13366                    provider.printComponentShortName(out);
13367            if (count > 1) {
13368                out.print(" ("); out.print(count); out.print(" filters)");
13369            }
13370            out.println();
13371        }
13372
13373        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13374                = new ArrayMap<ComponentName, PackageParser.Provider>();
13375        private int mFlags;
13376    }
13377
13378    static final class EphemeralIntentResolver
13379            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
13380        /**
13381         * The result that has the highest defined order. Ordering applies on a
13382         * per-package basis. Mapping is from package name to Pair of order and
13383         * EphemeralResolveInfo.
13384         * <p>
13385         * NOTE: This is implemented as a field variable for convenience and efficiency.
13386         * By having a field variable, we're able to track filter ordering as soon as
13387         * a non-zero order is defined. Otherwise, multiple loops across the result set
13388         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13389         * this needs to be contained entirely within {@link #filterResults}.
13390         */
13391        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13392
13393        @Override
13394        protected AuxiliaryResolveInfo[] newArray(int size) {
13395            return new AuxiliaryResolveInfo[size];
13396        }
13397
13398        @Override
13399        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
13400            return true;
13401        }
13402
13403        @Override
13404        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
13405                int userId) {
13406            if (!sUserManager.exists(userId)) {
13407                return null;
13408            }
13409            final String packageName = responseObj.resolveInfo.getPackageName();
13410            final Integer order = responseObj.getOrder();
13411            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13412                    mOrderResult.get(packageName);
13413            // ordering is enabled and this item's order isn't high enough
13414            if (lastOrderResult != null && lastOrderResult.first >= order) {
13415                return null;
13416            }
13417            final InstantAppResolveInfo res = responseObj.resolveInfo;
13418            if (order > 0) {
13419                // non-zero order, enable ordering
13420                mOrderResult.put(packageName, new Pair<>(order, res));
13421            }
13422            return responseObj;
13423        }
13424
13425        @Override
13426        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13427            // only do work if ordering is enabled [most of the time it won't be]
13428            if (mOrderResult.size() == 0) {
13429                return;
13430            }
13431            int resultSize = results.size();
13432            for (int i = 0; i < resultSize; i++) {
13433                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13434                final String packageName = info.getPackageName();
13435                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13436                if (savedInfo == null) {
13437                    // package doesn't having ordering
13438                    continue;
13439                }
13440                if (savedInfo.second == info) {
13441                    // circled back to the highest ordered item; remove from order list
13442                    mOrderResult.remove(savedInfo);
13443                    if (mOrderResult.size() == 0) {
13444                        // no more ordered items
13445                        break;
13446                    }
13447                    continue;
13448                }
13449                // item has a worse order, remove it from the result list
13450                results.remove(i);
13451                resultSize--;
13452                i--;
13453            }
13454        }
13455    }
13456
13457    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13458            new Comparator<ResolveInfo>() {
13459        public int compare(ResolveInfo r1, ResolveInfo r2) {
13460            int v1 = r1.priority;
13461            int v2 = r2.priority;
13462            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13463            if (v1 != v2) {
13464                return (v1 > v2) ? -1 : 1;
13465            }
13466            v1 = r1.preferredOrder;
13467            v2 = r2.preferredOrder;
13468            if (v1 != v2) {
13469                return (v1 > v2) ? -1 : 1;
13470            }
13471            if (r1.isDefault != r2.isDefault) {
13472                return r1.isDefault ? -1 : 1;
13473            }
13474            v1 = r1.match;
13475            v2 = r2.match;
13476            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13477            if (v1 != v2) {
13478                return (v1 > v2) ? -1 : 1;
13479            }
13480            if (r1.system != r2.system) {
13481                return r1.system ? -1 : 1;
13482            }
13483            if (r1.activityInfo != null) {
13484                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13485            }
13486            if (r1.serviceInfo != null) {
13487                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13488            }
13489            if (r1.providerInfo != null) {
13490                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13491            }
13492            return 0;
13493        }
13494    };
13495
13496    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13497            new Comparator<ProviderInfo>() {
13498        public int compare(ProviderInfo p1, ProviderInfo p2) {
13499            final int v1 = p1.initOrder;
13500            final int v2 = p2.initOrder;
13501            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13502        }
13503    };
13504
13505    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13506            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13507            final int[] userIds) {
13508        mHandler.post(new Runnable() {
13509            @Override
13510            public void run() {
13511                try {
13512                    final IActivityManager am = ActivityManager.getService();
13513                    if (am == null) return;
13514                    final int[] resolvedUserIds;
13515                    if (userIds == null) {
13516                        resolvedUserIds = am.getRunningUserIds();
13517                    } else {
13518                        resolvedUserIds = userIds;
13519                    }
13520                    for (int id : resolvedUserIds) {
13521                        final Intent intent = new Intent(action,
13522                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13523                        if (extras != null) {
13524                            intent.putExtras(extras);
13525                        }
13526                        if (targetPkg != null) {
13527                            intent.setPackage(targetPkg);
13528                        }
13529                        // Modify the UID when posting to other users
13530                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13531                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13532                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13533                            intent.putExtra(Intent.EXTRA_UID, uid);
13534                        }
13535                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13536                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13537                        if (DEBUG_BROADCASTS) {
13538                            RuntimeException here = new RuntimeException("here");
13539                            here.fillInStackTrace();
13540                            Slog.d(TAG, "Sending to user " + id + ": "
13541                                    + intent.toShortString(false, true, false, false)
13542                                    + " " + intent.getExtras(), here);
13543                        }
13544                        am.broadcastIntent(null, intent, null, finishedReceiver,
13545                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13546                                null, finishedReceiver != null, false, id);
13547                    }
13548                } catch (RemoteException ex) {
13549                }
13550            }
13551        });
13552    }
13553
13554    /**
13555     * Check if the external storage media is available. This is true if there
13556     * is a mounted external storage medium or if the external storage is
13557     * emulated.
13558     */
13559    private boolean isExternalMediaAvailable() {
13560        return mMediaMounted || Environment.isExternalStorageEmulated();
13561    }
13562
13563    @Override
13564    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13565        // writer
13566        synchronized (mPackages) {
13567            if (!isExternalMediaAvailable()) {
13568                // If the external storage is no longer mounted at this point,
13569                // the caller may not have been able to delete all of this
13570                // packages files and can not delete any more.  Bail.
13571                return null;
13572            }
13573            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13574            if (lastPackage != null) {
13575                pkgs.remove(lastPackage);
13576            }
13577            if (pkgs.size() > 0) {
13578                return pkgs.get(0);
13579            }
13580        }
13581        return null;
13582    }
13583
13584    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13585        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13586                userId, andCode ? 1 : 0, packageName);
13587        if (mSystemReady) {
13588            msg.sendToTarget();
13589        } else {
13590            if (mPostSystemReadyMessages == null) {
13591                mPostSystemReadyMessages = new ArrayList<>();
13592            }
13593            mPostSystemReadyMessages.add(msg);
13594        }
13595    }
13596
13597    void startCleaningPackages() {
13598        // reader
13599        if (!isExternalMediaAvailable()) {
13600            return;
13601        }
13602        synchronized (mPackages) {
13603            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13604                return;
13605            }
13606        }
13607        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13608        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13609        IActivityManager am = ActivityManager.getService();
13610        if (am != null) {
13611            int dcsUid = -1;
13612            synchronized (mPackages) {
13613                if (!mDefaultContainerWhitelisted) {
13614                    mDefaultContainerWhitelisted = true;
13615                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13616                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13617                }
13618            }
13619            try {
13620                if (dcsUid > 0) {
13621                    am.backgroundWhitelistUid(dcsUid);
13622                }
13623                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13624                        UserHandle.USER_SYSTEM);
13625            } catch (RemoteException e) {
13626            }
13627        }
13628    }
13629
13630    @Override
13631    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13632            int installFlags, String installerPackageName, int userId) {
13633        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13634
13635        final int callingUid = Binder.getCallingUid();
13636        enforceCrossUserPermission(callingUid, userId,
13637                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13638
13639        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13640            try {
13641                if (observer != null) {
13642                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13643                }
13644            } catch (RemoteException re) {
13645            }
13646            return;
13647        }
13648
13649        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13650            installFlags |= PackageManager.INSTALL_FROM_ADB;
13651
13652        } else {
13653            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13654            // about installerPackageName.
13655
13656            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13657            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13658        }
13659
13660        UserHandle user;
13661        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13662            user = UserHandle.ALL;
13663        } else {
13664            user = new UserHandle(userId);
13665        }
13666
13667        // Only system components can circumvent runtime permissions when installing.
13668        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13669                && mContext.checkCallingOrSelfPermission(Manifest.permission
13670                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13671            throw new SecurityException("You need the "
13672                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13673                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13674        }
13675
13676        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13677                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13678            throw new IllegalArgumentException(
13679                    "New installs into ASEC containers no longer supported");
13680        }
13681
13682        final File originFile = new File(originPath);
13683        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13684
13685        final Message msg = mHandler.obtainMessage(INIT_COPY);
13686        final VerificationInfo verificationInfo = new VerificationInfo(
13687                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13688        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13689                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13690                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13691                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13692        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13693        msg.obj = params;
13694
13695        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13696                System.identityHashCode(msg.obj));
13697        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13698                System.identityHashCode(msg.obj));
13699
13700        mHandler.sendMessage(msg);
13701    }
13702
13703
13704    /**
13705     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13706     * it is acting on behalf on an enterprise or the user).
13707     *
13708     * Note that the ordering of the conditionals in this method is important. The checks we perform
13709     * are as follows, in this order:
13710     *
13711     * 1) If the install is being performed by a system app, we can trust the app to have set the
13712     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13713     *    what it is.
13714     * 2) If the install is being performed by a device or profile owner app, the install reason
13715     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13716     *    set the install reason correctly. If the app targets an older SDK version where install
13717     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13718     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13719     * 3) In all other cases, the install is being performed by a regular app that is neither part
13720     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13721     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13722     *    set to enterprise policy and if so, change it to unknown instead.
13723     */
13724    private int fixUpInstallReason(String installerPackageName, int installerUid,
13725            int installReason) {
13726        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13727                == PERMISSION_GRANTED) {
13728            // If the install is being performed by a system app, we trust that app to have set the
13729            // install reason correctly.
13730            return installReason;
13731        }
13732
13733        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13734            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13735        if (dpm != null) {
13736            ComponentName owner = null;
13737            try {
13738                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13739                if (owner == null) {
13740                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13741                }
13742            } catch (RemoteException e) {
13743            }
13744            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13745                // If the install is being performed by a device or profile owner, the install
13746                // reason should be enterprise policy.
13747                return PackageManager.INSTALL_REASON_POLICY;
13748            }
13749        }
13750
13751        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13752            // If the install is being performed by a regular app (i.e. neither system app nor
13753            // device or profile owner), we have no reason to believe that the app is acting on
13754            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13755            // change it to unknown instead.
13756            return PackageManager.INSTALL_REASON_UNKNOWN;
13757        }
13758
13759        // If the install is being performed by a regular app and the install reason was set to any
13760        // value but enterprise policy, leave the install reason unchanged.
13761        return installReason;
13762    }
13763
13764    void installStage(String packageName, File stagedDir, String stagedCid,
13765            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13766            String installerPackageName, int installerUid, UserHandle user,
13767            Certificate[][] certificates) {
13768        if (DEBUG_EPHEMERAL) {
13769            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13770                Slog.d(TAG, "Ephemeral install of " + packageName);
13771            }
13772        }
13773        final VerificationInfo verificationInfo = new VerificationInfo(
13774                sessionParams.originatingUri, sessionParams.referrerUri,
13775                sessionParams.originatingUid, installerUid);
13776
13777        final OriginInfo origin;
13778        if (stagedDir != null) {
13779            origin = OriginInfo.fromStagedFile(stagedDir);
13780        } else {
13781            origin = OriginInfo.fromStagedContainer(stagedCid);
13782        }
13783
13784        final Message msg = mHandler.obtainMessage(INIT_COPY);
13785        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13786                sessionParams.installReason);
13787        final InstallParams params = new InstallParams(origin, null, observer,
13788                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13789                verificationInfo, user, sessionParams.abiOverride,
13790                sessionParams.grantedRuntimePermissions, certificates, installReason);
13791        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13792        msg.obj = params;
13793
13794        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13795                System.identityHashCode(msg.obj));
13796        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13797                System.identityHashCode(msg.obj));
13798
13799        mHandler.sendMessage(msg);
13800    }
13801
13802    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13803            int userId) {
13804        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13805        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13806
13807        // Send a session commit broadcast
13808        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13809        info.installReason = pkgSetting.getInstallReason(userId);
13810        info.appPackageName = packageName;
13811        sendSessionCommitBroadcast(info, userId);
13812    }
13813
13814    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13815        if (ArrayUtils.isEmpty(userIds)) {
13816            return;
13817        }
13818        Bundle extras = new Bundle(1);
13819        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13820        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13821
13822        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13823                packageName, extras, 0, null, null, userIds);
13824        if (isSystem) {
13825            mHandler.post(() -> {
13826                        for (int userId : userIds) {
13827                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13828                        }
13829                    }
13830            );
13831        }
13832    }
13833
13834    /**
13835     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13836     * automatically without needing an explicit launch.
13837     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13838     */
13839    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13840        // If user is not running, the app didn't miss any broadcast
13841        if (!mUserManagerInternal.isUserRunning(userId)) {
13842            return;
13843        }
13844        final IActivityManager am = ActivityManager.getService();
13845        try {
13846            // Deliver LOCKED_BOOT_COMPLETED first
13847            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13848                    .setPackage(packageName);
13849            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13850            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13851                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13852
13853            // Deliver BOOT_COMPLETED only if user is unlocked
13854            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13855                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13856                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13857                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13858            }
13859        } catch (RemoteException e) {
13860            throw e.rethrowFromSystemServer();
13861        }
13862    }
13863
13864    @Override
13865    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13866            int userId) {
13867        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13868        PackageSetting pkgSetting;
13869        final int uid = Binder.getCallingUid();
13870        enforceCrossUserPermission(uid, userId,
13871                true /* requireFullPermission */, true /* checkShell */,
13872                "setApplicationHiddenSetting for user " + userId);
13873
13874        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13875            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13876            return false;
13877        }
13878
13879        long callingId = Binder.clearCallingIdentity();
13880        try {
13881            boolean sendAdded = false;
13882            boolean sendRemoved = false;
13883            // writer
13884            synchronized (mPackages) {
13885                pkgSetting = mSettings.mPackages.get(packageName);
13886                if (pkgSetting == null) {
13887                    return false;
13888                }
13889                // Do not allow "android" is being disabled
13890                if ("android".equals(packageName)) {
13891                    Slog.w(TAG, "Cannot hide package: android");
13892                    return false;
13893                }
13894                // Cannot hide static shared libs as they are considered
13895                // a part of the using app (emulating static linking). Also
13896                // static libs are installed always on internal storage.
13897                PackageParser.Package pkg = mPackages.get(packageName);
13898                if (pkg != null && pkg.staticSharedLibName != null) {
13899                    Slog.w(TAG, "Cannot hide package: " + packageName
13900                            + " providing static shared library: "
13901                            + pkg.staticSharedLibName);
13902                    return false;
13903                }
13904                // Only allow protected packages to hide themselves.
13905                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13906                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13907                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13908                    return false;
13909                }
13910
13911                if (pkgSetting.getHidden(userId) != hidden) {
13912                    pkgSetting.setHidden(hidden, userId);
13913                    mSettings.writePackageRestrictionsLPr(userId);
13914                    if (hidden) {
13915                        sendRemoved = true;
13916                    } else {
13917                        sendAdded = true;
13918                    }
13919                }
13920            }
13921            if (sendAdded) {
13922                sendPackageAddedForUser(packageName, pkgSetting, userId);
13923                return true;
13924            }
13925            if (sendRemoved) {
13926                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13927                        "hiding pkg");
13928                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13929                return true;
13930            }
13931        } finally {
13932            Binder.restoreCallingIdentity(callingId);
13933        }
13934        return false;
13935    }
13936
13937    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13938            int userId) {
13939        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13940        info.removedPackage = packageName;
13941        info.installerPackageName = pkgSetting.installerPackageName;
13942        info.removedUsers = new int[] {userId};
13943        info.broadcastUsers = new int[] {userId};
13944        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13945        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13946    }
13947
13948    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13949        if (pkgList.length > 0) {
13950            Bundle extras = new Bundle(1);
13951            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13952
13953            sendPackageBroadcast(
13954                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13955                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13956                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13957                    new int[] {userId});
13958        }
13959    }
13960
13961    /**
13962     * Returns true if application is not found or there was an error. Otherwise it returns
13963     * the hidden state of the package for the given user.
13964     */
13965    @Override
13966    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13967        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13968        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13969                true /* requireFullPermission */, false /* checkShell */,
13970                "getApplicationHidden for user " + userId);
13971        PackageSetting pkgSetting;
13972        long callingId = Binder.clearCallingIdentity();
13973        try {
13974            // writer
13975            synchronized (mPackages) {
13976                pkgSetting = mSettings.mPackages.get(packageName);
13977                if (pkgSetting == null) {
13978                    return true;
13979                }
13980                return pkgSetting.getHidden(userId);
13981            }
13982        } finally {
13983            Binder.restoreCallingIdentity(callingId);
13984        }
13985    }
13986
13987    /**
13988     * @hide
13989     */
13990    @Override
13991    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13992            int installReason) {
13993        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13994                null);
13995        PackageSetting pkgSetting;
13996        final int uid = Binder.getCallingUid();
13997        enforceCrossUserPermission(uid, userId,
13998                true /* requireFullPermission */, true /* checkShell */,
13999                "installExistingPackage for user " + userId);
14000        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14001            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14002        }
14003
14004        long callingId = Binder.clearCallingIdentity();
14005        try {
14006            boolean installed = false;
14007            final boolean instantApp =
14008                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14009            final boolean fullApp =
14010                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14011
14012            // writer
14013            synchronized (mPackages) {
14014                pkgSetting = mSettings.mPackages.get(packageName);
14015                if (pkgSetting == null) {
14016                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14017                }
14018                if (!pkgSetting.getInstalled(userId)) {
14019                    pkgSetting.setInstalled(true, userId);
14020                    pkgSetting.setHidden(false, userId);
14021                    pkgSetting.setInstallReason(installReason, userId);
14022                    mSettings.writePackageRestrictionsLPr(userId);
14023                    mSettings.writeKernelMappingLPr(pkgSetting);
14024                    installed = true;
14025                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14026                    // upgrade app from instant to full; we don't allow app downgrade
14027                    installed = true;
14028                }
14029                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14030            }
14031
14032            if (installed) {
14033                if (pkgSetting.pkg != null) {
14034                    synchronized (mInstallLock) {
14035                        // We don't need to freeze for a brand new install
14036                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14037                    }
14038                }
14039                sendPackageAddedForUser(packageName, pkgSetting, userId);
14040                synchronized (mPackages) {
14041                    updateSequenceNumberLP(packageName, new int[]{ userId });
14042                }
14043            }
14044        } finally {
14045            Binder.restoreCallingIdentity(callingId);
14046        }
14047
14048        return PackageManager.INSTALL_SUCCEEDED;
14049    }
14050
14051    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14052            boolean instantApp, boolean fullApp) {
14053        // no state specified; do nothing
14054        if (!instantApp && !fullApp) {
14055            return;
14056        }
14057        if (userId != UserHandle.USER_ALL) {
14058            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14059                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14060            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14061                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14062            }
14063        } else {
14064            for (int currentUserId : sUserManager.getUserIds()) {
14065                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14066                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14067                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14068                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14069                }
14070            }
14071        }
14072    }
14073
14074    boolean isUserRestricted(int userId, String restrictionKey) {
14075        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14076        if (restrictions.getBoolean(restrictionKey, false)) {
14077            Log.w(TAG, "User is restricted: " + restrictionKey);
14078            return true;
14079        }
14080        return false;
14081    }
14082
14083    @Override
14084    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14085            int userId) {
14086        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14087        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14088                true /* requireFullPermission */, true /* checkShell */,
14089                "setPackagesSuspended for user " + userId);
14090
14091        if (ArrayUtils.isEmpty(packageNames)) {
14092            return packageNames;
14093        }
14094
14095        // List of package names for whom the suspended state has changed.
14096        List<String> changedPackages = new ArrayList<>(packageNames.length);
14097        // List of package names for whom the suspended state is not set as requested in this
14098        // method.
14099        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14100        long callingId = Binder.clearCallingIdentity();
14101        try {
14102            for (int i = 0; i < packageNames.length; i++) {
14103                String packageName = packageNames[i];
14104                boolean changed = false;
14105                final int appId;
14106                synchronized (mPackages) {
14107                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14108                    if (pkgSetting == null) {
14109                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14110                                + "\". Skipping suspending/un-suspending.");
14111                        unactionedPackages.add(packageName);
14112                        continue;
14113                    }
14114                    appId = pkgSetting.appId;
14115                    if (pkgSetting.getSuspended(userId) != suspended) {
14116                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14117                            unactionedPackages.add(packageName);
14118                            continue;
14119                        }
14120                        pkgSetting.setSuspended(suspended, userId);
14121                        mSettings.writePackageRestrictionsLPr(userId);
14122                        changed = true;
14123                        changedPackages.add(packageName);
14124                    }
14125                }
14126
14127                if (changed && suspended) {
14128                    killApplication(packageName, UserHandle.getUid(userId, appId),
14129                            "suspending package");
14130                }
14131            }
14132        } finally {
14133            Binder.restoreCallingIdentity(callingId);
14134        }
14135
14136        if (!changedPackages.isEmpty()) {
14137            sendPackagesSuspendedForUser(changedPackages.toArray(
14138                    new String[changedPackages.size()]), userId, suspended);
14139        }
14140
14141        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14142    }
14143
14144    @Override
14145    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14146        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14147                true /* requireFullPermission */, false /* checkShell */,
14148                "isPackageSuspendedForUser for user " + userId);
14149        synchronized (mPackages) {
14150            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14151            if (pkgSetting == null) {
14152                throw new IllegalArgumentException("Unknown target package: " + packageName);
14153            }
14154            return pkgSetting.getSuspended(userId);
14155        }
14156    }
14157
14158    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14159        if (isPackageDeviceAdmin(packageName, userId)) {
14160            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14161                    + "\": has an active device admin");
14162            return false;
14163        }
14164
14165        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14166        if (packageName.equals(activeLauncherPackageName)) {
14167            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14168                    + "\": contains the active launcher");
14169            return false;
14170        }
14171
14172        if (packageName.equals(mRequiredInstallerPackage)) {
14173            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14174                    + "\": required for package installation");
14175            return false;
14176        }
14177
14178        if (packageName.equals(mRequiredUninstallerPackage)) {
14179            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14180                    + "\": required for package uninstallation");
14181            return false;
14182        }
14183
14184        if (packageName.equals(mRequiredVerifierPackage)) {
14185            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14186                    + "\": required for package verification");
14187            return false;
14188        }
14189
14190        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14191            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14192                    + "\": is the default dialer");
14193            return false;
14194        }
14195
14196        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14197            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14198                    + "\": protected package");
14199            return false;
14200        }
14201
14202        // Cannot suspend static shared libs as they are considered
14203        // a part of the using app (emulating static linking). Also
14204        // static libs are installed always on internal storage.
14205        PackageParser.Package pkg = mPackages.get(packageName);
14206        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14207            Slog.w(TAG, "Cannot suspend package: " + packageName
14208                    + " providing static shared library: "
14209                    + pkg.staticSharedLibName);
14210            return false;
14211        }
14212
14213        return true;
14214    }
14215
14216    private String getActiveLauncherPackageName(int userId) {
14217        Intent intent = new Intent(Intent.ACTION_MAIN);
14218        intent.addCategory(Intent.CATEGORY_HOME);
14219        ResolveInfo resolveInfo = resolveIntent(
14220                intent,
14221                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14222                PackageManager.MATCH_DEFAULT_ONLY,
14223                userId);
14224
14225        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14226    }
14227
14228    private String getDefaultDialerPackageName(int userId) {
14229        synchronized (mPackages) {
14230            return mSettings.getDefaultDialerPackageNameLPw(userId);
14231        }
14232    }
14233
14234    @Override
14235    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14236        mContext.enforceCallingOrSelfPermission(
14237                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14238                "Only package verification agents can verify applications");
14239
14240        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14241        final PackageVerificationResponse response = new PackageVerificationResponse(
14242                verificationCode, Binder.getCallingUid());
14243        msg.arg1 = id;
14244        msg.obj = response;
14245        mHandler.sendMessage(msg);
14246    }
14247
14248    @Override
14249    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14250            long millisecondsToDelay) {
14251        mContext.enforceCallingOrSelfPermission(
14252                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14253                "Only package verification agents can extend verification timeouts");
14254
14255        final PackageVerificationState state = mPendingVerification.get(id);
14256        final PackageVerificationResponse response = new PackageVerificationResponse(
14257                verificationCodeAtTimeout, Binder.getCallingUid());
14258
14259        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14260            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14261        }
14262        if (millisecondsToDelay < 0) {
14263            millisecondsToDelay = 0;
14264        }
14265        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14266                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14267            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14268        }
14269
14270        if ((state != null) && !state.timeoutExtended()) {
14271            state.extendTimeout();
14272
14273            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14274            msg.arg1 = id;
14275            msg.obj = response;
14276            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14277        }
14278    }
14279
14280    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14281            int verificationCode, UserHandle user) {
14282        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14283        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14284        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14285        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14286        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14287
14288        mContext.sendBroadcastAsUser(intent, user,
14289                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14290    }
14291
14292    private ComponentName matchComponentForVerifier(String packageName,
14293            List<ResolveInfo> receivers) {
14294        ActivityInfo targetReceiver = null;
14295
14296        final int NR = receivers.size();
14297        for (int i = 0; i < NR; i++) {
14298            final ResolveInfo info = receivers.get(i);
14299            if (info.activityInfo == null) {
14300                continue;
14301            }
14302
14303            if (packageName.equals(info.activityInfo.packageName)) {
14304                targetReceiver = info.activityInfo;
14305                break;
14306            }
14307        }
14308
14309        if (targetReceiver == null) {
14310            return null;
14311        }
14312
14313        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14314    }
14315
14316    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14317            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14318        if (pkgInfo.verifiers.length == 0) {
14319            return null;
14320        }
14321
14322        final int N = pkgInfo.verifiers.length;
14323        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14324        for (int i = 0; i < N; i++) {
14325            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14326
14327            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14328                    receivers);
14329            if (comp == null) {
14330                continue;
14331            }
14332
14333            final int verifierUid = getUidForVerifier(verifierInfo);
14334            if (verifierUid == -1) {
14335                continue;
14336            }
14337
14338            if (DEBUG_VERIFY) {
14339                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14340                        + " with the correct signature");
14341            }
14342            sufficientVerifiers.add(comp);
14343            verificationState.addSufficientVerifier(verifierUid);
14344        }
14345
14346        return sufficientVerifiers;
14347    }
14348
14349    private int getUidForVerifier(VerifierInfo verifierInfo) {
14350        synchronized (mPackages) {
14351            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14352            if (pkg == null) {
14353                return -1;
14354            } else if (pkg.mSignatures.length != 1) {
14355                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14356                        + " has more than one signature; ignoring");
14357                return -1;
14358            }
14359
14360            /*
14361             * If the public key of the package's signature does not match
14362             * our expected public key, then this is a different package and
14363             * we should skip.
14364             */
14365
14366            final byte[] expectedPublicKey;
14367            try {
14368                final Signature verifierSig = pkg.mSignatures[0];
14369                final PublicKey publicKey = verifierSig.getPublicKey();
14370                expectedPublicKey = publicKey.getEncoded();
14371            } catch (CertificateException e) {
14372                return -1;
14373            }
14374
14375            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14376
14377            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14378                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14379                        + " does not have the expected public key; ignoring");
14380                return -1;
14381            }
14382
14383            return pkg.applicationInfo.uid;
14384        }
14385    }
14386
14387    @Override
14388    public void finishPackageInstall(int token, boolean didLaunch) {
14389        enforceSystemOrRoot("Only the system is allowed to finish installs");
14390
14391        if (DEBUG_INSTALL) {
14392            Slog.v(TAG, "BM finishing package install for " + token);
14393        }
14394        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14395
14396        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14397        mHandler.sendMessage(msg);
14398    }
14399
14400    /**
14401     * Get the verification agent timeout.  Used for both the APK verifier and the
14402     * intent filter verifier.
14403     *
14404     * @return verification timeout in milliseconds
14405     */
14406    private long getVerificationTimeout() {
14407        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14408                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14409                DEFAULT_VERIFICATION_TIMEOUT);
14410    }
14411
14412    /**
14413     * Get the default verification agent response code.
14414     *
14415     * @return default verification response code
14416     */
14417    private int getDefaultVerificationResponse(UserHandle user) {
14418        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14419            return PackageManager.VERIFICATION_REJECT;
14420        }
14421        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14422                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14423                DEFAULT_VERIFICATION_RESPONSE);
14424    }
14425
14426    /**
14427     * Check whether or not package verification has been enabled.
14428     *
14429     * @return true if verification should be performed
14430     */
14431    private boolean isVerificationEnabled(int userId, int installFlags) {
14432        if (!DEFAULT_VERIFY_ENABLE) {
14433            return false;
14434        }
14435
14436        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14437
14438        // Check if installing from ADB
14439        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14440            // Do not run verification in a test harness environment
14441            if (ActivityManager.isRunningInTestHarness()) {
14442                return false;
14443            }
14444            if (ensureVerifyAppsEnabled) {
14445                return true;
14446            }
14447            // Check if the developer does not want package verification for ADB installs
14448            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14449                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14450                return false;
14451            }
14452        }
14453
14454        if (ensureVerifyAppsEnabled) {
14455            return true;
14456        }
14457
14458        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14459                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14460    }
14461
14462    @Override
14463    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14464            throws RemoteException {
14465        mContext.enforceCallingOrSelfPermission(
14466                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14467                "Only intentfilter verification agents can verify applications");
14468
14469        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14470        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14471                Binder.getCallingUid(), verificationCode, failedDomains);
14472        msg.arg1 = id;
14473        msg.obj = response;
14474        mHandler.sendMessage(msg);
14475    }
14476
14477    @Override
14478    public int getIntentVerificationStatus(String packageName, int userId) {
14479        synchronized (mPackages) {
14480            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14481        }
14482    }
14483
14484    @Override
14485    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14486        mContext.enforceCallingOrSelfPermission(
14487                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14488
14489        boolean result = false;
14490        synchronized (mPackages) {
14491            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14492        }
14493        if (result) {
14494            scheduleWritePackageRestrictionsLocked(userId);
14495        }
14496        return result;
14497    }
14498
14499    @Override
14500    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14501            String packageName) {
14502        synchronized (mPackages) {
14503            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14504        }
14505    }
14506
14507    @Override
14508    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14509        if (TextUtils.isEmpty(packageName)) {
14510            return ParceledListSlice.emptyList();
14511        }
14512        synchronized (mPackages) {
14513            PackageParser.Package pkg = mPackages.get(packageName);
14514            if (pkg == null || pkg.activities == null) {
14515                return ParceledListSlice.emptyList();
14516            }
14517            final int count = pkg.activities.size();
14518            ArrayList<IntentFilter> result = new ArrayList<>();
14519            for (int n=0; n<count; n++) {
14520                PackageParser.Activity activity = pkg.activities.get(n);
14521                if (activity.intents != null && activity.intents.size() > 0) {
14522                    result.addAll(activity.intents);
14523                }
14524            }
14525            return new ParceledListSlice<>(result);
14526        }
14527    }
14528
14529    @Override
14530    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14531        mContext.enforceCallingOrSelfPermission(
14532                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14533
14534        synchronized (mPackages) {
14535            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14536            if (packageName != null) {
14537                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14538                        packageName, userId);
14539            }
14540            return result;
14541        }
14542    }
14543
14544    @Override
14545    public String getDefaultBrowserPackageName(int userId) {
14546        synchronized (mPackages) {
14547            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14548        }
14549    }
14550
14551    /**
14552     * Get the "allow unknown sources" setting.
14553     *
14554     * @return the current "allow unknown sources" setting
14555     */
14556    private int getUnknownSourcesSettings() {
14557        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14558                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14559                -1);
14560    }
14561
14562    @Override
14563    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14564        final int uid = Binder.getCallingUid();
14565        // writer
14566        synchronized (mPackages) {
14567            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14568            if (targetPackageSetting == null) {
14569                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14570            }
14571
14572            PackageSetting installerPackageSetting;
14573            if (installerPackageName != null) {
14574                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14575                if (installerPackageSetting == null) {
14576                    throw new IllegalArgumentException("Unknown installer package: "
14577                            + installerPackageName);
14578                }
14579            } else {
14580                installerPackageSetting = null;
14581            }
14582
14583            Signature[] callerSignature;
14584            Object obj = mSettings.getUserIdLPr(uid);
14585            if (obj != null) {
14586                if (obj instanceof SharedUserSetting) {
14587                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14588                } else if (obj instanceof PackageSetting) {
14589                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14590                } else {
14591                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
14592                }
14593            } else {
14594                throw new SecurityException("Unknown calling UID: " + uid);
14595            }
14596
14597            // Verify: can't set installerPackageName to a package that is
14598            // not signed with the same cert as the caller.
14599            if (installerPackageSetting != null) {
14600                if (compareSignatures(callerSignature,
14601                        installerPackageSetting.signatures.mSignatures)
14602                        != PackageManager.SIGNATURE_MATCH) {
14603                    throw new SecurityException(
14604                            "Caller does not have same cert as new installer package "
14605                            + installerPackageName);
14606                }
14607            }
14608
14609            // Verify: if target already has an installer package, it must
14610            // be signed with the same cert as the caller.
14611            if (targetPackageSetting.installerPackageName != null) {
14612                PackageSetting setting = mSettings.mPackages.get(
14613                        targetPackageSetting.installerPackageName);
14614                // If the currently set package isn't valid, then it's always
14615                // okay to change it.
14616                if (setting != null) {
14617                    if (compareSignatures(callerSignature,
14618                            setting.signatures.mSignatures)
14619                            != PackageManager.SIGNATURE_MATCH) {
14620                        throw new SecurityException(
14621                                "Caller does not have same cert as old installer package "
14622                                + targetPackageSetting.installerPackageName);
14623                    }
14624                }
14625            }
14626
14627            // Okay!
14628            targetPackageSetting.installerPackageName = installerPackageName;
14629            if (installerPackageName != null) {
14630                mSettings.mInstallerPackages.add(installerPackageName);
14631            }
14632            scheduleWriteSettingsLocked();
14633        }
14634    }
14635
14636    @Override
14637    public void setApplicationCategoryHint(String packageName, int categoryHint,
14638            String callerPackageName) {
14639        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14640                callerPackageName);
14641        synchronized (mPackages) {
14642            PackageSetting ps = mSettings.mPackages.get(packageName);
14643            if (ps == null) {
14644                throw new IllegalArgumentException("Unknown target package " + packageName);
14645            }
14646
14647            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14648                throw new IllegalArgumentException("Calling package " + callerPackageName
14649                        + " is not installer for " + packageName);
14650            }
14651
14652            if (ps.categoryHint != categoryHint) {
14653                ps.categoryHint = categoryHint;
14654                scheduleWriteSettingsLocked();
14655            }
14656        }
14657    }
14658
14659    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14660        // Queue up an async operation since the package installation may take a little while.
14661        mHandler.post(new Runnable() {
14662            public void run() {
14663                mHandler.removeCallbacks(this);
14664                 // Result object to be returned
14665                PackageInstalledInfo res = new PackageInstalledInfo();
14666                res.setReturnCode(currentStatus);
14667                res.uid = -1;
14668                res.pkg = null;
14669                res.removedInfo = null;
14670                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14671                    args.doPreInstall(res.returnCode);
14672                    synchronized (mInstallLock) {
14673                        installPackageTracedLI(args, res);
14674                    }
14675                    args.doPostInstall(res.returnCode, res.uid);
14676                }
14677
14678                // A restore should be performed at this point if (a) the install
14679                // succeeded, (b) the operation is not an update, and (c) the new
14680                // package has not opted out of backup participation.
14681                final boolean update = res.removedInfo != null
14682                        && res.removedInfo.removedPackage != null;
14683                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14684                boolean doRestore = !update
14685                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14686
14687                // Set up the post-install work request bookkeeping.  This will be used
14688                // and cleaned up by the post-install event handling regardless of whether
14689                // there's a restore pass performed.  Token values are >= 1.
14690                int token;
14691                if (mNextInstallToken < 0) mNextInstallToken = 1;
14692                token = mNextInstallToken++;
14693
14694                PostInstallData data = new PostInstallData(args, res);
14695                mRunningInstalls.put(token, data);
14696                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14697
14698                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14699                    // Pass responsibility to the Backup Manager.  It will perform a
14700                    // restore if appropriate, then pass responsibility back to the
14701                    // Package Manager to run the post-install observer callbacks
14702                    // and broadcasts.
14703                    IBackupManager bm = IBackupManager.Stub.asInterface(
14704                            ServiceManager.getService(Context.BACKUP_SERVICE));
14705                    if (bm != null) {
14706                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14707                                + " to BM for possible restore");
14708                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14709                        try {
14710                            // TODO: http://b/22388012
14711                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14712                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14713                            } else {
14714                                doRestore = false;
14715                            }
14716                        } catch (RemoteException e) {
14717                            // can't happen; the backup manager is local
14718                        } catch (Exception e) {
14719                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14720                            doRestore = false;
14721                        }
14722                    } else {
14723                        Slog.e(TAG, "Backup Manager not found!");
14724                        doRestore = false;
14725                    }
14726                }
14727
14728                if (!doRestore) {
14729                    // No restore possible, or the Backup Manager was mysteriously not
14730                    // available -- just fire the post-install work request directly.
14731                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14732
14733                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14734
14735                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14736                    mHandler.sendMessage(msg);
14737                }
14738            }
14739        });
14740    }
14741
14742    /**
14743     * Callback from PackageSettings whenever an app is first transitioned out of the
14744     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14745     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14746     * here whether the app is the target of an ongoing install, and only send the
14747     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14748     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14749     * handling.
14750     */
14751    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14752        // Serialize this with the rest of the install-process message chain.  In the
14753        // restore-at-install case, this Runnable will necessarily run before the
14754        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14755        // are coherent.  In the non-restore case, the app has already completed install
14756        // and been launched through some other means, so it is not in a problematic
14757        // state for observers to see the FIRST_LAUNCH signal.
14758        mHandler.post(new Runnable() {
14759            @Override
14760            public void run() {
14761                for (int i = 0; i < mRunningInstalls.size(); i++) {
14762                    final PostInstallData data = mRunningInstalls.valueAt(i);
14763                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14764                        continue;
14765                    }
14766                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14767                        // right package; but is it for the right user?
14768                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14769                            if (userId == data.res.newUsers[uIndex]) {
14770                                if (DEBUG_BACKUP) {
14771                                    Slog.i(TAG, "Package " + pkgName
14772                                            + " being restored so deferring FIRST_LAUNCH");
14773                                }
14774                                return;
14775                            }
14776                        }
14777                    }
14778                }
14779                // didn't find it, so not being restored
14780                if (DEBUG_BACKUP) {
14781                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14782                }
14783                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14784            }
14785        });
14786    }
14787
14788    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14789        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14790                installerPkg, null, userIds);
14791    }
14792
14793    private abstract class HandlerParams {
14794        private static final int MAX_RETRIES = 4;
14795
14796        /**
14797         * Number of times startCopy() has been attempted and had a non-fatal
14798         * error.
14799         */
14800        private int mRetries = 0;
14801
14802        /** User handle for the user requesting the information or installation. */
14803        private final UserHandle mUser;
14804        String traceMethod;
14805        int traceCookie;
14806
14807        HandlerParams(UserHandle user) {
14808            mUser = user;
14809        }
14810
14811        UserHandle getUser() {
14812            return mUser;
14813        }
14814
14815        HandlerParams setTraceMethod(String traceMethod) {
14816            this.traceMethod = traceMethod;
14817            return this;
14818        }
14819
14820        HandlerParams setTraceCookie(int traceCookie) {
14821            this.traceCookie = traceCookie;
14822            return this;
14823        }
14824
14825        final boolean startCopy() {
14826            boolean res;
14827            try {
14828                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14829
14830                if (++mRetries > MAX_RETRIES) {
14831                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14832                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14833                    handleServiceError();
14834                    return false;
14835                } else {
14836                    handleStartCopy();
14837                    res = true;
14838                }
14839            } catch (RemoteException e) {
14840                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14841                mHandler.sendEmptyMessage(MCS_RECONNECT);
14842                res = false;
14843            }
14844            handleReturnCode();
14845            return res;
14846        }
14847
14848        final void serviceError() {
14849            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14850            handleServiceError();
14851            handleReturnCode();
14852        }
14853
14854        abstract void handleStartCopy() throws RemoteException;
14855        abstract void handleServiceError();
14856        abstract void handleReturnCode();
14857    }
14858
14859    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14860        for (File path : paths) {
14861            try {
14862                mcs.clearDirectory(path.getAbsolutePath());
14863            } catch (RemoteException e) {
14864            }
14865        }
14866    }
14867
14868    static class OriginInfo {
14869        /**
14870         * Location where install is coming from, before it has been
14871         * copied/renamed into place. This could be a single monolithic APK
14872         * file, or a cluster directory. This location may be untrusted.
14873         */
14874        final File file;
14875        final String cid;
14876
14877        /**
14878         * Flag indicating that {@link #file} or {@link #cid} has already been
14879         * staged, meaning downstream users don't need to defensively copy the
14880         * contents.
14881         */
14882        final boolean staged;
14883
14884        /**
14885         * Flag indicating that {@link #file} or {@link #cid} is an already
14886         * installed app that is being moved.
14887         */
14888        final boolean existing;
14889
14890        final String resolvedPath;
14891        final File resolvedFile;
14892
14893        static OriginInfo fromNothing() {
14894            return new OriginInfo(null, null, false, false);
14895        }
14896
14897        static OriginInfo fromUntrustedFile(File file) {
14898            return new OriginInfo(file, null, false, false);
14899        }
14900
14901        static OriginInfo fromExistingFile(File file) {
14902            return new OriginInfo(file, null, false, true);
14903        }
14904
14905        static OriginInfo fromStagedFile(File file) {
14906            return new OriginInfo(file, null, true, false);
14907        }
14908
14909        static OriginInfo fromStagedContainer(String cid) {
14910            return new OriginInfo(null, cid, true, false);
14911        }
14912
14913        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14914            this.file = file;
14915            this.cid = cid;
14916            this.staged = staged;
14917            this.existing = existing;
14918
14919            if (cid != null) {
14920                resolvedPath = PackageHelper.getSdDir(cid);
14921                resolvedFile = new File(resolvedPath);
14922            } else if (file != null) {
14923                resolvedPath = file.getAbsolutePath();
14924                resolvedFile = file;
14925            } else {
14926                resolvedPath = null;
14927                resolvedFile = null;
14928            }
14929        }
14930    }
14931
14932    static class MoveInfo {
14933        final int moveId;
14934        final String fromUuid;
14935        final String toUuid;
14936        final String packageName;
14937        final String dataAppName;
14938        final int appId;
14939        final String seinfo;
14940        final int targetSdkVersion;
14941
14942        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14943                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14944            this.moveId = moveId;
14945            this.fromUuid = fromUuid;
14946            this.toUuid = toUuid;
14947            this.packageName = packageName;
14948            this.dataAppName = dataAppName;
14949            this.appId = appId;
14950            this.seinfo = seinfo;
14951            this.targetSdkVersion = targetSdkVersion;
14952        }
14953    }
14954
14955    static class VerificationInfo {
14956        /** A constant used to indicate that a uid value is not present. */
14957        public static final int NO_UID = -1;
14958
14959        /** URI referencing where the package was downloaded from. */
14960        final Uri originatingUri;
14961
14962        /** HTTP referrer URI associated with the originatingURI. */
14963        final Uri referrer;
14964
14965        /** UID of the application that the install request originated from. */
14966        final int originatingUid;
14967
14968        /** UID of application requesting the install */
14969        final int installerUid;
14970
14971        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14972            this.originatingUri = originatingUri;
14973            this.referrer = referrer;
14974            this.originatingUid = originatingUid;
14975            this.installerUid = installerUid;
14976        }
14977    }
14978
14979    class InstallParams extends HandlerParams {
14980        final OriginInfo origin;
14981        final MoveInfo move;
14982        final IPackageInstallObserver2 observer;
14983        int installFlags;
14984        final String installerPackageName;
14985        final String volumeUuid;
14986        private InstallArgs mArgs;
14987        private int mRet;
14988        final String packageAbiOverride;
14989        final String[] grantedRuntimePermissions;
14990        final VerificationInfo verificationInfo;
14991        final Certificate[][] certificates;
14992        final int installReason;
14993
14994        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14995                int installFlags, String installerPackageName, String volumeUuid,
14996                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14997                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14998            super(user);
14999            this.origin = origin;
15000            this.move = move;
15001            this.observer = observer;
15002            this.installFlags = installFlags;
15003            this.installerPackageName = installerPackageName;
15004            this.volumeUuid = volumeUuid;
15005            this.verificationInfo = verificationInfo;
15006            this.packageAbiOverride = packageAbiOverride;
15007            this.grantedRuntimePermissions = grantedPermissions;
15008            this.certificates = certificates;
15009            this.installReason = installReason;
15010        }
15011
15012        @Override
15013        public String toString() {
15014            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15015                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15016        }
15017
15018        private int installLocationPolicy(PackageInfoLite pkgLite) {
15019            String packageName = pkgLite.packageName;
15020            int installLocation = pkgLite.installLocation;
15021            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15022            // reader
15023            synchronized (mPackages) {
15024                // Currently installed package which the new package is attempting to replace or
15025                // null if no such package is installed.
15026                PackageParser.Package installedPkg = mPackages.get(packageName);
15027                // Package which currently owns the data which the new package will own if installed.
15028                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15029                // will be null whereas dataOwnerPkg will contain information about the package
15030                // which was uninstalled while keeping its data.
15031                PackageParser.Package dataOwnerPkg = installedPkg;
15032                if (dataOwnerPkg  == null) {
15033                    PackageSetting ps = mSettings.mPackages.get(packageName);
15034                    if (ps != null) {
15035                        dataOwnerPkg = ps.pkg;
15036                    }
15037                }
15038
15039                if (dataOwnerPkg != null) {
15040                    // If installed, the package will get access to data left on the device by its
15041                    // predecessor. As a security measure, this is permited only if this is not a
15042                    // version downgrade or if the predecessor package is marked as debuggable and
15043                    // a downgrade is explicitly requested.
15044                    //
15045                    // On debuggable platform builds, downgrades are permitted even for
15046                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15047                    // not offer security guarantees and thus it's OK to disable some security
15048                    // mechanisms to make debugging/testing easier on those builds. However, even on
15049                    // debuggable builds downgrades of packages are permitted only if requested via
15050                    // installFlags. This is because we aim to keep the behavior of debuggable
15051                    // platform builds as close as possible to the behavior of non-debuggable
15052                    // platform builds.
15053                    final boolean downgradeRequested =
15054                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15055                    final boolean packageDebuggable =
15056                                (dataOwnerPkg.applicationInfo.flags
15057                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15058                    final boolean downgradePermitted =
15059                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15060                    if (!downgradePermitted) {
15061                        try {
15062                            checkDowngrade(dataOwnerPkg, pkgLite);
15063                        } catch (PackageManagerException e) {
15064                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15065                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15066                        }
15067                    }
15068                }
15069
15070                if (installedPkg != null) {
15071                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15072                        // Check for updated system application.
15073                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15074                            if (onSd) {
15075                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15076                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15077                            }
15078                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15079                        } else {
15080                            if (onSd) {
15081                                // Install flag overrides everything.
15082                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15083                            }
15084                            // If current upgrade specifies particular preference
15085                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15086                                // Application explicitly specified internal.
15087                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15088                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15089                                // App explictly prefers external. Let policy decide
15090                            } else {
15091                                // Prefer previous location
15092                                if (isExternal(installedPkg)) {
15093                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15094                                }
15095                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15096                            }
15097                        }
15098                    } else {
15099                        // Invalid install. Return error code
15100                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15101                    }
15102                }
15103            }
15104            // All the special cases have been taken care of.
15105            // Return result based on recommended install location.
15106            if (onSd) {
15107                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15108            }
15109            return pkgLite.recommendedInstallLocation;
15110        }
15111
15112        /*
15113         * Invoke remote method to get package information and install
15114         * location values. Override install location based on default
15115         * policy if needed and then create install arguments based
15116         * on the install location.
15117         */
15118        public void handleStartCopy() throws RemoteException {
15119            int ret = PackageManager.INSTALL_SUCCEEDED;
15120
15121            // If we're already staged, we've firmly committed to an install location
15122            if (origin.staged) {
15123                if (origin.file != null) {
15124                    installFlags |= PackageManager.INSTALL_INTERNAL;
15125                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15126                } else if (origin.cid != null) {
15127                    installFlags |= PackageManager.INSTALL_EXTERNAL;
15128                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
15129                } else {
15130                    throw new IllegalStateException("Invalid stage location");
15131                }
15132            }
15133
15134            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15135            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15136            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15137            PackageInfoLite pkgLite = null;
15138
15139            if (onInt && onSd) {
15140                // Check if both bits are set.
15141                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15142                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15143            } else if (onSd && ephemeral) {
15144                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15145                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15146            } else {
15147                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15148                        packageAbiOverride);
15149
15150                if (DEBUG_EPHEMERAL && ephemeral) {
15151                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15152                }
15153
15154                /*
15155                 * If we have too little free space, try to free cache
15156                 * before giving up.
15157                 */
15158                if (!origin.staged && pkgLite.recommendedInstallLocation
15159                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15160                    // TODO: focus freeing disk space on the target device
15161                    final StorageManager storage = StorageManager.from(mContext);
15162                    final long lowThreshold = storage.getStorageLowBytes(
15163                            Environment.getDataDirectory());
15164
15165                    final long sizeBytes = mContainerService.calculateInstalledSize(
15166                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
15167
15168                    try {
15169                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
15170                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15171                                installFlags, packageAbiOverride);
15172                    } catch (InstallerException e) {
15173                        Slog.w(TAG, "Failed to free cache", e);
15174                    }
15175
15176                    /*
15177                     * The cache free must have deleted the file we
15178                     * downloaded to install.
15179                     *
15180                     * TODO: fix the "freeCache" call to not delete
15181                     *       the file we care about.
15182                     */
15183                    if (pkgLite.recommendedInstallLocation
15184                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15185                        pkgLite.recommendedInstallLocation
15186                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15187                    }
15188                }
15189            }
15190
15191            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15192                int loc = pkgLite.recommendedInstallLocation;
15193                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15194                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15195                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15196                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15197                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15198                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15199                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15200                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15201                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15202                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15203                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15204                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15205                } else {
15206                    // Override with defaults if needed.
15207                    loc = installLocationPolicy(pkgLite);
15208                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15209                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15210                    } else if (!onSd && !onInt) {
15211                        // Override install location with flags
15212                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15213                            // Set the flag to install on external media.
15214                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15215                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15216                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15217                            if (DEBUG_EPHEMERAL) {
15218                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15219                            }
15220                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15221                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15222                                    |PackageManager.INSTALL_INTERNAL);
15223                        } else {
15224                            // Make sure the flag for installing on external
15225                            // media is unset
15226                            installFlags |= PackageManager.INSTALL_INTERNAL;
15227                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15228                        }
15229                    }
15230                }
15231            }
15232
15233            final InstallArgs args = createInstallArgs(this);
15234            mArgs = args;
15235
15236            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15237                // TODO: http://b/22976637
15238                // Apps installed for "all" users use the device owner to verify the app
15239                UserHandle verifierUser = getUser();
15240                if (verifierUser == UserHandle.ALL) {
15241                    verifierUser = UserHandle.SYSTEM;
15242                }
15243
15244                /*
15245                 * Determine if we have any installed package verifiers. If we
15246                 * do, then we'll defer to them to verify the packages.
15247                 */
15248                final int requiredUid = mRequiredVerifierPackage == null ? -1
15249                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15250                                verifierUser.getIdentifier());
15251                if (!origin.existing && requiredUid != -1
15252                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
15253                    final Intent verification = new Intent(
15254                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15255                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15256                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15257                            PACKAGE_MIME_TYPE);
15258                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15259
15260                    // Query all live verifiers based on current user state
15261                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15262                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
15263
15264                    if (DEBUG_VERIFY) {
15265                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15266                                + verification.toString() + " with " + pkgLite.verifiers.length
15267                                + " optional verifiers");
15268                    }
15269
15270                    final int verificationId = mPendingVerificationToken++;
15271
15272                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15273
15274                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15275                            installerPackageName);
15276
15277                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15278                            installFlags);
15279
15280                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15281                            pkgLite.packageName);
15282
15283                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15284                            pkgLite.versionCode);
15285
15286                    if (verificationInfo != null) {
15287                        if (verificationInfo.originatingUri != null) {
15288                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15289                                    verificationInfo.originatingUri);
15290                        }
15291                        if (verificationInfo.referrer != null) {
15292                            verification.putExtra(Intent.EXTRA_REFERRER,
15293                                    verificationInfo.referrer);
15294                        }
15295                        if (verificationInfo.originatingUid >= 0) {
15296                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15297                                    verificationInfo.originatingUid);
15298                        }
15299                        if (verificationInfo.installerUid >= 0) {
15300                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15301                                    verificationInfo.installerUid);
15302                        }
15303                    }
15304
15305                    final PackageVerificationState verificationState = new PackageVerificationState(
15306                            requiredUid, args);
15307
15308                    mPendingVerification.append(verificationId, verificationState);
15309
15310                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15311                            receivers, verificationState);
15312
15313                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15314                    final long idleDuration = getVerificationTimeout();
15315
15316                    /*
15317                     * If any sufficient verifiers were listed in the package
15318                     * manifest, attempt to ask them.
15319                     */
15320                    if (sufficientVerifiers != null) {
15321                        final int N = sufficientVerifiers.size();
15322                        if (N == 0) {
15323                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15324                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15325                        } else {
15326                            for (int i = 0; i < N; i++) {
15327                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15328                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15329                                        verifierComponent.getPackageName(), idleDuration,
15330                                        verifierUser.getIdentifier(), false, "package verifier");
15331
15332                                final Intent sufficientIntent = new Intent(verification);
15333                                sufficientIntent.setComponent(verifierComponent);
15334                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15335                            }
15336                        }
15337                    }
15338
15339                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15340                            mRequiredVerifierPackage, receivers);
15341                    if (ret == PackageManager.INSTALL_SUCCEEDED
15342                            && mRequiredVerifierPackage != null) {
15343                        Trace.asyncTraceBegin(
15344                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15345                        /*
15346                         * Send the intent to the required verification agent,
15347                         * but only start the verification timeout after the
15348                         * target BroadcastReceivers have run.
15349                         */
15350                        verification.setComponent(requiredVerifierComponent);
15351                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15352                                mRequiredVerifierPackage, idleDuration,
15353                                verifierUser.getIdentifier(), false, "package verifier");
15354                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15355                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15356                                new BroadcastReceiver() {
15357                                    @Override
15358                                    public void onReceive(Context context, Intent intent) {
15359                                        final Message msg = mHandler
15360                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15361                                        msg.arg1 = verificationId;
15362                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15363                                    }
15364                                }, null, 0, null, null);
15365
15366                        /*
15367                         * We don't want the copy to proceed until verification
15368                         * succeeds, so null out this field.
15369                         */
15370                        mArgs = null;
15371                    }
15372                } else {
15373                    /*
15374                     * No package verification is enabled, so immediately start
15375                     * the remote call to initiate copy using temporary file.
15376                     */
15377                    ret = args.copyApk(mContainerService, true);
15378                }
15379            }
15380
15381            mRet = ret;
15382        }
15383
15384        @Override
15385        void handleReturnCode() {
15386            // If mArgs is null, then MCS couldn't be reached. When it
15387            // reconnects, it will try again to install. At that point, this
15388            // will succeed.
15389            if (mArgs != null) {
15390                processPendingInstall(mArgs, mRet);
15391            }
15392        }
15393
15394        @Override
15395        void handleServiceError() {
15396            mArgs = createInstallArgs(this);
15397            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15398        }
15399
15400        public boolean isForwardLocked() {
15401            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15402        }
15403    }
15404
15405    /**
15406     * Used during creation of InstallArgs
15407     *
15408     * @param installFlags package installation flags
15409     * @return true if should be installed on external storage
15410     */
15411    private static boolean installOnExternalAsec(int installFlags) {
15412        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
15413            return false;
15414        }
15415        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15416            return true;
15417        }
15418        return false;
15419    }
15420
15421    /**
15422     * Used during creation of InstallArgs
15423     *
15424     * @param installFlags package installation flags
15425     * @return true if should be installed as forward locked
15426     */
15427    private static boolean installForwardLocked(int installFlags) {
15428        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15429    }
15430
15431    private InstallArgs createInstallArgs(InstallParams params) {
15432        if (params.move != null) {
15433            return new MoveInstallArgs(params);
15434        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15435            return new AsecInstallArgs(params);
15436        } else {
15437            return new FileInstallArgs(params);
15438        }
15439    }
15440
15441    /**
15442     * Create args that describe an existing installed package. Typically used
15443     * when cleaning up old installs, or used as a move source.
15444     */
15445    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15446            String resourcePath, String[] instructionSets) {
15447        final boolean isInAsec;
15448        if (installOnExternalAsec(installFlags)) {
15449            /* Apps on SD card are always in ASEC containers. */
15450            isInAsec = true;
15451        } else if (installForwardLocked(installFlags)
15452                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15453            /*
15454             * Forward-locked apps are only in ASEC containers if they're the
15455             * new style
15456             */
15457            isInAsec = true;
15458        } else {
15459            isInAsec = false;
15460        }
15461
15462        if (isInAsec) {
15463            return new AsecInstallArgs(codePath, instructionSets,
15464                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15465        } else {
15466            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15467        }
15468    }
15469
15470    static abstract class InstallArgs {
15471        /** @see InstallParams#origin */
15472        final OriginInfo origin;
15473        /** @see InstallParams#move */
15474        final MoveInfo move;
15475
15476        final IPackageInstallObserver2 observer;
15477        // Always refers to PackageManager flags only
15478        final int installFlags;
15479        final String installerPackageName;
15480        final String volumeUuid;
15481        final UserHandle user;
15482        final String abiOverride;
15483        final String[] installGrantPermissions;
15484        /** If non-null, drop an async trace when the install completes */
15485        final String traceMethod;
15486        final int traceCookie;
15487        final Certificate[][] certificates;
15488        final int installReason;
15489
15490        // The list of instruction sets supported by this app. This is currently
15491        // only used during the rmdex() phase to clean up resources. We can get rid of this
15492        // if we move dex files under the common app path.
15493        /* nullable */ String[] instructionSets;
15494
15495        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15496                int installFlags, String installerPackageName, String volumeUuid,
15497                UserHandle user, String[] instructionSets,
15498                String abiOverride, String[] installGrantPermissions,
15499                String traceMethod, int traceCookie, Certificate[][] certificates,
15500                int installReason) {
15501            this.origin = origin;
15502            this.move = move;
15503            this.installFlags = installFlags;
15504            this.observer = observer;
15505            this.installerPackageName = installerPackageName;
15506            this.volumeUuid = volumeUuid;
15507            this.user = user;
15508            this.instructionSets = instructionSets;
15509            this.abiOverride = abiOverride;
15510            this.installGrantPermissions = installGrantPermissions;
15511            this.traceMethod = traceMethod;
15512            this.traceCookie = traceCookie;
15513            this.certificates = certificates;
15514            this.installReason = installReason;
15515        }
15516
15517        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15518        abstract int doPreInstall(int status);
15519
15520        /**
15521         * Rename package into final resting place. All paths on the given
15522         * scanned package should be updated to reflect the rename.
15523         */
15524        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15525        abstract int doPostInstall(int status, int uid);
15526
15527        /** @see PackageSettingBase#codePathString */
15528        abstract String getCodePath();
15529        /** @see PackageSettingBase#resourcePathString */
15530        abstract String getResourcePath();
15531
15532        // Need installer lock especially for dex file removal.
15533        abstract void cleanUpResourcesLI();
15534        abstract boolean doPostDeleteLI(boolean delete);
15535
15536        /**
15537         * Called before the source arguments are copied. This is used mostly
15538         * for MoveParams when it needs to read the source file to put it in the
15539         * destination.
15540         */
15541        int doPreCopy() {
15542            return PackageManager.INSTALL_SUCCEEDED;
15543        }
15544
15545        /**
15546         * Called after the source arguments are copied. This is used mostly for
15547         * MoveParams when it needs to read the source file to put it in the
15548         * destination.
15549         */
15550        int doPostCopy(int uid) {
15551            return PackageManager.INSTALL_SUCCEEDED;
15552        }
15553
15554        protected boolean isFwdLocked() {
15555            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15556        }
15557
15558        protected boolean isExternalAsec() {
15559            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15560        }
15561
15562        protected boolean isEphemeral() {
15563            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15564        }
15565
15566        UserHandle getUser() {
15567            return user;
15568        }
15569    }
15570
15571    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15572        if (!allCodePaths.isEmpty()) {
15573            if (instructionSets == null) {
15574                throw new IllegalStateException("instructionSet == null");
15575            }
15576            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15577            for (String codePath : allCodePaths) {
15578                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15579                    try {
15580                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15581                    } catch (InstallerException ignored) {
15582                    }
15583                }
15584            }
15585        }
15586    }
15587
15588    /**
15589     * Logic to handle installation of non-ASEC applications, including copying
15590     * and renaming logic.
15591     */
15592    class FileInstallArgs extends InstallArgs {
15593        private File codeFile;
15594        private File resourceFile;
15595
15596        // Example topology:
15597        // /data/app/com.example/base.apk
15598        // /data/app/com.example/split_foo.apk
15599        // /data/app/com.example/lib/arm/libfoo.so
15600        // /data/app/com.example/lib/arm64/libfoo.so
15601        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15602
15603        /** New install */
15604        FileInstallArgs(InstallParams params) {
15605            super(params.origin, params.move, params.observer, params.installFlags,
15606                    params.installerPackageName, params.volumeUuid,
15607                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15608                    params.grantedRuntimePermissions,
15609                    params.traceMethod, params.traceCookie, params.certificates,
15610                    params.installReason);
15611            if (isFwdLocked()) {
15612                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15613            }
15614        }
15615
15616        /** Existing install */
15617        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15618            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15619                    null, null, null, 0, null /*certificates*/,
15620                    PackageManager.INSTALL_REASON_UNKNOWN);
15621            this.codeFile = (codePath != null) ? new File(codePath) : null;
15622            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15623        }
15624
15625        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15626            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15627            try {
15628                return doCopyApk(imcs, temp);
15629            } finally {
15630                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15631            }
15632        }
15633
15634        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15635            if (origin.staged) {
15636                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15637                codeFile = origin.file;
15638                resourceFile = origin.file;
15639                return PackageManager.INSTALL_SUCCEEDED;
15640            }
15641
15642            try {
15643                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15644                final File tempDir =
15645                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15646                codeFile = tempDir;
15647                resourceFile = tempDir;
15648            } catch (IOException e) {
15649                Slog.w(TAG, "Failed to create copy file: " + e);
15650                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15651            }
15652
15653            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15654                @Override
15655                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15656                    if (!FileUtils.isValidExtFilename(name)) {
15657                        throw new IllegalArgumentException("Invalid filename: " + name);
15658                    }
15659                    try {
15660                        final File file = new File(codeFile, name);
15661                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15662                                O_RDWR | O_CREAT, 0644);
15663                        Os.chmod(file.getAbsolutePath(), 0644);
15664                        return new ParcelFileDescriptor(fd);
15665                    } catch (ErrnoException e) {
15666                        throw new RemoteException("Failed to open: " + e.getMessage());
15667                    }
15668                }
15669            };
15670
15671            int ret = PackageManager.INSTALL_SUCCEEDED;
15672            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15673            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15674                Slog.e(TAG, "Failed to copy package");
15675                return ret;
15676            }
15677
15678            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15679            NativeLibraryHelper.Handle handle = null;
15680            try {
15681                handle = NativeLibraryHelper.Handle.create(codeFile);
15682                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15683                        abiOverride);
15684            } catch (IOException e) {
15685                Slog.e(TAG, "Copying native libraries failed", e);
15686                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15687            } finally {
15688                IoUtils.closeQuietly(handle);
15689            }
15690
15691            return ret;
15692        }
15693
15694        int doPreInstall(int status) {
15695            if (status != PackageManager.INSTALL_SUCCEEDED) {
15696                cleanUp();
15697            }
15698            return status;
15699        }
15700
15701        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15702            if (status != PackageManager.INSTALL_SUCCEEDED) {
15703                cleanUp();
15704                return false;
15705            }
15706
15707            final File targetDir = codeFile.getParentFile();
15708            final File beforeCodeFile = codeFile;
15709            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15710
15711            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15712            try {
15713                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15714            } catch (ErrnoException e) {
15715                Slog.w(TAG, "Failed to rename", e);
15716                return false;
15717            }
15718
15719            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15720                Slog.w(TAG, "Failed to restorecon");
15721                return false;
15722            }
15723
15724            // Reflect the rename internally
15725            codeFile = afterCodeFile;
15726            resourceFile = afterCodeFile;
15727
15728            // Reflect the rename in scanned details
15729            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15730            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15731                    afterCodeFile, pkg.baseCodePath));
15732            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15733                    afterCodeFile, pkg.splitCodePaths));
15734
15735            // Reflect the rename in app info
15736            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15737            pkg.setApplicationInfoCodePath(pkg.codePath);
15738            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15739            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15740            pkg.setApplicationInfoResourcePath(pkg.codePath);
15741            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15742            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15743
15744            return true;
15745        }
15746
15747        int doPostInstall(int status, int uid) {
15748            if (status != PackageManager.INSTALL_SUCCEEDED) {
15749                cleanUp();
15750            }
15751            return status;
15752        }
15753
15754        @Override
15755        String getCodePath() {
15756            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15757        }
15758
15759        @Override
15760        String getResourcePath() {
15761            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15762        }
15763
15764        private boolean cleanUp() {
15765            if (codeFile == null || !codeFile.exists()) {
15766                return false;
15767            }
15768
15769            removeCodePathLI(codeFile);
15770
15771            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15772                resourceFile.delete();
15773            }
15774
15775            return true;
15776        }
15777
15778        void cleanUpResourcesLI() {
15779            // Try enumerating all code paths before deleting
15780            List<String> allCodePaths = Collections.EMPTY_LIST;
15781            if (codeFile != null && codeFile.exists()) {
15782                try {
15783                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15784                    allCodePaths = pkg.getAllCodePaths();
15785                } catch (PackageParserException e) {
15786                    // Ignored; we tried our best
15787                }
15788            }
15789
15790            cleanUp();
15791            removeDexFiles(allCodePaths, instructionSets);
15792        }
15793
15794        boolean doPostDeleteLI(boolean delete) {
15795            // XXX err, shouldn't we respect the delete flag?
15796            cleanUpResourcesLI();
15797            return true;
15798        }
15799    }
15800
15801    private boolean isAsecExternal(String cid) {
15802        final String asecPath = PackageHelper.getSdFilesystem(cid);
15803        return !asecPath.startsWith(mAsecInternalPath);
15804    }
15805
15806    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15807            PackageManagerException {
15808        if (copyRet < 0) {
15809            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15810                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15811                throw new PackageManagerException(copyRet, message);
15812            }
15813        }
15814    }
15815
15816    /**
15817     * Extract the StorageManagerService "container ID" from the full code path of an
15818     * .apk.
15819     */
15820    static String cidFromCodePath(String fullCodePath) {
15821        int eidx = fullCodePath.lastIndexOf("/");
15822        String subStr1 = fullCodePath.substring(0, eidx);
15823        int sidx = subStr1.lastIndexOf("/");
15824        return subStr1.substring(sidx+1, eidx);
15825    }
15826
15827    /**
15828     * Logic to handle installation of ASEC applications, including copying and
15829     * renaming logic.
15830     */
15831    class AsecInstallArgs extends InstallArgs {
15832        static final String RES_FILE_NAME = "pkg.apk";
15833        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15834
15835        String cid;
15836        String packagePath;
15837        String resourcePath;
15838
15839        /** New install */
15840        AsecInstallArgs(InstallParams params) {
15841            super(params.origin, params.move, params.observer, params.installFlags,
15842                    params.installerPackageName, params.volumeUuid,
15843                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15844                    params.grantedRuntimePermissions,
15845                    params.traceMethod, params.traceCookie, params.certificates,
15846                    params.installReason);
15847        }
15848
15849        /** Existing install */
15850        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15851                        boolean isExternal, boolean isForwardLocked) {
15852            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15853                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15854                    instructionSets, null, null, null, 0, null /*certificates*/,
15855                    PackageManager.INSTALL_REASON_UNKNOWN);
15856            // Hackily pretend we're still looking at a full code path
15857            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15858                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15859            }
15860
15861            // Extract cid from fullCodePath
15862            int eidx = fullCodePath.lastIndexOf("/");
15863            String subStr1 = fullCodePath.substring(0, eidx);
15864            int sidx = subStr1.lastIndexOf("/");
15865            cid = subStr1.substring(sidx+1, eidx);
15866            setMountPath(subStr1);
15867        }
15868
15869        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15870            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15871                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15872                    instructionSets, null, null, null, 0, null /*certificates*/,
15873                    PackageManager.INSTALL_REASON_UNKNOWN);
15874            this.cid = cid;
15875            setMountPath(PackageHelper.getSdDir(cid));
15876        }
15877
15878        void createCopyFile() {
15879            cid = mInstallerService.allocateExternalStageCidLegacy();
15880        }
15881
15882        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15883            if (origin.staged && origin.cid != null) {
15884                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15885                cid = origin.cid;
15886                setMountPath(PackageHelper.getSdDir(cid));
15887                return PackageManager.INSTALL_SUCCEEDED;
15888            }
15889
15890            if (temp) {
15891                createCopyFile();
15892            } else {
15893                /*
15894                 * Pre-emptively destroy the container since it's destroyed if
15895                 * copying fails due to it existing anyway.
15896                 */
15897                PackageHelper.destroySdDir(cid);
15898            }
15899
15900            final String newMountPath = imcs.copyPackageToContainer(
15901                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15902                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15903
15904            if (newMountPath != null) {
15905                setMountPath(newMountPath);
15906                return PackageManager.INSTALL_SUCCEEDED;
15907            } else {
15908                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15909            }
15910        }
15911
15912        @Override
15913        String getCodePath() {
15914            return packagePath;
15915        }
15916
15917        @Override
15918        String getResourcePath() {
15919            return resourcePath;
15920        }
15921
15922        int doPreInstall(int status) {
15923            if (status != PackageManager.INSTALL_SUCCEEDED) {
15924                // Destroy container
15925                PackageHelper.destroySdDir(cid);
15926            } else {
15927                boolean mounted = PackageHelper.isContainerMounted(cid);
15928                if (!mounted) {
15929                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15930                            Process.SYSTEM_UID);
15931                    if (newMountPath != null) {
15932                        setMountPath(newMountPath);
15933                    } else {
15934                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15935                    }
15936                }
15937            }
15938            return status;
15939        }
15940
15941        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15942            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15943            String newMountPath = null;
15944            if (PackageHelper.isContainerMounted(cid)) {
15945                // Unmount the container
15946                if (!PackageHelper.unMountSdDir(cid)) {
15947                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15948                    return false;
15949                }
15950            }
15951            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15952                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15953                        " which might be stale. Will try to clean up.");
15954                // Clean up the stale container and proceed to recreate.
15955                if (!PackageHelper.destroySdDir(newCacheId)) {
15956                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15957                    return false;
15958                }
15959                // Successfully cleaned up stale container. Try to rename again.
15960                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15961                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15962                            + " inspite of cleaning it up.");
15963                    return false;
15964                }
15965            }
15966            if (!PackageHelper.isContainerMounted(newCacheId)) {
15967                Slog.w(TAG, "Mounting container " + newCacheId);
15968                newMountPath = PackageHelper.mountSdDir(newCacheId,
15969                        getEncryptKey(), Process.SYSTEM_UID);
15970            } else {
15971                newMountPath = PackageHelper.getSdDir(newCacheId);
15972            }
15973            if (newMountPath == null) {
15974                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15975                return false;
15976            }
15977            Log.i(TAG, "Succesfully renamed " + cid +
15978                    " to " + newCacheId +
15979                    " at new path: " + newMountPath);
15980            cid = newCacheId;
15981
15982            final File beforeCodeFile = new File(packagePath);
15983            setMountPath(newMountPath);
15984            final File afterCodeFile = new File(packagePath);
15985
15986            // Reflect the rename in scanned details
15987            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15988            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15989                    afterCodeFile, pkg.baseCodePath));
15990            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15991                    afterCodeFile, pkg.splitCodePaths));
15992
15993            // Reflect the rename in app info
15994            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15995            pkg.setApplicationInfoCodePath(pkg.codePath);
15996            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15997            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15998            pkg.setApplicationInfoResourcePath(pkg.codePath);
15999            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16000            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16001
16002            return true;
16003        }
16004
16005        private void setMountPath(String mountPath) {
16006            final File mountFile = new File(mountPath);
16007
16008            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16009            if (monolithicFile.exists()) {
16010                packagePath = monolithicFile.getAbsolutePath();
16011                if (isFwdLocked()) {
16012                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16013                } else {
16014                    resourcePath = packagePath;
16015                }
16016            } else {
16017                packagePath = mountFile.getAbsolutePath();
16018                resourcePath = packagePath;
16019            }
16020        }
16021
16022        int doPostInstall(int status, int uid) {
16023            if (status != PackageManager.INSTALL_SUCCEEDED) {
16024                cleanUp();
16025            } else {
16026                final int groupOwner;
16027                final String protectedFile;
16028                if (isFwdLocked()) {
16029                    groupOwner = UserHandle.getSharedAppGid(uid);
16030                    protectedFile = RES_FILE_NAME;
16031                } else {
16032                    groupOwner = -1;
16033                    protectedFile = null;
16034                }
16035
16036                if (uid < Process.FIRST_APPLICATION_UID
16037                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16038                    Slog.e(TAG, "Failed to finalize " + cid);
16039                    PackageHelper.destroySdDir(cid);
16040                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16041                }
16042
16043                boolean mounted = PackageHelper.isContainerMounted(cid);
16044                if (!mounted) {
16045                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16046                }
16047            }
16048            return status;
16049        }
16050
16051        private void cleanUp() {
16052            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16053
16054            // Destroy secure container
16055            PackageHelper.destroySdDir(cid);
16056        }
16057
16058        private List<String> getAllCodePaths() {
16059            final File codeFile = new File(getCodePath());
16060            if (codeFile != null && codeFile.exists()) {
16061                try {
16062                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16063                    return pkg.getAllCodePaths();
16064                } catch (PackageParserException e) {
16065                    // Ignored; we tried our best
16066                }
16067            }
16068            return Collections.EMPTY_LIST;
16069        }
16070
16071        void cleanUpResourcesLI() {
16072            // Enumerate all code paths before deleting
16073            cleanUpResourcesLI(getAllCodePaths());
16074        }
16075
16076        private void cleanUpResourcesLI(List<String> allCodePaths) {
16077            cleanUp();
16078            removeDexFiles(allCodePaths, instructionSets);
16079        }
16080
16081        String getPackageName() {
16082            return getAsecPackageName(cid);
16083        }
16084
16085        boolean doPostDeleteLI(boolean delete) {
16086            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
16087            final List<String> allCodePaths = getAllCodePaths();
16088            boolean mounted = PackageHelper.isContainerMounted(cid);
16089            if (mounted) {
16090                // Unmount first
16091                if (PackageHelper.unMountSdDir(cid)) {
16092                    mounted = false;
16093                }
16094            }
16095            if (!mounted && delete) {
16096                cleanUpResourcesLI(allCodePaths);
16097            }
16098            return !mounted;
16099        }
16100
16101        @Override
16102        int doPreCopy() {
16103            if (isFwdLocked()) {
16104                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
16105                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
16106                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16107                }
16108            }
16109
16110            return PackageManager.INSTALL_SUCCEEDED;
16111        }
16112
16113        @Override
16114        int doPostCopy(int uid) {
16115            if (isFwdLocked()) {
16116                if (uid < Process.FIRST_APPLICATION_UID
16117                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
16118                                RES_FILE_NAME)) {
16119                    Slog.e(TAG, "Failed to finalize " + cid);
16120                    PackageHelper.destroySdDir(cid);
16121                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16122                }
16123            }
16124
16125            return PackageManager.INSTALL_SUCCEEDED;
16126        }
16127    }
16128
16129    /**
16130     * Logic to handle movement of existing installed applications.
16131     */
16132    class MoveInstallArgs extends InstallArgs {
16133        private File codeFile;
16134        private File resourceFile;
16135
16136        /** New install */
16137        MoveInstallArgs(InstallParams params) {
16138            super(params.origin, params.move, params.observer, params.installFlags,
16139                    params.installerPackageName, params.volumeUuid,
16140                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16141                    params.grantedRuntimePermissions,
16142                    params.traceMethod, params.traceCookie, params.certificates,
16143                    params.installReason);
16144        }
16145
16146        int copyApk(IMediaContainerService imcs, boolean temp) {
16147            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16148                    + move.fromUuid + " to " + move.toUuid);
16149            synchronized (mInstaller) {
16150                try {
16151                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16152                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16153                } catch (InstallerException e) {
16154                    Slog.w(TAG, "Failed to move app", e);
16155                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16156                }
16157            }
16158
16159            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16160            resourceFile = codeFile;
16161            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16162
16163            return PackageManager.INSTALL_SUCCEEDED;
16164        }
16165
16166        int doPreInstall(int status) {
16167            if (status != PackageManager.INSTALL_SUCCEEDED) {
16168                cleanUp(move.toUuid);
16169            }
16170            return status;
16171        }
16172
16173        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16174            if (status != PackageManager.INSTALL_SUCCEEDED) {
16175                cleanUp(move.toUuid);
16176                return false;
16177            }
16178
16179            // Reflect the move in app info
16180            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16181            pkg.setApplicationInfoCodePath(pkg.codePath);
16182            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16183            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16184            pkg.setApplicationInfoResourcePath(pkg.codePath);
16185            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16186            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16187
16188            return true;
16189        }
16190
16191        int doPostInstall(int status, int uid) {
16192            if (status == PackageManager.INSTALL_SUCCEEDED) {
16193                cleanUp(move.fromUuid);
16194            } else {
16195                cleanUp(move.toUuid);
16196            }
16197            return status;
16198        }
16199
16200        @Override
16201        String getCodePath() {
16202            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16203        }
16204
16205        @Override
16206        String getResourcePath() {
16207            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16208        }
16209
16210        private boolean cleanUp(String volumeUuid) {
16211            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16212                    move.dataAppName);
16213            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16214            final int[] userIds = sUserManager.getUserIds();
16215            synchronized (mInstallLock) {
16216                // Clean up both app data and code
16217                // All package moves are frozen until finished
16218                for (int userId : userIds) {
16219                    try {
16220                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16221                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16222                    } catch (InstallerException e) {
16223                        Slog.w(TAG, String.valueOf(e));
16224                    }
16225                }
16226                removeCodePathLI(codeFile);
16227            }
16228            return true;
16229        }
16230
16231        void cleanUpResourcesLI() {
16232            throw new UnsupportedOperationException();
16233        }
16234
16235        boolean doPostDeleteLI(boolean delete) {
16236            throw new UnsupportedOperationException();
16237        }
16238    }
16239
16240    static String getAsecPackageName(String packageCid) {
16241        int idx = packageCid.lastIndexOf("-");
16242        if (idx == -1) {
16243            return packageCid;
16244        }
16245        return packageCid.substring(0, idx);
16246    }
16247
16248    // Utility method used to create code paths based on package name and available index.
16249    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16250        String idxStr = "";
16251        int idx = 1;
16252        // Fall back to default value of idx=1 if prefix is not
16253        // part of oldCodePath
16254        if (oldCodePath != null) {
16255            String subStr = oldCodePath;
16256            // Drop the suffix right away
16257            if (suffix != null && subStr.endsWith(suffix)) {
16258                subStr = subStr.substring(0, subStr.length() - suffix.length());
16259            }
16260            // If oldCodePath already contains prefix find out the
16261            // ending index to either increment or decrement.
16262            int sidx = subStr.lastIndexOf(prefix);
16263            if (sidx != -1) {
16264                subStr = subStr.substring(sidx + prefix.length());
16265                if (subStr != null) {
16266                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16267                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16268                    }
16269                    try {
16270                        idx = Integer.parseInt(subStr);
16271                        if (idx <= 1) {
16272                            idx++;
16273                        } else {
16274                            idx--;
16275                        }
16276                    } catch(NumberFormatException e) {
16277                    }
16278                }
16279            }
16280        }
16281        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16282        return prefix + idxStr;
16283    }
16284
16285    private File getNextCodePath(File targetDir, String packageName) {
16286        File result;
16287        SecureRandom random = new SecureRandom();
16288        byte[] bytes = new byte[16];
16289        do {
16290            random.nextBytes(bytes);
16291            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16292            result = new File(targetDir, packageName + "-" + suffix);
16293        } while (result.exists());
16294        return result;
16295    }
16296
16297    // Utility method that returns the relative package path with respect
16298    // to the installation directory. Like say for /data/data/com.test-1.apk
16299    // string com.test-1 is returned.
16300    static String deriveCodePathName(String codePath) {
16301        if (codePath == null) {
16302            return null;
16303        }
16304        final File codeFile = new File(codePath);
16305        final String name = codeFile.getName();
16306        if (codeFile.isDirectory()) {
16307            return name;
16308        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16309            final int lastDot = name.lastIndexOf('.');
16310            return name.substring(0, lastDot);
16311        } else {
16312            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16313            return null;
16314        }
16315    }
16316
16317    static class PackageInstalledInfo {
16318        String name;
16319        int uid;
16320        // The set of users that originally had this package installed.
16321        int[] origUsers;
16322        // The set of users that now have this package installed.
16323        int[] newUsers;
16324        PackageParser.Package pkg;
16325        int returnCode;
16326        String returnMsg;
16327        PackageRemovedInfo removedInfo;
16328        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16329
16330        public void setError(int code, String msg) {
16331            setReturnCode(code);
16332            setReturnMessage(msg);
16333            Slog.w(TAG, msg);
16334        }
16335
16336        public void setError(String msg, PackageParserException e) {
16337            setReturnCode(e.error);
16338            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16339            Slog.w(TAG, msg, e);
16340        }
16341
16342        public void setError(String msg, PackageManagerException e) {
16343            returnCode = e.error;
16344            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16345            Slog.w(TAG, msg, e);
16346        }
16347
16348        public void setReturnCode(int returnCode) {
16349            this.returnCode = returnCode;
16350            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16351            for (int i = 0; i < childCount; i++) {
16352                addedChildPackages.valueAt(i).returnCode = returnCode;
16353            }
16354        }
16355
16356        private void setReturnMessage(String returnMsg) {
16357            this.returnMsg = returnMsg;
16358            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16359            for (int i = 0; i < childCount; i++) {
16360                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16361            }
16362        }
16363
16364        // In some error cases we want to convey more info back to the observer
16365        String origPackage;
16366        String origPermission;
16367    }
16368
16369    /*
16370     * Install a non-existing package.
16371     */
16372    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16373            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16374            PackageInstalledInfo res, int installReason) {
16375        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16376
16377        // Remember this for later, in case we need to rollback this install
16378        String pkgName = pkg.packageName;
16379
16380        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16381
16382        synchronized(mPackages) {
16383            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16384            if (renamedPackage != null) {
16385                // A package with the same name is already installed, though
16386                // it has been renamed to an older name.  The package we
16387                // are trying to install should be installed as an update to
16388                // the existing one, but that has not been requested, so bail.
16389                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16390                        + " without first uninstalling package running as "
16391                        + renamedPackage);
16392                return;
16393            }
16394            if (mPackages.containsKey(pkgName)) {
16395                // Don't allow installation over an existing package with the same name.
16396                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16397                        + " without first uninstalling.");
16398                return;
16399            }
16400        }
16401
16402        try {
16403            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
16404                    System.currentTimeMillis(), user);
16405
16406            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16407
16408            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16409                prepareAppDataAfterInstallLIF(newPackage);
16410
16411            } else {
16412                // Remove package from internal structures, but keep around any
16413                // data that might have already existed
16414                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16415                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16416            }
16417        } catch (PackageManagerException e) {
16418            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16419        }
16420
16421        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16422    }
16423
16424    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16425        // Can't rotate keys during boot or if sharedUser.
16426        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16427                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16428            return false;
16429        }
16430        // app is using upgradeKeySets; make sure all are valid
16431        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16432        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16433        for (int i = 0; i < upgradeKeySets.length; i++) {
16434            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16435                Slog.wtf(TAG, "Package "
16436                         + (oldPs.name != null ? oldPs.name : "<null>")
16437                         + " contains upgrade-key-set reference to unknown key-set: "
16438                         + upgradeKeySets[i]
16439                         + " reverting to signatures check.");
16440                return false;
16441            }
16442        }
16443        return true;
16444    }
16445
16446    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16447        // Upgrade keysets are being used.  Determine if new package has a superset of the
16448        // required keys.
16449        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16450        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16451        for (int i = 0; i < upgradeKeySets.length; i++) {
16452            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16453            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16454                return true;
16455            }
16456        }
16457        return false;
16458    }
16459
16460    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16461        try (DigestInputStream digestStream =
16462                new DigestInputStream(new FileInputStream(file), digest)) {
16463            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16464        }
16465    }
16466
16467    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16468            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16469            int installReason) {
16470        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16471
16472        final PackageParser.Package oldPackage;
16473        final PackageSetting ps;
16474        final String pkgName = pkg.packageName;
16475        final int[] allUsers;
16476        final int[] installedUsers;
16477
16478        synchronized(mPackages) {
16479            oldPackage = mPackages.get(pkgName);
16480            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16481
16482            // don't allow upgrade to target a release SDK from a pre-release SDK
16483            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16484                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16485            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16486                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16487            if (oldTargetsPreRelease
16488                    && !newTargetsPreRelease
16489                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16490                Slog.w(TAG, "Can't install package targeting released sdk");
16491                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16492                return;
16493            }
16494
16495            ps = mSettings.mPackages.get(pkgName);
16496
16497            // verify signatures are valid
16498            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16499                if (!checkUpgradeKeySetLP(ps, pkg)) {
16500                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16501                            "New package not signed by keys specified by upgrade-keysets: "
16502                                    + pkgName);
16503                    return;
16504                }
16505            } else {
16506                // default to original signature matching
16507                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16508                        != PackageManager.SIGNATURE_MATCH) {
16509                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16510                            "New package has a different signature: " + pkgName);
16511                    return;
16512                }
16513            }
16514
16515            // don't allow a system upgrade unless the upgrade hash matches
16516            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16517                byte[] digestBytes = null;
16518                try {
16519                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16520                    updateDigest(digest, new File(pkg.baseCodePath));
16521                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16522                        for (String path : pkg.splitCodePaths) {
16523                            updateDigest(digest, new File(path));
16524                        }
16525                    }
16526                    digestBytes = digest.digest();
16527                } catch (NoSuchAlgorithmException | IOException e) {
16528                    res.setError(INSTALL_FAILED_INVALID_APK,
16529                            "Could not compute hash: " + pkgName);
16530                    return;
16531                }
16532                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16533                    res.setError(INSTALL_FAILED_INVALID_APK,
16534                            "New package fails restrict-update check: " + pkgName);
16535                    return;
16536                }
16537                // retain upgrade restriction
16538                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16539            }
16540
16541            // Check for shared user id changes
16542            String invalidPackageName =
16543                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16544            if (invalidPackageName != null) {
16545                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16546                        "Package " + invalidPackageName + " tried to change user "
16547                                + oldPackage.mSharedUserId);
16548                return;
16549            }
16550
16551            // In case of rollback, remember per-user/profile install state
16552            allUsers = sUserManager.getUserIds();
16553            installedUsers = ps.queryInstalledUsers(allUsers, true);
16554
16555            // don't allow an upgrade from full to ephemeral
16556            if (isInstantApp) {
16557                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16558                    for (int currentUser : allUsers) {
16559                        if (!ps.getInstantApp(currentUser)) {
16560                            // can't downgrade from full to instant
16561                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16562                                    + " for user: " + currentUser);
16563                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16564                            return;
16565                        }
16566                    }
16567                } else if (!ps.getInstantApp(user.getIdentifier())) {
16568                    // can't downgrade from full to instant
16569                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16570                            + " for user: " + user.getIdentifier());
16571                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16572                    return;
16573                }
16574            }
16575        }
16576
16577        // Update what is removed
16578        res.removedInfo = new PackageRemovedInfo(this);
16579        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16580        res.removedInfo.removedPackage = oldPackage.packageName;
16581        res.removedInfo.installerPackageName = ps.installerPackageName;
16582        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16583        res.removedInfo.isUpdate = true;
16584        res.removedInfo.origUsers = installedUsers;
16585        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16586        for (int i = 0; i < installedUsers.length; i++) {
16587            final int userId = installedUsers[i];
16588            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16589        }
16590
16591        final int childCount = (oldPackage.childPackages != null)
16592                ? oldPackage.childPackages.size() : 0;
16593        for (int i = 0; i < childCount; i++) {
16594            boolean childPackageUpdated = false;
16595            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16596            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16597            if (res.addedChildPackages != null) {
16598                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16599                if (childRes != null) {
16600                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16601                    childRes.removedInfo.removedPackage = childPkg.packageName;
16602                    if (childPs != null) {
16603                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16604                    }
16605                    childRes.removedInfo.isUpdate = true;
16606                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16607                    childPackageUpdated = true;
16608                }
16609            }
16610            if (!childPackageUpdated) {
16611                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16612                childRemovedRes.removedPackage = childPkg.packageName;
16613                if (childPs != null) {
16614                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16615                }
16616                childRemovedRes.isUpdate = false;
16617                childRemovedRes.dataRemoved = true;
16618                synchronized (mPackages) {
16619                    if (childPs != null) {
16620                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16621                    }
16622                }
16623                if (res.removedInfo.removedChildPackages == null) {
16624                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16625                }
16626                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16627            }
16628        }
16629
16630        boolean sysPkg = (isSystemApp(oldPackage));
16631        if (sysPkg) {
16632            // Set the system/privileged flags as needed
16633            final boolean privileged =
16634                    (oldPackage.applicationInfo.privateFlags
16635                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16636            final int systemPolicyFlags = policyFlags
16637                    | PackageParser.PARSE_IS_SYSTEM
16638                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16639
16640            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16641                    user, allUsers, installerPackageName, res, installReason);
16642        } else {
16643            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16644                    user, allUsers, installerPackageName, res, installReason);
16645        }
16646    }
16647
16648    public List<String> getPreviousCodePaths(String packageName) {
16649        final PackageSetting ps = mSettings.mPackages.get(packageName);
16650        final List<String> result = new ArrayList<String>();
16651        if (ps != null && ps.oldCodePaths != null) {
16652            result.addAll(ps.oldCodePaths);
16653        }
16654        return result;
16655    }
16656
16657    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16658            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16659            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16660            int installReason) {
16661        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16662                + deletedPackage);
16663
16664        String pkgName = deletedPackage.packageName;
16665        boolean deletedPkg = true;
16666        boolean addedPkg = false;
16667        boolean updatedSettings = false;
16668        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16669        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16670                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16671
16672        final long origUpdateTime = (pkg.mExtras != null)
16673                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16674
16675        // First delete the existing package while retaining the data directory
16676        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16677                res.removedInfo, true, pkg)) {
16678            // If the existing package wasn't successfully deleted
16679            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16680            deletedPkg = false;
16681        } else {
16682            // Successfully deleted the old package; proceed with replace.
16683
16684            // If deleted package lived in a container, give users a chance to
16685            // relinquish resources before killing.
16686            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16687                if (DEBUG_INSTALL) {
16688                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16689                }
16690                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16691                final ArrayList<String> pkgList = new ArrayList<String>(1);
16692                pkgList.add(deletedPackage.applicationInfo.packageName);
16693                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16694            }
16695
16696            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16697                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16698            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16699
16700            try {
16701                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16702                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16703                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16704                        installReason);
16705
16706                // Update the in-memory copy of the previous code paths.
16707                PackageSetting ps = mSettings.mPackages.get(pkgName);
16708                if (!killApp) {
16709                    if (ps.oldCodePaths == null) {
16710                        ps.oldCodePaths = new ArraySet<>();
16711                    }
16712                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16713                    if (deletedPackage.splitCodePaths != null) {
16714                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16715                    }
16716                } else {
16717                    ps.oldCodePaths = null;
16718                }
16719                if (ps.childPackageNames != null) {
16720                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16721                        final String childPkgName = ps.childPackageNames.get(i);
16722                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16723                        childPs.oldCodePaths = ps.oldCodePaths;
16724                    }
16725                }
16726                // set instant app status, but, only if it's explicitly specified
16727                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16728                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16729                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16730                prepareAppDataAfterInstallLIF(newPackage);
16731                addedPkg = true;
16732                mDexManager.notifyPackageUpdated(newPackage.packageName,
16733                        newPackage.baseCodePath, newPackage.splitCodePaths);
16734            } catch (PackageManagerException e) {
16735                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16736            }
16737        }
16738
16739        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16740            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16741
16742            // Revert all internal state mutations and added folders for the failed install
16743            if (addedPkg) {
16744                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16745                        res.removedInfo, true, null);
16746            }
16747
16748            // Restore the old package
16749            if (deletedPkg) {
16750                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16751                File restoreFile = new File(deletedPackage.codePath);
16752                // Parse old package
16753                boolean oldExternal = isExternal(deletedPackage);
16754                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16755                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16756                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16757                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16758                try {
16759                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16760                            null);
16761                } catch (PackageManagerException e) {
16762                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16763                            + e.getMessage());
16764                    return;
16765                }
16766
16767                synchronized (mPackages) {
16768                    // Ensure the installer package name up to date
16769                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16770
16771                    // Update permissions for restored package
16772                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16773
16774                    mSettings.writeLPr();
16775                }
16776
16777                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16778            }
16779        } else {
16780            synchronized (mPackages) {
16781                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16782                if (ps != null) {
16783                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16784                    if (res.removedInfo.removedChildPackages != null) {
16785                        final int childCount = res.removedInfo.removedChildPackages.size();
16786                        // Iterate in reverse as we may modify the collection
16787                        for (int i = childCount - 1; i >= 0; i--) {
16788                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16789                            if (res.addedChildPackages.containsKey(childPackageName)) {
16790                                res.removedInfo.removedChildPackages.removeAt(i);
16791                            } else {
16792                                PackageRemovedInfo childInfo = res.removedInfo
16793                                        .removedChildPackages.valueAt(i);
16794                                childInfo.removedForAllUsers = mPackages.get(
16795                                        childInfo.removedPackage) == null;
16796                            }
16797                        }
16798                    }
16799                }
16800            }
16801        }
16802    }
16803
16804    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16805            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16806            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16807            int installReason) {
16808        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16809                + ", old=" + deletedPackage);
16810
16811        final boolean disabledSystem;
16812
16813        // Remove existing system package
16814        removePackageLI(deletedPackage, true);
16815
16816        synchronized (mPackages) {
16817            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16818        }
16819        if (!disabledSystem) {
16820            // We didn't need to disable the .apk as a current system package,
16821            // which means we are replacing another update that is already
16822            // installed.  We need to make sure to delete the older one's .apk.
16823            res.removedInfo.args = createInstallArgsForExisting(0,
16824                    deletedPackage.applicationInfo.getCodePath(),
16825                    deletedPackage.applicationInfo.getResourcePath(),
16826                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16827        } else {
16828            res.removedInfo.args = null;
16829        }
16830
16831        // Successfully disabled the old package. Now proceed with re-installation
16832        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16833                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16834        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16835
16836        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16837        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16838                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16839
16840        PackageParser.Package newPackage = null;
16841        try {
16842            // Add the package to the internal data structures
16843            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16844
16845            // Set the update and install times
16846            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16847            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16848                    System.currentTimeMillis());
16849
16850            // Update the package dynamic state if succeeded
16851            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16852                // Now that the install succeeded make sure we remove data
16853                // directories for any child package the update removed.
16854                final int deletedChildCount = (deletedPackage.childPackages != null)
16855                        ? deletedPackage.childPackages.size() : 0;
16856                final int newChildCount = (newPackage.childPackages != null)
16857                        ? newPackage.childPackages.size() : 0;
16858                for (int i = 0; i < deletedChildCount; i++) {
16859                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16860                    boolean childPackageDeleted = true;
16861                    for (int j = 0; j < newChildCount; j++) {
16862                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16863                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16864                            childPackageDeleted = false;
16865                            break;
16866                        }
16867                    }
16868                    if (childPackageDeleted) {
16869                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16870                                deletedChildPkg.packageName);
16871                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16872                            PackageRemovedInfo removedChildRes = res.removedInfo
16873                                    .removedChildPackages.get(deletedChildPkg.packageName);
16874                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16875                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16876                        }
16877                    }
16878                }
16879
16880                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16881                        installReason);
16882                prepareAppDataAfterInstallLIF(newPackage);
16883
16884                mDexManager.notifyPackageUpdated(newPackage.packageName,
16885                            newPackage.baseCodePath, newPackage.splitCodePaths);
16886            }
16887        } catch (PackageManagerException e) {
16888            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16889            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16890        }
16891
16892        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16893            // Re installation failed. Restore old information
16894            // Remove new pkg information
16895            if (newPackage != null) {
16896                removeInstalledPackageLI(newPackage, true);
16897            }
16898            // Add back the old system package
16899            try {
16900                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16901            } catch (PackageManagerException e) {
16902                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16903            }
16904
16905            synchronized (mPackages) {
16906                if (disabledSystem) {
16907                    enableSystemPackageLPw(deletedPackage);
16908                }
16909
16910                // Ensure the installer package name up to date
16911                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16912
16913                // Update permissions for restored package
16914                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16915
16916                mSettings.writeLPr();
16917            }
16918
16919            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16920                    + " after failed upgrade");
16921        }
16922    }
16923
16924    /**
16925     * Checks whether the parent or any of the child packages have a change shared
16926     * user. For a package to be a valid update the shred users of the parent and
16927     * the children should match. We may later support changing child shared users.
16928     * @param oldPkg The updated package.
16929     * @param newPkg The update package.
16930     * @return The shared user that change between the versions.
16931     */
16932    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16933            PackageParser.Package newPkg) {
16934        // Check parent shared user
16935        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16936            return newPkg.packageName;
16937        }
16938        // Check child shared users
16939        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16940        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16941        for (int i = 0; i < newChildCount; i++) {
16942            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16943            // If this child was present, did it have the same shared user?
16944            for (int j = 0; j < oldChildCount; j++) {
16945                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16946                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16947                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16948                    return newChildPkg.packageName;
16949                }
16950            }
16951        }
16952        return null;
16953    }
16954
16955    private void removeNativeBinariesLI(PackageSetting ps) {
16956        // Remove the lib path for the parent package
16957        if (ps != null) {
16958            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16959            // Remove the lib path for the child packages
16960            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16961            for (int i = 0; i < childCount; i++) {
16962                PackageSetting childPs = null;
16963                synchronized (mPackages) {
16964                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16965                }
16966                if (childPs != null) {
16967                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16968                            .legacyNativeLibraryPathString);
16969                }
16970            }
16971        }
16972    }
16973
16974    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16975        // Enable the parent package
16976        mSettings.enableSystemPackageLPw(pkg.packageName);
16977        // Enable the child packages
16978        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16979        for (int i = 0; i < childCount; i++) {
16980            PackageParser.Package childPkg = pkg.childPackages.get(i);
16981            mSettings.enableSystemPackageLPw(childPkg.packageName);
16982        }
16983    }
16984
16985    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16986            PackageParser.Package newPkg) {
16987        // Disable the parent package (parent always replaced)
16988        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16989        // Disable the child packages
16990        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16991        for (int i = 0; i < childCount; i++) {
16992            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16993            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16994            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16995        }
16996        return disabled;
16997    }
16998
16999    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17000            String installerPackageName) {
17001        // Enable the parent package
17002        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17003        // Enable the child packages
17004        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17005        for (int i = 0; i < childCount; i++) {
17006            PackageParser.Package childPkg = pkg.childPackages.get(i);
17007            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17008        }
17009    }
17010
17011    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17012        // Collect all used permissions in the UID
17013        ArraySet<String> usedPermissions = new ArraySet<>();
17014        final int packageCount = su.packages.size();
17015        for (int i = 0; i < packageCount; i++) {
17016            PackageSetting ps = su.packages.valueAt(i);
17017            if (ps.pkg == null) {
17018                continue;
17019            }
17020            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17021            for (int j = 0; j < requestedPermCount; j++) {
17022                String permission = ps.pkg.requestedPermissions.get(j);
17023                BasePermission bp = mSettings.mPermissions.get(permission);
17024                if (bp != null) {
17025                    usedPermissions.add(permission);
17026                }
17027            }
17028        }
17029
17030        PermissionsState permissionsState = su.getPermissionsState();
17031        // Prune install permissions
17032        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17033        final int installPermCount = installPermStates.size();
17034        for (int i = installPermCount - 1; i >= 0;  i--) {
17035            PermissionState permissionState = installPermStates.get(i);
17036            if (!usedPermissions.contains(permissionState.getName())) {
17037                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17038                if (bp != null) {
17039                    permissionsState.revokeInstallPermission(bp);
17040                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17041                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17042                }
17043            }
17044        }
17045
17046        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17047
17048        // Prune runtime permissions
17049        for (int userId : allUserIds) {
17050            List<PermissionState> runtimePermStates = permissionsState
17051                    .getRuntimePermissionStates(userId);
17052            final int runtimePermCount = runtimePermStates.size();
17053            for (int i = runtimePermCount - 1; i >= 0; i--) {
17054                PermissionState permissionState = runtimePermStates.get(i);
17055                if (!usedPermissions.contains(permissionState.getName())) {
17056                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17057                    if (bp != null) {
17058                        permissionsState.revokeRuntimePermission(bp, userId);
17059                        permissionsState.updatePermissionFlags(bp, userId,
17060                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17061                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17062                                runtimePermissionChangedUserIds, userId);
17063                    }
17064                }
17065            }
17066        }
17067
17068        return runtimePermissionChangedUserIds;
17069    }
17070
17071    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17072            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17073        // Update the parent package setting
17074        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17075                res, user, installReason);
17076        // Update the child packages setting
17077        final int childCount = (newPackage.childPackages != null)
17078                ? newPackage.childPackages.size() : 0;
17079        for (int i = 0; i < childCount; i++) {
17080            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17081            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17082            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17083                    childRes.origUsers, childRes, user, installReason);
17084        }
17085    }
17086
17087    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17088            String installerPackageName, int[] allUsers, int[] installedForUsers,
17089            PackageInstalledInfo res, UserHandle user, int installReason) {
17090        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17091
17092        String pkgName = newPackage.packageName;
17093        synchronized (mPackages) {
17094            //write settings. the installStatus will be incomplete at this stage.
17095            //note that the new package setting would have already been
17096            //added to mPackages. It hasn't been persisted yet.
17097            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17098            // TODO: Remove this write? It's also written at the end of this method
17099            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17100            mSettings.writeLPr();
17101            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17102        }
17103
17104        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17105        synchronized (mPackages) {
17106            updatePermissionsLPw(newPackage.packageName, newPackage,
17107                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17108                            ? UPDATE_PERMISSIONS_ALL : 0));
17109            // For system-bundled packages, we assume that installing an upgraded version
17110            // of the package implies that the user actually wants to run that new code,
17111            // so we enable the package.
17112            PackageSetting ps = mSettings.mPackages.get(pkgName);
17113            final int userId = user.getIdentifier();
17114            if (ps != null) {
17115                if (isSystemApp(newPackage)) {
17116                    if (DEBUG_INSTALL) {
17117                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17118                    }
17119                    // Enable system package for requested users
17120                    if (res.origUsers != null) {
17121                        for (int origUserId : res.origUsers) {
17122                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17123                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17124                                        origUserId, installerPackageName);
17125                            }
17126                        }
17127                    }
17128                    // Also convey the prior install/uninstall state
17129                    if (allUsers != null && installedForUsers != null) {
17130                        for (int currentUserId : allUsers) {
17131                            final boolean installed = ArrayUtils.contains(
17132                                    installedForUsers, currentUserId);
17133                            if (DEBUG_INSTALL) {
17134                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17135                            }
17136                            ps.setInstalled(installed, currentUserId);
17137                        }
17138                        // these install state changes will be persisted in the
17139                        // upcoming call to mSettings.writeLPr().
17140                    }
17141                }
17142                // It's implied that when a user requests installation, they want the app to be
17143                // installed and enabled.
17144                if (userId != UserHandle.USER_ALL) {
17145                    ps.setInstalled(true, userId);
17146                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17147                }
17148
17149                // When replacing an existing package, preserve the original install reason for all
17150                // users that had the package installed before.
17151                final Set<Integer> previousUserIds = new ArraySet<>();
17152                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17153                    final int installReasonCount = res.removedInfo.installReasons.size();
17154                    for (int i = 0; i < installReasonCount; i++) {
17155                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17156                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17157                        ps.setInstallReason(previousInstallReason, previousUserId);
17158                        previousUserIds.add(previousUserId);
17159                    }
17160                }
17161
17162                // Set install reason for users that are having the package newly installed.
17163                if (userId == UserHandle.USER_ALL) {
17164                    for (int currentUserId : sUserManager.getUserIds()) {
17165                        if (!previousUserIds.contains(currentUserId)) {
17166                            ps.setInstallReason(installReason, currentUserId);
17167                        }
17168                    }
17169                } else if (!previousUserIds.contains(userId)) {
17170                    ps.setInstallReason(installReason, userId);
17171                }
17172                mSettings.writeKernelMappingLPr(ps);
17173            }
17174            res.name = pkgName;
17175            res.uid = newPackage.applicationInfo.uid;
17176            res.pkg = newPackage;
17177            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17178            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17179            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17180            //to update install status
17181            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17182            mSettings.writeLPr();
17183            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17184        }
17185
17186        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17187    }
17188
17189    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17190        try {
17191            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17192            installPackageLI(args, res);
17193        } finally {
17194            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17195        }
17196    }
17197
17198    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17199        final int installFlags = args.installFlags;
17200        final String installerPackageName = args.installerPackageName;
17201        final String volumeUuid = args.volumeUuid;
17202        final File tmpPackageFile = new File(args.getCodePath());
17203        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17204        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17205                || (args.volumeUuid != null));
17206        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17207        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17208        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17209        boolean replace = false;
17210        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17211        if (args.move != null) {
17212            // moving a complete application; perform an initial scan on the new install location
17213            scanFlags |= SCAN_INITIAL;
17214        }
17215        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17216            scanFlags |= SCAN_DONT_KILL_APP;
17217        }
17218        if (instantApp) {
17219            scanFlags |= SCAN_AS_INSTANT_APP;
17220        }
17221        if (fullApp) {
17222            scanFlags |= SCAN_AS_FULL_APP;
17223        }
17224
17225        // Result object to be returned
17226        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17227
17228        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17229
17230        // Sanity check
17231        if (instantApp && (forwardLocked || onExternal)) {
17232            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17233                    + " external=" + onExternal);
17234            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17235            return;
17236        }
17237
17238        // Retrieve PackageSettings and parse package
17239        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17240                | PackageParser.PARSE_ENFORCE_CODE
17241                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17242                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17243                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17244                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17245        PackageParser pp = new PackageParser();
17246        pp.setSeparateProcesses(mSeparateProcesses);
17247        pp.setDisplayMetrics(mMetrics);
17248        pp.setCallback(mPackageParserCallback);
17249
17250        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17251        final PackageParser.Package pkg;
17252        try {
17253            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17254        } catch (PackageParserException e) {
17255            res.setError("Failed parse during installPackageLI", e);
17256            return;
17257        } finally {
17258            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17259        }
17260
17261        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17262        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17263            Slog.w(TAG, "Instant app package " + pkg.packageName
17264                    + " does not target O, this will be a fatal error.");
17265            // STOPSHIP: Make this a fatal error
17266            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
17267        }
17268        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17269            Slog.w(TAG, "Instant app package " + pkg.packageName
17270                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
17271            // STOPSHIP: Make this a fatal error
17272            pkg.applicationInfo.targetSandboxVersion = 2;
17273        }
17274
17275        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17276            // Static shared libraries have synthetic package names
17277            renameStaticSharedLibraryPackage(pkg);
17278
17279            // No static shared libs on external storage
17280            if (onExternal) {
17281                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17282                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17283                        "Packages declaring static-shared libs cannot be updated");
17284                return;
17285            }
17286        }
17287
17288        // If we are installing a clustered package add results for the children
17289        if (pkg.childPackages != null) {
17290            synchronized (mPackages) {
17291                final int childCount = pkg.childPackages.size();
17292                for (int i = 0; i < childCount; i++) {
17293                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17294                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17295                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17296                    childRes.pkg = childPkg;
17297                    childRes.name = childPkg.packageName;
17298                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17299                    if (childPs != null) {
17300                        childRes.origUsers = childPs.queryInstalledUsers(
17301                                sUserManager.getUserIds(), true);
17302                    }
17303                    if ((mPackages.containsKey(childPkg.packageName))) {
17304                        childRes.removedInfo = new PackageRemovedInfo(this);
17305                        childRes.removedInfo.removedPackage = childPkg.packageName;
17306                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17307                    }
17308                    if (res.addedChildPackages == null) {
17309                        res.addedChildPackages = new ArrayMap<>();
17310                    }
17311                    res.addedChildPackages.put(childPkg.packageName, childRes);
17312                }
17313            }
17314        }
17315
17316        // If package doesn't declare API override, mark that we have an install
17317        // time CPU ABI override.
17318        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17319            pkg.cpuAbiOverride = args.abiOverride;
17320        }
17321
17322        String pkgName = res.name = pkg.packageName;
17323        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17324            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17325                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17326                return;
17327            }
17328        }
17329
17330        try {
17331            // either use what we've been given or parse directly from the APK
17332            if (args.certificates != null) {
17333                try {
17334                    PackageParser.populateCertificates(pkg, args.certificates);
17335                } catch (PackageParserException e) {
17336                    // there was something wrong with the certificates we were given;
17337                    // try to pull them from the APK
17338                    PackageParser.collectCertificates(pkg, parseFlags);
17339                }
17340            } else {
17341                PackageParser.collectCertificates(pkg, parseFlags);
17342            }
17343        } catch (PackageParserException e) {
17344            res.setError("Failed collect during installPackageLI", e);
17345            return;
17346        }
17347
17348        // Get rid of all references to package scan path via parser.
17349        pp = null;
17350        String oldCodePath = null;
17351        boolean systemApp = false;
17352        synchronized (mPackages) {
17353            // Check if installing already existing package
17354            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17355                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17356                if (pkg.mOriginalPackages != null
17357                        && pkg.mOriginalPackages.contains(oldName)
17358                        && mPackages.containsKey(oldName)) {
17359                    // This package is derived from an original package,
17360                    // and this device has been updating from that original
17361                    // name.  We must continue using the original name, so
17362                    // rename the new package here.
17363                    pkg.setPackageName(oldName);
17364                    pkgName = pkg.packageName;
17365                    replace = true;
17366                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17367                            + oldName + " pkgName=" + pkgName);
17368                } else if (mPackages.containsKey(pkgName)) {
17369                    // This package, under its official name, already exists
17370                    // on the device; we should replace it.
17371                    replace = true;
17372                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17373                }
17374
17375                // Child packages are installed through the parent package
17376                if (pkg.parentPackage != null) {
17377                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17378                            "Package " + pkg.packageName + " is child of package "
17379                                    + pkg.parentPackage.parentPackage + ". Child packages "
17380                                    + "can be updated only through the parent package.");
17381                    return;
17382                }
17383
17384                if (replace) {
17385                    // Prevent apps opting out from runtime permissions
17386                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17387                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17388                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17389                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17390                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17391                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17392                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17393                                        + " doesn't support runtime permissions but the old"
17394                                        + " target SDK " + oldTargetSdk + " does.");
17395                        return;
17396                    }
17397                    // Prevent apps from downgrading their targetSandbox.
17398                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
17399                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
17400                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
17401                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17402                                "Package " + pkg.packageName + " new target sandbox "
17403                                + newTargetSandbox + " is incompatible with the previous value of"
17404                                + oldTargetSandbox + ".");
17405                        return;
17406                    }
17407
17408                    // Prevent installing of child packages
17409                    if (oldPackage.parentPackage != null) {
17410                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17411                                "Package " + pkg.packageName + " is child of package "
17412                                        + oldPackage.parentPackage + ". Child packages "
17413                                        + "can be updated only through the parent package.");
17414                        return;
17415                    }
17416                }
17417            }
17418
17419            PackageSetting ps = mSettings.mPackages.get(pkgName);
17420            if (ps != null) {
17421                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17422
17423                // Static shared libs have same package with different versions where
17424                // we internally use a synthetic package name to allow multiple versions
17425                // of the same package, therefore we need to compare signatures against
17426                // the package setting for the latest library version.
17427                PackageSetting signatureCheckPs = ps;
17428                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17429                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17430                    if (libraryEntry != null) {
17431                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17432                    }
17433                }
17434
17435                // Quick sanity check that we're signed correctly if updating;
17436                // we'll check this again later when scanning, but we want to
17437                // bail early here before tripping over redefined permissions.
17438                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17439                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17440                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17441                                + pkg.packageName + " upgrade keys do not match the "
17442                                + "previously installed version");
17443                        return;
17444                    }
17445                } else {
17446                    try {
17447                        verifySignaturesLP(signatureCheckPs, pkg);
17448                    } catch (PackageManagerException e) {
17449                        res.setError(e.error, e.getMessage());
17450                        return;
17451                    }
17452                }
17453
17454                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17455                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17456                    systemApp = (ps.pkg.applicationInfo.flags &
17457                            ApplicationInfo.FLAG_SYSTEM) != 0;
17458                }
17459                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17460            }
17461
17462            int N = pkg.permissions.size();
17463            for (int i = N-1; i >= 0; i--) {
17464                PackageParser.Permission perm = pkg.permissions.get(i);
17465                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17466
17467                // Don't allow anyone but the system to define ephemeral permissions.
17468                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17469                        && !systemApp) {
17470                    Slog.w(TAG, "Non-System package " + pkg.packageName
17471                            + " attempting to delcare ephemeral permission "
17472                            + perm.info.name + "; Removing ephemeral.");
17473                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17474                }
17475                // Check whether the newly-scanned package wants to define an already-defined perm
17476                if (bp != null) {
17477                    // If the defining package is signed with our cert, it's okay.  This
17478                    // also includes the "updating the same package" case, of course.
17479                    // "updating same package" could also involve key-rotation.
17480                    final boolean sigsOk;
17481                    if (bp.sourcePackage.equals(pkg.packageName)
17482                            && (bp.packageSetting instanceof PackageSetting)
17483                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17484                                    scanFlags))) {
17485                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17486                    } else {
17487                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17488                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17489                    }
17490                    if (!sigsOk) {
17491                        // If the owning package is the system itself, we log but allow
17492                        // install to proceed; we fail the install on all other permission
17493                        // redefinitions.
17494                        if (!bp.sourcePackage.equals("android")) {
17495                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17496                                    + pkg.packageName + " attempting to redeclare permission "
17497                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17498                            res.origPermission = perm.info.name;
17499                            res.origPackage = bp.sourcePackage;
17500                            return;
17501                        } else {
17502                            Slog.w(TAG, "Package " + pkg.packageName
17503                                    + " attempting to redeclare system permission "
17504                                    + perm.info.name + "; ignoring new declaration");
17505                            pkg.permissions.remove(i);
17506                        }
17507                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17508                        // Prevent apps to change protection level to dangerous from any other
17509                        // type as this would allow a privilege escalation where an app adds a
17510                        // normal/signature permission in other app's group and later redefines
17511                        // it as dangerous leading to the group auto-grant.
17512                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17513                                == PermissionInfo.PROTECTION_DANGEROUS) {
17514                            if (bp != null && !bp.isRuntime()) {
17515                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17516                                        + "non-runtime permission " + perm.info.name
17517                                        + " to runtime; keeping old protection level");
17518                                perm.info.protectionLevel = bp.protectionLevel;
17519                            }
17520                        }
17521                    }
17522                }
17523            }
17524        }
17525
17526        if (systemApp) {
17527            if (onExternal) {
17528                // Abort update; system app can't be replaced with app on sdcard
17529                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17530                        "Cannot install updates to system apps on sdcard");
17531                return;
17532            } else if (instantApp) {
17533                // Abort update; system app can't be replaced with an instant app
17534                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17535                        "Cannot update a system app with an instant app");
17536                return;
17537            }
17538        }
17539
17540        if (args.move != null) {
17541            // We did an in-place move, so dex is ready to roll
17542            scanFlags |= SCAN_NO_DEX;
17543            scanFlags |= SCAN_MOVE;
17544
17545            synchronized (mPackages) {
17546                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17547                if (ps == null) {
17548                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17549                            "Missing settings for moved package " + pkgName);
17550                }
17551
17552                // We moved the entire application as-is, so bring over the
17553                // previously derived ABI information.
17554                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17555                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17556            }
17557
17558        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17559            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17560            scanFlags |= SCAN_NO_DEX;
17561
17562            try {
17563                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17564                    args.abiOverride : pkg.cpuAbiOverride);
17565                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17566                        true /*extractLibs*/, mAppLib32InstallDir);
17567            } catch (PackageManagerException pme) {
17568                Slog.e(TAG, "Error deriving application ABI", pme);
17569                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17570                return;
17571            }
17572
17573            // Shared libraries for the package need to be updated.
17574            synchronized (mPackages) {
17575                try {
17576                    updateSharedLibrariesLPr(pkg, null);
17577                } catch (PackageManagerException e) {
17578                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17579                }
17580            }
17581
17582            // dexopt can take some time to complete, so, for instant apps, we skip this
17583            // step during installation. Instead, we'll take extra time the first time the
17584            // instant app starts. It's preferred to do it this way to provide continuous
17585            // progress to the user instead of mysteriously blocking somewhere in the
17586            // middle of running an instant app.
17587            if (!instantApp) {
17588                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17589                // Do not run PackageDexOptimizer through the local performDexOpt
17590                // method because `pkg` may not be in `mPackages` yet.
17591                //
17592                // Also, don't fail application installs if the dexopt step fails.
17593                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17594                        null /* instructionSets */, false /* checkProfiles */,
17595                        getCompilerFilterForReason(REASON_INSTALL),
17596                        getOrCreateCompilerPackageStats(pkg),
17597                        mDexManager.isUsedByOtherApps(pkg.packageName));
17598                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17599            }
17600
17601            // Notify BackgroundDexOptService that the package has been changed.
17602            // If this is an update of a package which used to fail to compile,
17603            // BDOS will remove it from its blacklist.
17604            // TODO: Layering violation
17605            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17606        }
17607
17608        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17609            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17610            return;
17611        }
17612
17613        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17614
17615        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17616                "installPackageLI")) {
17617            if (replace) {
17618                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17619                    // Static libs have a synthetic package name containing the version
17620                    // and cannot be updated as an update would get a new package name,
17621                    // unless this is the exact same version code which is useful for
17622                    // development.
17623                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17624                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17625                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17626                                + "static-shared libs cannot be updated");
17627                        return;
17628                    }
17629                }
17630                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17631                        installerPackageName, res, args.installReason);
17632            } else {
17633                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17634                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17635            }
17636        }
17637
17638        synchronized (mPackages) {
17639            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17640            if (ps != null) {
17641                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17642                ps.setUpdateAvailable(false /*updateAvailable*/);
17643            }
17644
17645            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17646            for (int i = 0; i < childCount; i++) {
17647                PackageParser.Package childPkg = pkg.childPackages.get(i);
17648                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17649                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17650                if (childPs != null) {
17651                    childRes.newUsers = childPs.queryInstalledUsers(
17652                            sUserManager.getUserIds(), true);
17653                }
17654            }
17655
17656            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17657                updateSequenceNumberLP(pkgName, res.newUsers);
17658                updateInstantAppInstallerLocked(pkgName);
17659            }
17660        }
17661    }
17662
17663    private void startIntentFilterVerifications(int userId, boolean replacing,
17664            PackageParser.Package pkg) {
17665        if (mIntentFilterVerifierComponent == null) {
17666            Slog.w(TAG, "No IntentFilter verification will not be done as "
17667                    + "there is no IntentFilterVerifier available!");
17668            return;
17669        }
17670
17671        final int verifierUid = getPackageUid(
17672                mIntentFilterVerifierComponent.getPackageName(),
17673                MATCH_DEBUG_TRIAGED_MISSING,
17674                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17675
17676        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17677        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17678        mHandler.sendMessage(msg);
17679
17680        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17681        for (int i = 0; i < childCount; i++) {
17682            PackageParser.Package childPkg = pkg.childPackages.get(i);
17683            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17684            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17685            mHandler.sendMessage(msg);
17686        }
17687    }
17688
17689    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17690            PackageParser.Package pkg) {
17691        int size = pkg.activities.size();
17692        if (size == 0) {
17693            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17694                    "No activity, so no need to verify any IntentFilter!");
17695            return;
17696        }
17697
17698        final boolean hasDomainURLs = hasDomainURLs(pkg);
17699        if (!hasDomainURLs) {
17700            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17701                    "No domain URLs, so no need to verify any IntentFilter!");
17702            return;
17703        }
17704
17705        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17706                + " if any IntentFilter from the " + size
17707                + " Activities needs verification ...");
17708
17709        int count = 0;
17710        final String packageName = pkg.packageName;
17711
17712        synchronized (mPackages) {
17713            // If this is a new install and we see that we've already run verification for this
17714            // package, we have nothing to do: it means the state was restored from backup.
17715            if (!replacing) {
17716                IntentFilterVerificationInfo ivi =
17717                        mSettings.getIntentFilterVerificationLPr(packageName);
17718                if (ivi != null) {
17719                    if (DEBUG_DOMAIN_VERIFICATION) {
17720                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17721                                + ivi.getStatusString());
17722                    }
17723                    return;
17724                }
17725            }
17726
17727            // If any filters need to be verified, then all need to be.
17728            boolean needToVerify = false;
17729            for (PackageParser.Activity a : pkg.activities) {
17730                for (ActivityIntentInfo filter : a.intents) {
17731                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17732                        if (DEBUG_DOMAIN_VERIFICATION) {
17733                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17734                        }
17735                        needToVerify = true;
17736                        break;
17737                    }
17738                }
17739            }
17740
17741            if (needToVerify) {
17742                final int verificationId = mIntentFilterVerificationToken++;
17743                for (PackageParser.Activity a : pkg.activities) {
17744                    for (ActivityIntentInfo filter : a.intents) {
17745                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17746                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17747                                    "Verification needed for IntentFilter:" + filter.toString());
17748                            mIntentFilterVerifier.addOneIntentFilterVerification(
17749                                    verifierUid, userId, verificationId, filter, packageName);
17750                            count++;
17751                        }
17752                    }
17753                }
17754            }
17755        }
17756
17757        if (count > 0) {
17758            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17759                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17760                    +  " for userId:" + userId);
17761            mIntentFilterVerifier.startVerifications(userId);
17762        } else {
17763            if (DEBUG_DOMAIN_VERIFICATION) {
17764                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17765            }
17766        }
17767    }
17768
17769    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17770        final ComponentName cn  = filter.activity.getComponentName();
17771        final String packageName = cn.getPackageName();
17772
17773        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17774                packageName);
17775        if (ivi == null) {
17776            return true;
17777        }
17778        int status = ivi.getStatus();
17779        switch (status) {
17780            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17781            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17782                return true;
17783
17784            default:
17785                // Nothing to do
17786                return false;
17787        }
17788    }
17789
17790    private static boolean isMultiArch(ApplicationInfo info) {
17791        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17792    }
17793
17794    private static boolean isExternal(PackageParser.Package pkg) {
17795        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17796    }
17797
17798    private static boolean isExternal(PackageSetting ps) {
17799        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17800    }
17801
17802    private static boolean isSystemApp(PackageParser.Package pkg) {
17803        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17804    }
17805
17806    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17807        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17808    }
17809
17810    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17811        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17812    }
17813
17814    private static boolean isSystemApp(PackageSetting ps) {
17815        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17816    }
17817
17818    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17819        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17820    }
17821
17822    private int packageFlagsToInstallFlags(PackageSetting ps) {
17823        int installFlags = 0;
17824        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17825            // This existing package was an external ASEC install when we have
17826            // the external flag without a UUID
17827            installFlags |= PackageManager.INSTALL_EXTERNAL;
17828        }
17829        if (ps.isForwardLocked()) {
17830            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17831        }
17832        return installFlags;
17833    }
17834
17835    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17836        if (isExternal(pkg)) {
17837            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17838                return StorageManager.UUID_PRIMARY_PHYSICAL;
17839            } else {
17840                return pkg.volumeUuid;
17841            }
17842        } else {
17843            return StorageManager.UUID_PRIVATE_INTERNAL;
17844        }
17845    }
17846
17847    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17848        if (isExternal(pkg)) {
17849            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17850                return mSettings.getExternalVersion();
17851            } else {
17852                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17853            }
17854        } else {
17855            return mSettings.getInternalVersion();
17856        }
17857    }
17858
17859    private void deleteTempPackageFiles() {
17860        final FilenameFilter filter = new FilenameFilter() {
17861            public boolean accept(File dir, String name) {
17862                return name.startsWith("vmdl") && name.endsWith(".tmp");
17863            }
17864        };
17865        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17866            file.delete();
17867        }
17868    }
17869
17870    @Override
17871    public void deletePackageAsUser(String packageName, int versionCode,
17872            IPackageDeleteObserver observer, int userId, int flags) {
17873        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17874                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17875    }
17876
17877    @Override
17878    public void deletePackageVersioned(VersionedPackage versionedPackage,
17879            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17880        mContext.enforceCallingOrSelfPermission(
17881                android.Manifest.permission.DELETE_PACKAGES, null);
17882        Preconditions.checkNotNull(versionedPackage);
17883        Preconditions.checkNotNull(observer);
17884        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17885                PackageManager.VERSION_CODE_HIGHEST,
17886                Integer.MAX_VALUE, "versionCode must be >= -1");
17887
17888        final String packageName = versionedPackage.getPackageName();
17889        final int versionCode = versionedPackage.getVersionCode();
17890        final String internalPackageName;
17891        synchronized (mPackages) {
17892            // Normalize package name to handle renamed packages and static libs
17893            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17894                    versionedPackage.getVersionCode());
17895        }
17896
17897        final int uid = Binder.getCallingUid();
17898        if (!isOrphaned(internalPackageName)
17899                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17900            try {
17901                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17902                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17903                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17904                observer.onUserActionRequired(intent);
17905            } catch (RemoteException re) {
17906            }
17907            return;
17908        }
17909        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17910        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17911        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17912            mContext.enforceCallingOrSelfPermission(
17913                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17914                    "deletePackage for user " + userId);
17915        }
17916
17917        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17918            try {
17919                observer.onPackageDeleted(packageName,
17920                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17921            } catch (RemoteException re) {
17922            }
17923            return;
17924        }
17925
17926        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17927            try {
17928                observer.onPackageDeleted(packageName,
17929                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17930            } catch (RemoteException re) {
17931            }
17932            return;
17933        }
17934
17935        if (DEBUG_REMOVE) {
17936            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17937                    + " deleteAllUsers: " + deleteAllUsers + " version="
17938                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17939                    ? "VERSION_CODE_HIGHEST" : versionCode));
17940        }
17941        // Queue up an async operation since the package deletion may take a little while.
17942        mHandler.post(new Runnable() {
17943            public void run() {
17944                mHandler.removeCallbacks(this);
17945                int returnCode;
17946                if (!deleteAllUsers) {
17947                    returnCode = deletePackageX(internalPackageName, versionCode,
17948                            userId, deleteFlags);
17949                } else {
17950                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
17951                            internalPackageName, users);
17952                    // If nobody is blocking uninstall, proceed with delete for all users
17953                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17954                        returnCode = deletePackageX(internalPackageName, versionCode,
17955                                userId, deleteFlags);
17956                    } else {
17957                        // Otherwise uninstall individually for users with blockUninstalls=false
17958                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17959                        for (int userId : users) {
17960                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17961                                returnCode = deletePackageX(internalPackageName, versionCode,
17962                                        userId, userFlags);
17963                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17964                                    Slog.w(TAG, "Package delete failed for user " + userId
17965                                            + ", returnCode " + returnCode);
17966                                }
17967                            }
17968                        }
17969                        // The app has only been marked uninstalled for certain users.
17970                        // We still need to report that delete was blocked
17971                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17972                    }
17973                }
17974                try {
17975                    observer.onPackageDeleted(packageName, returnCode, null);
17976                } catch (RemoteException e) {
17977                    Log.i(TAG, "Observer no longer exists.");
17978                } //end catch
17979            } //end run
17980        });
17981    }
17982
17983    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17984        if (pkg.staticSharedLibName != null) {
17985            return pkg.manifestPackageName;
17986        }
17987        return pkg.packageName;
17988    }
17989
17990    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17991        // Handle renamed packages
17992        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17993        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17994
17995        // Is this a static library?
17996        SparseArray<SharedLibraryEntry> versionedLib =
17997                mStaticLibsByDeclaringPackage.get(packageName);
17998        if (versionedLib == null || versionedLib.size() <= 0) {
17999            return packageName;
18000        }
18001
18002        // Figure out which lib versions the caller can see
18003        SparseIntArray versionsCallerCanSee = null;
18004        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18005        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18006                && callingAppId != Process.ROOT_UID) {
18007            versionsCallerCanSee = new SparseIntArray();
18008            String libName = versionedLib.valueAt(0).info.getName();
18009            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18010            if (uidPackages != null) {
18011                for (String uidPackage : uidPackages) {
18012                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18013                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18014                    if (libIdx >= 0) {
18015                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18016                        versionsCallerCanSee.append(libVersion, libVersion);
18017                    }
18018                }
18019            }
18020        }
18021
18022        // Caller can see nothing - done
18023        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18024            return packageName;
18025        }
18026
18027        // Find the version the caller can see and the app version code
18028        SharedLibraryEntry highestVersion = null;
18029        final int versionCount = versionedLib.size();
18030        for (int i = 0; i < versionCount; i++) {
18031            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18032            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18033                    libEntry.info.getVersion()) < 0) {
18034                continue;
18035            }
18036            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18037            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18038                if (libVersionCode == versionCode) {
18039                    return libEntry.apk;
18040                }
18041            } else if (highestVersion == null) {
18042                highestVersion = libEntry;
18043            } else if (libVersionCode  > highestVersion.info
18044                    .getDeclaringPackage().getVersionCode()) {
18045                highestVersion = libEntry;
18046            }
18047        }
18048
18049        if (highestVersion != null) {
18050            return highestVersion.apk;
18051        }
18052
18053        return packageName;
18054    }
18055
18056    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18057        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18058              || callingUid == Process.SYSTEM_UID) {
18059            return true;
18060        }
18061        final int callingUserId = UserHandle.getUserId(callingUid);
18062        // If the caller installed the pkgName, then allow it to silently uninstall.
18063        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18064            return true;
18065        }
18066
18067        // Allow package verifier to silently uninstall.
18068        if (mRequiredVerifierPackage != null &&
18069                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18070            return true;
18071        }
18072
18073        // Allow package uninstaller to silently uninstall.
18074        if (mRequiredUninstallerPackage != null &&
18075                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18076            return true;
18077        }
18078
18079        // Allow storage manager to silently uninstall.
18080        if (mStorageManagerPackage != null &&
18081                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18082            return true;
18083        }
18084        return false;
18085    }
18086
18087    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18088        int[] result = EMPTY_INT_ARRAY;
18089        for (int userId : userIds) {
18090            if (getBlockUninstallForUser(packageName, userId)) {
18091                result = ArrayUtils.appendInt(result, userId);
18092            }
18093        }
18094        return result;
18095    }
18096
18097    @Override
18098    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18099        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18100    }
18101
18102    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18103        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18104                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18105        try {
18106            if (dpm != null) {
18107                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18108                        /* callingUserOnly =*/ false);
18109                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18110                        : deviceOwnerComponentName.getPackageName();
18111                // Does the package contains the device owner?
18112                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18113                // this check is probably not needed, since DO should be registered as a device
18114                // admin on some user too. (Original bug for this: b/17657954)
18115                if (packageName.equals(deviceOwnerPackageName)) {
18116                    return true;
18117                }
18118                // Does it contain a device admin for any user?
18119                int[] users;
18120                if (userId == UserHandle.USER_ALL) {
18121                    users = sUserManager.getUserIds();
18122                } else {
18123                    users = new int[]{userId};
18124                }
18125                for (int i = 0; i < users.length; ++i) {
18126                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18127                        return true;
18128                    }
18129                }
18130            }
18131        } catch (RemoteException e) {
18132        }
18133        return false;
18134    }
18135
18136    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18137        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18138    }
18139
18140    /**
18141     *  This method is an internal method that could be get invoked either
18142     *  to delete an installed package or to clean up a failed installation.
18143     *  After deleting an installed package, a broadcast is sent to notify any
18144     *  listeners that the package has been removed. For cleaning up a failed
18145     *  installation, the broadcast is not necessary since the package's
18146     *  installation wouldn't have sent the initial broadcast either
18147     *  The key steps in deleting a package are
18148     *  deleting the package information in internal structures like mPackages,
18149     *  deleting the packages base directories through installd
18150     *  updating mSettings to reflect current status
18151     *  persisting settings for later use
18152     *  sending a broadcast if necessary
18153     */
18154    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18155        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18156        final boolean res;
18157
18158        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18159                ? UserHandle.USER_ALL : userId;
18160
18161        if (isPackageDeviceAdmin(packageName, removeUser)) {
18162            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18163            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18164        }
18165
18166        PackageSetting uninstalledPs = null;
18167        PackageParser.Package pkg = null;
18168
18169        // for the uninstall-updates case and restricted profiles, remember the per-
18170        // user handle installed state
18171        int[] allUsers;
18172        synchronized (mPackages) {
18173            uninstalledPs = mSettings.mPackages.get(packageName);
18174            if (uninstalledPs == null) {
18175                Slog.w(TAG, "Not removing non-existent package " + packageName);
18176                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18177            }
18178
18179            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18180                    && uninstalledPs.versionCode != versionCode) {
18181                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18182                        + uninstalledPs.versionCode + " != " + versionCode);
18183                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18184            }
18185
18186            // Static shared libs can be declared by any package, so let us not
18187            // allow removing a package if it provides a lib others depend on.
18188            pkg = mPackages.get(packageName);
18189
18190            allUsers = sUserManager.getUserIds();
18191
18192            if (pkg != null && pkg.staticSharedLibName != null) {
18193                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18194                        pkg.staticSharedLibVersion);
18195                if (libEntry != null) {
18196                    for (int currUserId : allUsers) {
18197                        if (userId != UserHandle.USER_ALL && userId != currUserId) {
18198                            continue;
18199                        }
18200                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18201                                libEntry.info, 0, currUserId);
18202                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18203                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18204                                    + " hosting lib " + libEntry.info.getName() + " version "
18205                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18206                                    + " for user " + currUserId);
18207                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18208                        }
18209                    }
18210                }
18211            }
18212
18213            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18214        }
18215
18216        final int freezeUser;
18217        if (isUpdatedSystemApp(uninstalledPs)
18218                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18219            // We're downgrading a system app, which will apply to all users, so
18220            // freeze them all during the downgrade
18221            freezeUser = UserHandle.USER_ALL;
18222        } else {
18223            freezeUser = removeUser;
18224        }
18225
18226        synchronized (mInstallLock) {
18227            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18228            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18229                    deleteFlags, "deletePackageX")) {
18230                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18231                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18232            }
18233            synchronized (mPackages) {
18234                if (res) {
18235                    if (pkg != null) {
18236                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18237                    }
18238                    updateSequenceNumberLP(packageName, info.removedUsers);
18239                    updateInstantAppInstallerLocked(packageName);
18240                }
18241            }
18242        }
18243
18244        if (res) {
18245            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18246            info.sendPackageRemovedBroadcasts(killApp);
18247            info.sendSystemPackageUpdatedBroadcasts();
18248            info.sendSystemPackageAppearedBroadcasts();
18249        }
18250        // Force a gc here.
18251        Runtime.getRuntime().gc();
18252        // Delete the resources here after sending the broadcast to let
18253        // other processes clean up before deleting resources.
18254        if (info.args != null) {
18255            synchronized (mInstallLock) {
18256                info.args.doPostDeleteLI(true);
18257            }
18258        }
18259
18260        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18261    }
18262
18263    static class PackageRemovedInfo {
18264        final PackageSender packageSender;
18265        String removedPackage;
18266        String installerPackageName;
18267        int uid = -1;
18268        int removedAppId = -1;
18269        int[] origUsers;
18270        int[] removedUsers = null;
18271        int[] broadcastUsers = null;
18272        SparseArray<Integer> installReasons;
18273        boolean isRemovedPackageSystemUpdate = false;
18274        boolean isUpdate;
18275        boolean dataRemoved;
18276        boolean removedForAllUsers;
18277        boolean isStaticSharedLib;
18278        // Clean up resources deleted packages.
18279        InstallArgs args = null;
18280        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18281        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18282
18283        PackageRemovedInfo(PackageSender packageSender) {
18284            this.packageSender = packageSender;
18285        }
18286
18287        void sendPackageRemovedBroadcasts(boolean killApp) {
18288            sendPackageRemovedBroadcastInternal(killApp);
18289            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18290            for (int i = 0; i < childCount; i++) {
18291                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18292                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18293            }
18294        }
18295
18296        void sendSystemPackageUpdatedBroadcasts() {
18297            if (isRemovedPackageSystemUpdate) {
18298                sendSystemPackageUpdatedBroadcastsInternal();
18299                final int childCount = (removedChildPackages != null)
18300                        ? removedChildPackages.size() : 0;
18301                for (int i = 0; i < childCount; i++) {
18302                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18303                    if (childInfo.isRemovedPackageSystemUpdate) {
18304                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18305                    }
18306                }
18307            }
18308        }
18309
18310        void sendSystemPackageAppearedBroadcasts() {
18311            final int packageCount = (appearedChildPackages != null)
18312                    ? appearedChildPackages.size() : 0;
18313            for (int i = 0; i < packageCount; i++) {
18314                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18315                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18316                    true, UserHandle.getAppId(installedInfo.uid),
18317                    installedInfo.newUsers);
18318            }
18319        }
18320
18321        private void sendSystemPackageUpdatedBroadcastsInternal() {
18322            Bundle extras = new Bundle(2);
18323            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18324            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18325            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18326                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18327            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18328                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18329            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18330                null, null, 0, removedPackage, null, null);
18331            if (installerPackageName != null) {
18332                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18333                        removedPackage, extras, 0 /*flags*/,
18334                        installerPackageName, null, null);
18335                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18336                        removedPackage, extras, 0 /*flags*/,
18337                        installerPackageName, null, null);
18338            }
18339        }
18340
18341        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18342            // Don't send static shared library removal broadcasts as these
18343            // libs are visible only the the apps that depend on them an one
18344            // cannot remove the library if it has a dependency.
18345            if (isStaticSharedLib) {
18346                return;
18347            }
18348            Bundle extras = new Bundle(2);
18349            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18350            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18351            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18352            if (isUpdate || isRemovedPackageSystemUpdate) {
18353                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18354            }
18355            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18356            if (removedPackage != null) {
18357                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18358                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
18359                if (installerPackageName != null) {
18360                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18361                            removedPackage, extras, 0 /*flags*/,
18362                            installerPackageName, null, broadcastUsers);
18363                }
18364                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18365                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18366                        removedPackage, extras,
18367                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18368                        null, null, broadcastUsers);
18369                }
18370            }
18371            if (removedAppId >= 0) {
18372                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18373                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18374                    null, null, broadcastUsers);
18375            }
18376        }
18377
18378        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18379            removedUsers = userIds;
18380            if (removedUsers == null) {
18381                broadcastUsers = null;
18382                return;
18383            }
18384
18385            broadcastUsers = EMPTY_INT_ARRAY;
18386            for (int i = userIds.length - 1; i >= 0; --i) {
18387                final int userId = userIds[i];
18388                if (deletedPackageSetting.getInstantApp(userId)) {
18389                    continue;
18390                }
18391                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18392            }
18393        }
18394    }
18395
18396    /*
18397     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18398     * flag is not set, the data directory is removed as well.
18399     * make sure this flag is set for partially installed apps. If not its meaningless to
18400     * delete a partially installed application.
18401     */
18402    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18403            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18404        String packageName = ps.name;
18405        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18406        // Retrieve object to delete permissions for shared user later on
18407        final PackageParser.Package deletedPkg;
18408        final PackageSetting deletedPs;
18409        // reader
18410        synchronized (mPackages) {
18411            deletedPkg = mPackages.get(packageName);
18412            deletedPs = mSettings.mPackages.get(packageName);
18413            if (outInfo != null) {
18414                outInfo.removedPackage = packageName;
18415                outInfo.installerPackageName = ps.installerPackageName;
18416                outInfo.isStaticSharedLib = deletedPkg != null
18417                        && deletedPkg.staticSharedLibName != null;
18418                outInfo.populateUsers(deletedPs == null ? null
18419                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18420            }
18421        }
18422
18423        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
18424
18425        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18426            final PackageParser.Package resolvedPkg;
18427            if (deletedPkg != null) {
18428                resolvedPkg = deletedPkg;
18429            } else {
18430                // We don't have a parsed package when it lives on an ejected
18431                // adopted storage device, so fake something together
18432                resolvedPkg = new PackageParser.Package(ps.name);
18433                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18434            }
18435            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18436                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18437            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18438            if (outInfo != null) {
18439                outInfo.dataRemoved = true;
18440            }
18441            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18442        }
18443
18444        int removedAppId = -1;
18445
18446        // writer
18447        synchronized (mPackages) {
18448            boolean installedStateChanged = false;
18449            if (deletedPs != null) {
18450                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18451                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18452                    clearDefaultBrowserIfNeeded(packageName);
18453                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18454                    removedAppId = mSettings.removePackageLPw(packageName);
18455                    if (outInfo != null) {
18456                        outInfo.removedAppId = removedAppId;
18457                    }
18458                    updatePermissionsLPw(deletedPs.name, null, 0);
18459                    if (deletedPs.sharedUser != null) {
18460                        // Remove permissions associated with package. Since runtime
18461                        // permissions are per user we have to kill the removed package
18462                        // or packages running under the shared user of the removed
18463                        // package if revoking the permissions requested only by the removed
18464                        // package is successful and this causes a change in gids.
18465                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18466                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18467                                    userId);
18468                            if (userIdToKill == UserHandle.USER_ALL
18469                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18470                                // If gids changed for this user, kill all affected packages.
18471                                mHandler.post(new Runnable() {
18472                                    @Override
18473                                    public void run() {
18474                                        // This has to happen with no lock held.
18475                                        killApplication(deletedPs.name, deletedPs.appId,
18476                                                KILL_APP_REASON_GIDS_CHANGED);
18477                                    }
18478                                });
18479                                break;
18480                            }
18481                        }
18482                    }
18483                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18484                }
18485                // make sure to preserve per-user disabled state if this removal was just
18486                // a downgrade of a system app to the factory package
18487                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18488                    if (DEBUG_REMOVE) {
18489                        Slog.d(TAG, "Propagating install state across downgrade");
18490                    }
18491                    for (int userId : allUserHandles) {
18492                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18493                        if (DEBUG_REMOVE) {
18494                            Slog.d(TAG, "    user " + userId + " => " + installed);
18495                        }
18496                        if (installed != ps.getInstalled(userId)) {
18497                            installedStateChanged = true;
18498                        }
18499                        ps.setInstalled(installed, userId);
18500                    }
18501                }
18502            }
18503            // can downgrade to reader
18504            if (writeSettings) {
18505                // Save settings now
18506                mSettings.writeLPr();
18507            }
18508            if (installedStateChanged) {
18509                mSettings.writeKernelMappingLPr(ps);
18510            }
18511        }
18512        if (removedAppId != -1) {
18513            // A user ID was deleted here. Go through all users and remove it
18514            // from KeyStore.
18515            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18516        }
18517    }
18518
18519    static boolean locationIsPrivileged(File path) {
18520        try {
18521            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18522                    .getCanonicalPath();
18523            return path.getCanonicalPath().startsWith(privilegedAppDir);
18524        } catch (IOException e) {
18525            Slog.e(TAG, "Unable to access code path " + path);
18526        }
18527        return false;
18528    }
18529
18530    /*
18531     * Tries to delete system package.
18532     */
18533    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18534            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18535            boolean writeSettings) {
18536        if (deletedPs.parentPackageName != null) {
18537            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18538            return false;
18539        }
18540
18541        final boolean applyUserRestrictions
18542                = (allUserHandles != null) && (outInfo.origUsers != null);
18543        final PackageSetting disabledPs;
18544        // Confirm if the system package has been updated
18545        // An updated system app can be deleted. This will also have to restore
18546        // the system pkg from system partition
18547        // reader
18548        synchronized (mPackages) {
18549            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18550        }
18551
18552        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18553                + " disabledPs=" + disabledPs);
18554
18555        if (disabledPs == null) {
18556            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18557            return false;
18558        } else if (DEBUG_REMOVE) {
18559            Slog.d(TAG, "Deleting system pkg from data partition");
18560        }
18561
18562        if (DEBUG_REMOVE) {
18563            if (applyUserRestrictions) {
18564                Slog.d(TAG, "Remembering install states:");
18565                for (int userId : allUserHandles) {
18566                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18567                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18568                }
18569            }
18570        }
18571
18572        // Delete the updated package
18573        outInfo.isRemovedPackageSystemUpdate = true;
18574        if (outInfo.removedChildPackages != null) {
18575            final int childCount = (deletedPs.childPackageNames != null)
18576                    ? deletedPs.childPackageNames.size() : 0;
18577            for (int i = 0; i < childCount; i++) {
18578                String childPackageName = deletedPs.childPackageNames.get(i);
18579                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18580                        .contains(childPackageName)) {
18581                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18582                            childPackageName);
18583                    if (childInfo != null) {
18584                        childInfo.isRemovedPackageSystemUpdate = true;
18585                    }
18586                }
18587            }
18588        }
18589
18590        if (disabledPs.versionCode < deletedPs.versionCode) {
18591            // Delete data for downgrades
18592            flags &= ~PackageManager.DELETE_KEEP_DATA;
18593        } else {
18594            // Preserve data by setting flag
18595            flags |= PackageManager.DELETE_KEEP_DATA;
18596        }
18597
18598        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18599                outInfo, writeSettings, disabledPs.pkg);
18600        if (!ret) {
18601            return false;
18602        }
18603
18604        // writer
18605        synchronized (mPackages) {
18606            // Reinstate the old system package
18607            enableSystemPackageLPw(disabledPs.pkg);
18608            // Remove any native libraries from the upgraded package.
18609            removeNativeBinariesLI(deletedPs);
18610        }
18611
18612        // Install the system package
18613        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18614        int parseFlags = mDefParseFlags
18615                | PackageParser.PARSE_MUST_BE_APK
18616                | PackageParser.PARSE_IS_SYSTEM
18617                | PackageParser.PARSE_IS_SYSTEM_DIR;
18618        if (locationIsPrivileged(disabledPs.codePath)) {
18619            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18620        }
18621
18622        final PackageParser.Package newPkg;
18623        try {
18624            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18625                0 /* currentTime */, null);
18626        } catch (PackageManagerException e) {
18627            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18628                    + e.getMessage());
18629            return false;
18630        }
18631
18632        try {
18633            // update shared libraries for the newly re-installed system package
18634            updateSharedLibrariesLPr(newPkg, null);
18635        } catch (PackageManagerException e) {
18636            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18637        }
18638
18639        prepareAppDataAfterInstallLIF(newPkg);
18640
18641        // writer
18642        synchronized (mPackages) {
18643            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18644
18645            // Propagate the permissions state as we do not want to drop on the floor
18646            // runtime permissions. The update permissions method below will take
18647            // care of removing obsolete permissions and grant install permissions.
18648            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18649            updatePermissionsLPw(newPkg.packageName, newPkg,
18650                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18651
18652            if (applyUserRestrictions) {
18653                boolean installedStateChanged = false;
18654                if (DEBUG_REMOVE) {
18655                    Slog.d(TAG, "Propagating install state across reinstall");
18656                }
18657                for (int userId : allUserHandles) {
18658                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18659                    if (DEBUG_REMOVE) {
18660                        Slog.d(TAG, "    user " + userId + " => " + installed);
18661                    }
18662                    if (installed != ps.getInstalled(userId)) {
18663                        installedStateChanged = true;
18664                    }
18665                    ps.setInstalled(installed, userId);
18666
18667                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18668                }
18669                // Regardless of writeSettings we need to ensure that this restriction
18670                // state propagation is persisted
18671                mSettings.writeAllUsersPackageRestrictionsLPr();
18672                if (installedStateChanged) {
18673                    mSettings.writeKernelMappingLPr(ps);
18674                }
18675            }
18676            // can downgrade to reader here
18677            if (writeSettings) {
18678                mSettings.writeLPr();
18679            }
18680        }
18681        return true;
18682    }
18683
18684    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18685            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18686            PackageRemovedInfo outInfo, boolean writeSettings,
18687            PackageParser.Package replacingPackage) {
18688        synchronized (mPackages) {
18689            if (outInfo != null) {
18690                outInfo.uid = ps.appId;
18691            }
18692
18693            if (outInfo != null && outInfo.removedChildPackages != null) {
18694                final int childCount = (ps.childPackageNames != null)
18695                        ? ps.childPackageNames.size() : 0;
18696                for (int i = 0; i < childCount; i++) {
18697                    String childPackageName = ps.childPackageNames.get(i);
18698                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18699                    if (childPs == null) {
18700                        return false;
18701                    }
18702                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18703                            childPackageName);
18704                    if (childInfo != null) {
18705                        childInfo.uid = childPs.appId;
18706                    }
18707                }
18708            }
18709        }
18710
18711        // Delete package data from internal structures and also remove data if flag is set
18712        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18713
18714        // Delete the child packages data
18715        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18716        for (int i = 0; i < childCount; i++) {
18717            PackageSetting childPs;
18718            synchronized (mPackages) {
18719                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18720            }
18721            if (childPs != null) {
18722                PackageRemovedInfo childOutInfo = (outInfo != null
18723                        && outInfo.removedChildPackages != null)
18724                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18725                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18726                        && (replacingPackage != null
18727                        && !replacingPackage.hasChildPackage(childPs.name))
18728                        ? flags & ~DELETE_KEEP_DATA : flags;
18729                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18730                        deleteFlags, writeSettings);
18731            }
18732        }
18733
18734        // Delete application code and resources only for parent packages
18735        if (ps.parentPackageName == null) {
18736            if (deleteCodeAndResources && (outInfo != null)) {
18737                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18738                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18739                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18740            }
18741        }
18742
18743        return true;
18744    }
18745
18746    @Override
18747    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18748            int userId) {
18749        mContext.enforceCallingOrSelfPermission(
18750                android.Manifest.permission.DELETE_PACKAGES, null);
18751        synchronized (mPackages) {
18752            // Cannot block uninstall of static shared libs as they are
18753            // considered a part of the using app (emulating static linking).
18754            // Also static libs are installed always on internal storage.
18755            PackageParser.Package pkg = mPackages.get(packageName);
18756            if (pkg != null && pkg.staticSharedLibName != null) {
18757                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18758                        + " providing static shared library: " + pkg.staticSharedLibName);
18759                return false;
18760            }
18761            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18762            mSettings.writePackageRestrictionsLPr(userId);
18763        }
18764        return true;
18765    }
18766
18767    @Override
18768    public boolean getBlockUninstallForUser(String packageName, int userId) {
18769        synchronized (mPackages) {
18770            return mSettings.getBlockUninstallLPr(userId, packageName);
18771        }
18772    }
18773
18774    @Override
18775    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18776        int callingUid = Binder.getCallingUid();
18777        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18778            throw new SecurityException(
18779                    "setRequiredForSystemUser can only be run by the system or root");
18780        }
18781        synchronized (mPackages) {
18782            PackageSetting ps = mSettings.mPackages.get(packageName);
18783            if (ps == null) {
18784                Log.w(TAG, "Package doesn't exist: " + packageName);
18785                return false;
18786            }
18787            if (systemUserApp) {
18788                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18789            } else {
18790                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18791            }
18792            mSettings.writeLPr();
18793        }
18794        return true;
18795    }
18796
18797    /*
18798     * This method handles package deletion in general
18799     */
18800    private boolean deletePackageLIF(String packageName, UserHandle user,
18801            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18802            PackageRemovedInfo outInfo, boolean writeSettings,
18803            PackageParser.Package replacingPackage) {
18804        if (packageName == null) {
18805            Slog.w(TAG, "Attempt to delete null packageName.");
18806            return false;
18807        }
18808
18809        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18810
18811        PackageSetting ps;
18812        synchronized (mPackages) {
18813            ps = mSettings.mPackages.get(packageName);
18814            if (ps == null) {
18815                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18816                return false;
18817            }
18818
18819            if (ps.parentPackageName != null && (!isSystemApp(ps)
18820                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18821                if (DEBUG_REMOVE) {
18822                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18823                            + ((user == null) ? UserHandle.USER_ALL : user));
18824                }
18825                final int removedUserId = (user != null) ? user.getIdentifier()
18826                        : UserHandle.USER_ALL;
18827                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18828                    return false;
18829                }
18830                markPackageUninstalledForUserLPw(ps, user);
18831                scheduleWritePackageRestrictionsLocked(user);
18832                return true;
18833            }
18834        }
18835
18836        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18837                && user.getIdentifier() != UserHandle.USER_ALL)) {
18838            // The caller is asking that the package only be deleted for a single
18839            // user.  To do this, we just mark its uninstalled state and delete
18840            // its data. If this is a system app, we only allow this to happen if
18841            // they have set the special DELETE_SYSTEM_APP which requests different
18842            // semantics than normal for uninstalling system apps.
18843            markPackageUninstalledForUserLPw(ps, user);
18844
18845            if (!isSystemApp(ps)) {
18846                // Do not uninstall the APK if an app should be cached
18847                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18848                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18849                    // Other user still have this package installed, so all
18850                    // we need to do is clear this user's data and save that
18851                    // it is uninstalled.
18852                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18853                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18854                        return false;
18855                    }
18856                    scheduleWritePackageRestrictionsLocked(user);
18857                    return true;
18858                } else {
18859                    // We need to set it back to 'installed' so the uninstall
18860                    // broadcasts will be sent correctly.
18861                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18862                    ps.setInstalled(true, user.getIdentifier());
18863                    mSettings.writeKernelMappingLPr(ps);
18864                }
18865            } else {
18866                // This is a system app, so we assume that the
18867                // other users still have this package installed, so all
18868                // we need to do is clear this user's data and save that
18869                // it is uninstalled.
18870                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18871                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18872                    return false;
18873                }
18874                scheduleWritePackageRestrictionsLocked(user);
18875                return true;
18876            }
18877        }
18878
18879        // If we are deleting a composite package for all users, keep track
18880        // of result for each child.
18881        if (ps.childPackageNames != null && outInfo != null) {
18882            synchronized (mPackages) {
18883                final int childCount = ps.childPackageNames.size();
18884                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18885                for (int i = 0; i < childCount; i++) {
18886                    String childPackageName = ps.childPackageNames.get(i);
18887                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18888                    childInfo.removedPackage = childPackageName;
18889                    childInfo.installerPackageName = ps.installerPackageName;
18890                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18891                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18892                    if (childPs != null) {
18893                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18894                    }
18895                }
18896            }
18897        }
18898
18899        boolean ret = false;
18900        if (isSystemApp(ps)) {
18901            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18902            // When an updated system application is deleted we delete the existing resources
18903            // as well and fall back to existing code in system partition
18904            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18905        } else {
18906            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18907            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18908                    outInfo, writeSettings, replacingPackage);
18909        }
18910
18911        // Take a note whether we deleted the package for all users
18912        if (outInfo != null) {
18913            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18914            if (outInfo.removedChildPackages != null) {
18915                synchronized (mPackages) {
18916                    final int childCount = outInfo.removedChildPackages.size();
18917                    for (int i = 0; i < childCount; i++) {
18918                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18919                        if (childInfo != null) {
18920                            childInfo.removedForAllUsers = mPackages.get(
18921                                    childInfo.removedPackage) == null;
18922                        }
18923                    }
18924                }
18925            }
18926            // If we uninstalled an update to a system app there may be some
18927            // child packages that appeared as they are declared in the system
18928            // app but were not declared in the update.
18929            if (isSystemApp(ps)) {
18930                synchronized (mPackages) {
18931                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18932                    final int childCount = (updatedPs.childPackageNames != null)
18933                            ? updatedPs.childPackageNames.size() : 0;
18934                    for (int i = 0; i < childCount; i++) {
18935                        String childPackageName = updatedPs.childPackageNames.get(i);
18936                        if (outInfo.removedChildPackages == null
18937                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18938                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18939                            if (childPs == null) {
18940                                continue;
18941                            }
18942                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18943                            installRes.name = childPackageName;
18944                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18945                            installRes.pkg = mPackages.get(childPackageName);
18946                            installRes.uid = childPs.pkg.applicationInfo.uid;
18947                            if (outInfo.appearedChildPackages == null) {
18948                                outInfo.appearedChildPackages = new ArrayMap<>();
18949                            }
18950                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18951                        }
18952                    }
18953                }
18954            }
18955        }
18956
18957        return ret;
18958    }
18959
18960    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18961        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18962                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18963        for (int nextUserId : userIds) {
18964            if (DEBUG_REMOVE) {
18965                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18966            }
18967            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18968                    false /*installed*/,
18969                    true /*stopped*/,
18970                    true /*notLaunched*/,
18971                    false /*hidden*/,
18972                    false /*suspended*/,
18973                    false /*instantApp*/,
18974                    null /*lastDisableAppCaller*/,
18975                    null /*enabledComponents*/,
18976                    null /*disabledComponents*/,
18977                    ps.readUserState(nextUserId).domainVerificationStatus,
18978                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18979        }
18980        mSettings.writeKernelMappingLPr(ps);
18981    }
18982
18983    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18984            PackageRemovedInfo outInfo) {
18985        final PackageParser.Package pkg;
18986        synchronized (mPackages) {
18987            pkg = mPackages.get(ps.name);
18988        }
18989
18990        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18991                : new int[] {userId};
18992        for (int nextUserId : userIds) {
18993            if (DEBUG_REMOVE) {
18994                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18995                        + nextUserId);
18996            }
18997
18998            destroyAppDataLIF(pkg, userId,
18999                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19000            destroyAppProfilesLIF(pkg, userId);
19001            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19002            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19003            schedulePackageCleaning(ps.name, nextUserId, false);
19004            synchronized (mPackages) {
19005                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19006                    scheduleWritePackageRestrictionsLocked(nextUserId);
19007                }
19008                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19009            }
19010        }
19011
19012        if (outInfo != null) {
19013            outInfo.removedPackage = ps.name;
19014            outInfo.installerPackageName = ps.installerPackageName;
19015            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19016            outInfo.removedAppId = ps.appId;
19017            outInfo.removedUsers = userIds;
19018            outInfo.broadcastUsers = userIds;
19019        }
19020
19021        return true;
19022    }
19023
19024    private final class ClearStorageConnection implements ServiceConnection {
19025        IMediaContainerService mContainerService;
19026
19027        @Override
19028        public void onServiceConnected(ComponentName name, IBinder service) {
19029            synchronized (this) {
19030                mContainerService = IMediaContainerService.Stub
19031                        .asInterface(Binder.allowBlocking(service));
19032                notifyAll();
19033            }
19034        }
19035
19036        @Override
19037        public void onServiceDisconnected(ComponentName name) {
19038        }
19039    }
19040
19041    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19042        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19043
19044        final boolean mounted;
19045        if (Environment.isExternalStorageEmulated()) {
19046            mounted = true;
19047        } else {
19048            final String status = Environment.getExternalStorageState();
19049
19050            mounted = status.equals(Environment.MEDIA_MOUNTED)
19051                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19052        }
19053
19054        if (!mounted) {
19055            return;
19056        }
19057
19058        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19059        int[] users;
19060        if (userId == UserHandle.USER_ALL) {
19061            users = sUserManager.getUserIds();
19062        } else {
19063            users = new int[] { userId };
19064        }
19065        final ClearStorageConnection conn = new ClearStorageConnection();
19066        if (mContext.bindServiceAsUser(
19067                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19068            try {
19069                for (int curUser : users) {
19070                    long timeout = SystemClock.uptimeMillis() + 5000;
19071                    synchronized (conn) {
19072                        long now;
19073                        while (conn.mContainerService == null &&
19074                                (now = SystemClock.uptimeMillis()) < timeout) {
19075                            try {
19076                                conn.wait(timeout - now);
19077                            } catch (InterruptedException e) {
19078                            }
19079                        }
19080                    }
19081                    if (conn.mContainerService == null) {
19082                        return;
19083                    }
19084
19085                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19086                    clearDirectory(conn.mContainerService,
19087                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19088                    if (allData) {
19089                        clearDirectory(conn.mContainerService,
19090                                userEnv.buildExternalStorageAppDataDirs(packageName));
19091                        clearDirectory(conn.mContainerService,
19092                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19093                    }
19094                }
19095            } finally {
19096                mContext.unbindService(conn);
19097            }
19098        }
19099    }
19100
19101    @Override
19102    public void clearApplicationProfileData(String packageName) {
19103        enforceSystemOrRoot("Only the system can clear all profile data");
19104
19105        final PackageParser.Package pkg;
19106        synchronized (mPackages) {
19107            pkg = mPackages.get(packageName);
19108        }
19109
19110        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19111            synchronized (mInstallLock) {
19112                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19113            }
19114        }
19115    }
19116
19117    @Override
19118    public void clearApplicationUserData(final String packageName,
19119            final IPackageDataObserver observer, final int userId) {
19120        mContext.enforceCallingOrSelfPermission(
19121                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19122
19123        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19124                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19125
19126        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19127            throw new SecurityException("Cannot clear data for a protected package: "
19128                    + packageName);
19129        }
19130        // Queue up an async operation since the package deletion may take a little while.
19131        mHandler.post(new Runnable() {
19132            public void run() {
19133                mHandler.removeCallbacks(this);
19134                final boolean succeeded;
19135                try (PackageFreezer freezer = freezePackage(packageName,
19136                        "clearApplicationUserData")) {
19137                    synchronized (mInstallLock) {
19138                        succeeded = clearApplicationUserDataLIF(packageName, userId);
19139                    }
19140                    clearExternalStorageDataSync(packageName, userId, true);
19141                    synchronized (mPackages) {
19142                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19143                                packageName, userId);
19144                    }
19145                }
19146                if (succeeded) {
19147                    // invoke DeviceStorageMonitor's update method to clear any notifications
19148                    DeviceStorageMonitorInternal dsm = LocalServices
19149                            .getService(DeviceStorageMonitorInternal.class);
19150                    if (dsm != null) {
19151                        dsm.checkMemory();
19152                    }
19153                }
19154                if(observer != null) {
19155                    try {
19156                        observer.onRemoveCompleted(packageName, succeeded);
19157                    } catch (RemoteException e) {
19158                        Log.i(TAG, "Observer no longer exists.");
19159                    }
19160                } //end if observer
19161            } //end run
19162        });
19163    }
19164
19165    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19166        if (packageName == null) {
19167            Slog.w(TAG, "Attempt to delete null packageName.");
19168            return false;
19169        }
19170
19171        // Try finding details about the requested package
19172        PackageParser.Package pkg;
19173        synchronized (mPackages) {
19174            pkg = mPackages.get(packageName);
19175            if (pkg == null) {
19176                final PackageSetting ps = mSettings.mPackages.get(packageName);
19177                if (ps != null) {
19178                    pkg = ps.pkg;
19179                }
19180            }
19181
19182            if (pkg == null) {
19183                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19184                return false;
19185            }
19186
19187            PackageSetting ps = (PackageSetting) pkg.mExtras;
19188            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19189        }
19190
19191        clearAppDataLIF(pkg, userId,
19192                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19193
19194        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19195        removeKeystoreDataIfNeeded(userId, appId);
19196
19197        UserManagerInternal umInternal = getUserManagerInternal();
19198        final int flags;
19199        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19200            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19201        } else if (umInternal.isUserRunning(userId)) {
19202            flags = StorageManager.FLAG_STORAGE_DE;
19203        } else {
19204            flags = 0;
19205        }
19206        prepareAppDataContentsLIF(pkg, userId, flags);
19207
19208        return true;
19209    }
19210
19211    /**
19212     * Reverts user permission state changes (permissions and flags) in
19213     * all packages for a given user.
19214     *
19215     * @param userId The device user for which to do a reset.
19216     */
19217    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19218        final int packageCount = mPackages.size();
19219        for (int i = 0; i < packageCount; i++) {
19220            PackageParser.Package pkg = mPackages.valueAt(i);
19221            PackageSetting ps = (PackageSetting) pkg.mExtras;
19222            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19223        }
19224    }
19225
19226    private void resetNetworkPolicies(int userId) {
19227        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19228    }
19229
19230    /**
19231     * Reverts user permission state changes (permissions and flags).
19232     *
19233     * @param ps The package for which to reset.
19234     * @param userId The device user for which to do a reset.
19235     */
19236    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19237            final PackageSetting ps, final int userId) {
19238        if (ps.pkg == null) {
19239            return;
19240        }
19241
19242        // These are flags that can change base on user actions.
19243        final int userSettableMask = FLAG_PERMISSION_USER_SET
19244                | FLAG_PERMISSION_USER_FIXED
19245                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19246                | FLAG_PERMISSION_REVIEW_REQUIRED;
19247
19248        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19249                | FLAG_PERMISSION_POLICY_FIXED;
19250
19251        boolean writeInstallPermissions = false;
19252        boolean writeRuntimePermissions = false;
19253
19254        final int permissionCount = ps.pkg.requestedPermissions.size();
19255        for (int i = 0; i < permissionCount; i++) {
19256            String permission = ps.pkg.requestedPermissions.get(i);
19257
19258            BasePermission bp = mSettings.mPermissions.get(permission);
19259            if (bp == null) {
19260                continue;
19261            }
19262
19263            // If shared user we just reset the state to which only this app contributed.
19264            if (ps.sharedUser != null) {
19265                boolean used = false;
19266                final int packageCount = ps.sharedUser.packages.size();
19267                for (int j = 0; j < packageCount; j++) {
19268                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19269                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19270                            && pkg.pkg.requestedPermissions.contains(permission)) {
19271                        used = true;
19272                        break;
19273                    }
19274                }
19275                if (used) {
19276                    continue;
19277                }
19278            }
19279
19280            PermissionsState permissionsState = ps.getPermissionsState();
19281
19282            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
19283
19284            // Always clear the user settable flags.
19285            final boolean hasInstallState = permissionsState.getInstallPermissionState(
19286                    bp.name) != null;
19287            // If permission review is enabled and this is a legacy app, mark the
19288            // permission as requiring a review as this is the initial state.
19289            int flags = 0;
19290            if (mPermissionReviewRequired
19291                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19292                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19293            }
19294            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19295                if (hasInstallState) {
19296                    writeInstallPermissions = true;
19297                } else {
19298                    writeRuntimePermissions = true;
19299                }
19300            }
19301
19302            // Below is only runtime permission handling.
19303            if (!bp.isRuntime()) {
19304                continue;
19305            }
19306
19307            // Never clobber system or policy.
19308            if ((oldFlags & policyOrSystemFlags) != 0) {
19309                continue;
19310            }
19311
19312            // If this permission was granted by default, make sure it is.
19313            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19314                if (permissionsState.grantRuntimePermission(bp, userId)
19315                        != PERMISSION_OPERATION_FAILURE) {
19316                    writeRuntimePermissions = true;
19317                }
19318            // If permission review is enabled the permissions for a legacy apps
19319            // are represented as constantly granted runtime ones, so don't revoke.
19320            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19321                // Otherwise, reset the permission.
19322                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19323                switch (revokeResult) {
19324                    case PERMISSION_OPERATION_SUCCESS:
19325                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19326                        writeRuntimePermissions = true;
19327                        final int appId = ps.appId;
19328                        mHandler.post(new Runnable() {
19329                            @Override
19330                            public void run() {
19331                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19332                            }
19333                        });
19334                    } break;
19335                }
19336            }
19337        }
19338
19339        // Synchronously write as we are taking permissions away.
19340        if (writeRuntimePermissions) {
19341            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19342        }
19343
19344        // Synchronously write as we are taking permissions away.
19345        if (writeInstallPermissions) {
19346            mSettings.writeLPr();
19347        }
19348    }
19349
19350    /**
19351     * Remove entries from the keystore daemon. Will only remove it if the
19352     * {@code appId} is valid.
19353     */
19354    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19355        if (appId < 0) {
19356            return;
19357        }
19358
19359        final KeyStore keyStore = KeyStore.getInstance();
19360        if (keyStore != null) {
19361            if (userId == UserHandle.USER_ALL) {
19362                for (final int individual : sUserManager.getUserIds()) {
19363                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19364                }
19365            } else {
19366                keyStore.clearUid(UserHandle.getUid(userId, appId));
19367            }
19368        } else {
19369            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19370        }
19371    }
19372
19373    @Override
19374    public void deleteApplicationCacheFiles(final String packageName,
19375            final IPackageDataObserver observer) {
19376        final int userId = UserHandle.getCallingUserId();
19377        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19378    }
19379
19380    @Override
19381    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19382            final IPackageDataObserver observer) {
19383        mContext.enforceCallingOrSelfPermission(
19384                android.Manifest.permission.DELETE_CACHE_FILES, null);
19385        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19386                /* requireFullPermission= */ true, /* checkShell= */ false,
19387                "delete application cache files");
19388
19389        final PackageParser.Package pkg;
19390        synchronized (mPackages) {
19391            pkg = mPackages.get(packageName);
19392        }
19393
19394        // Queue up an async operation since the package deletion may take a little while.
19395        mHandler.post(new Runnable() {
19396            public void run() {
19397                synchronized (mInstallLock) {
19398                    final int flags = StorageManager.FLAG_STORAGE_DE
19399                            | StorageManager.FLAG_STORAGE_CE;
19400                    // We're only clearing cache files, so we don't care if the
19401                    // app is unfrozen and still able to run
19402                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19403                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19404                }
19405                clearExternalStorageDataSync(packageName, userId, false);
19406                if (observer != null) {
19407                    try {
19408                        observer.onRemoveCompleted(packageName, true);
19409                    } catch (RemoteException e) {
19410                        Log.i(TAG, "Observer no longer exists.");
19411                    }
19412                }
19413            }
19414        });
19415    }
19416
19417    @Override
19418    public void getPackageSizeInfo(final String packageName, int userHandle,
19419            final IPackageStatsObserver observer) {
19420        throw new UnsupportedOperationException(
19421                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19422    }
19423
19424    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19425        final PackageSetting ps;
19426        synchronized (mPackages) {
19427            ps = mSettings.mPackages.get(packageName);
19428            if (ps == null) {
19429                Slog.w(TAG, "Failed to find settings for " + packageName);
19430                return false;
19431            }
19432        }
19433
19434        final String[] packageNames = { packageName };
19435        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19436        final String[] codePaths = { ps.codePathString };
19437
19438        try {
19439            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19440                    ps.appId, ceDataInodes, codePaths, stats);
19441
19442            // For now, ignore code size of packages on system partition
19443            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19444                stats.codeSize = 0;
19445            }
19446
19447            // External clients expect these to be tracked separately
19448            stats.dataSize -= stats.cacheSize;
19449
19450        } catch (InstallerException e) {
19451            Slog.w(TAG, String.valueOf(e));
19452            return false;
19453        }
19454
19455        return true;
19456    }
19457
19458    private int getUidTargetSdkVersionLockedLPr(int uid) {
19459        Object obj = mSettings.getUserIdLPr(uid);
19460        if (obj instanceof SharedUserSetting) {
19461            final SharedUserSetting sus = (SharedUserSetting) obj;
19462            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19463            final Iterator<PackageSetting> it = sus.packages.iterator();
19464            while (it.hasNext()) {
19465                final PackageSetting ps = it.next();
19466                if (ps.pkg != null) {
19467                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19468                    if (v < vers) vers = v;
19469                }
19470            }
19471            return vers;
19472        } else if (obj instanceof PackageSetting) {
19473            final PackageSetting ps = (PackageSetting) obj;
19474            if (ps.pkg != null) {
19475                return ps.pkg.applicationInfo.targetSdkVersion;
19476            }
19477        }
19478        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19479    }
19480
19481    @Override
19482    public void addPreferredActivity(IntentFilter filter, int match,
19483            ComponentName[] set, ComponentName activity, int userId) {
19484        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19485                "Adding preferred");
19486    }
19487
19488    private void addPreferredActivityInternal(IntentFilter filter, int match,
19489            ComponentName[] set, ComponentName activity, boolean always, int userId,
19490            String opname) {
19491        // writer
19492        int callingUid = Binder.getCallingUid();
19493        enforceCrossUserPermission(callingUid, userId,
19494                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19495        if (filter.countActions() == 0) {
19496            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19497            return;
19498        }
19499        synchronized (mPackages) {
19500            if (mContext.checkCallingOrSelfPermission(
19501                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19502                    != PackageManager.PERMISSION_GRANTED) {
19503                if (getUidTargetSdkVersionLockedLPr(callingUid)
19504                        < Build.VERSION_CODES.FROYO) {
19505                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19506                            + callingUid);
19507                    return;
19508                }
19509                mContext.enforceCallingOrSelfPermission(
19510                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19511            }
19512
19513            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19514            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19515                    + userId + ":");
19516            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19517            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19518            scheduleWritePackageRestrictionsLocked(userId);
19519            postPreferredActivityChangedBroadcast(userId);
19520        }
19521    }
19522
19523    private void postPreferredActivityChangedBroadcast(int userId) {
19524        mHandler.post(() -> {
19525            final IActivityManager am = ActivityManager.getService();
19526            if (am == null) {
19527                return;
19528            }
19529
19530            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19531            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19532            try {
19533                am.broadcastIntent(null, intent, null, null,
19534                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19535                        null, false, false, userId);
19536            } catch (RemoteException e) {
19537            }
19538        });
19539    }
19540
19541    @Override
19542    public void replacePreferredActivity(IntentFilter filter, int match,
19543            ComponentName[] set, ComponentName activity, int userId) {
19544        if (filter.countActions() != 1) {
19545            throw new IllegalArgumentException(
19546                    "replacePreferredActivity expects filter to have only 1 action.");
19547        }
19548        if (filter.countDataAuthorities() != 0
19549                || filter.countDataPaths() != 0
19550                || filter.countDataSchemes() > 1
19551                || filter.countDataTypes() != 0) {
19552            throw new IllegalArgumentException(
19553                    "replacePreferredActivity expects filter to have no data authorities, " +
19554                    "paths, or types; and at most one scheme.");
19555        }
19556
19557        final int callingUid = Binder.getCallingUid();
19558        enforceCrossUserPermission(callingUid, userId,
19559                true /* requireFullPermission */, false /* checkShell */,
19560                "replace preferred activity");
19561        synchronized (mPackages) {
19562            if (mContext.checkCallingOrSelfPermission(
19563                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19564                    != PackageManager.PERMISSION_GRANTED) {
19565                if (getUidTargetSdkVersionLockedLPr(callingUid)
19566                        < Build.VERSION_CODES.FROYO) {
19567                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19568                            + Binder.getCallingUid());
19569                    return;
19570                }
19571                mContext.enforceCallingOrSelfPermission(
19572                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19573            }
19574
19575            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19576            if (pir != null) {
19577                // Get all of the existing entries that exactly match this filter.
19578                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19579                if (existing != null && existing.size() == 1) {
19580                    PreferredActivity cur = existing.get(0);
19581                    if (DEBUG_PREFERRED) {
19582                        Slog.i(TAG, "Checking replace of preferred:");
19583                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19584                        if (!cur.mPref.mAlways) {
19585                            Slog.i(TAG, "  -- CUR; not mAlways!");
19586                        } else {
19587                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19588                            Slog.i(TAG, "  -- CUR: mSet="
19589                                    + Arrays.toString(cur.mPref.mSetComponents));
19590                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19591                            Slog.i(TAG, "  -- NEW: mMatch="
19592                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19593                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19594                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19595                        }
19596                    }
19597                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19598                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19599                            && cur.mPref.sameSet(set)) {
19600                        // Setting the preferred activity to what it happens to be already
19601                        if (DEBUG_PREFERRED) {
19602                            Slog.i(TAG, "Replacing with same preferred activity "
19603                                    + cur.mPref.mShortComponent + " for user "
19604                                    + userId + ":");
19605                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19606                        }
19607                        return;
19608                    }
19609                }
19610
19611                if (existing != null) {
19612                    if (DEBUG_PREFERRED) {
19613                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19614                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19615                    }
19616                    for (int i = 0; i < existing.size(); i++) {
19617                        PreferredActivity pa = existing.get(i);
19618                        if (DEBUG_PREFERRED) {
19619                            Slog.i(TAG, "Removing existing preferred activity "
19620                                    + pa.mPref.mComponent + ":");
19621                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19622                        }
19623                        pir.removeFilter(pa);
19624                    }
19625                }
19626            }
19627            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19628                    "Replacing preferred");
19629        }
19630    }
19631
19632    @Override
19633    public void clearPackagePreferredActivities(String packageName) {
19634        final int uid = Binder.getCallingUid();
19635        // writer
19636        synchronized (mPackages) {
19637            PackageParser.Package pkg = mPackages.get(packageName);
19638            if (pkg == null || pkg.applicationInfo.uid != uid) {
19639                if (mContext.checkCallingOrSelfPermission(
19640                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19641                        != PackageManager.PERMISSION_GRANTED) {
19642                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19643                            < Build.VERSION_CODES.FROYO) {
19644                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19645                                + Binder.getCallingUid());
19646                        return;
19647                    }
19648                    mContext.enforceCallingOrSelfPermission(
19649                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19650                }
19651            }
19652
19653            int user = UserHandle.getCallingUserId();
19654            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19655                scheduleWritePackageRestrictionsLocked(user);
19656            }
19657        }
19658    }
19659
19660    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19661    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19662        ArrayList<PreferredActivity> removed = null;
19663        boolean changed = false;
19664        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19665            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19666            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19667            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19668                continue;
19669            }
19670            Iterator<PreferredActivity> it = pir.filterIterator();
19671            while (it.hasNext()) {
19672                PreferredActivity pa = it.next();
19673                // Mark entry for removal only if it matches the package name
19674                // and the entry is of type "always".
19675                if (packageName == null ||
19676                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19677                                && pa.mPref.mAlways)) {
19678                    if (removed == null) {
19679                        removed = new ArrayList<PreferredActivity>();
19680                    }
19681                    removed.add(pa);
19682                }
19683            }
19684            if (removed != null) {
19685                for (int j=0; j<removed.size(); j++) {
19686                    PreferredActivity pa = removed.get(j);
19687                    pir.removeFilter(pa);
19688                }
19689                changed = true;
19690            }
19691        }
19692        if (changed) {
19693            postPreferredActivityChangedBroadcast(userId);
19694        }
19695        return changed;
19696    }
19697
19698    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19699    private void clearIntentFilterVerificationsLPw(int userId) {
19700        final int packageCount = mPackages.size();
19701        for (int i = 0; i < packageCount; i++) {
19702            PackageParser.Package pkg = mPackages.valueAt(i);
19703            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19704        }
19705    }
19706
19707    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19708    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19709        if (userId == UserHandle.USER_ALL) {
19710            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19711                    sUserManager.getUserIds())) {
19712                for (int oneUserId : sUserManager.getUserIds()) {
19713                    scheduleWritePackageRestrictionsLocked(oneUserId);
19714                }
19715            }
19716        } else {
19717            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19718                scheduleWritePackageRestrictionsLocked(userId);
19719            }
19720        }
19721    }
19722
19723    /** Clears state for all users, and touches intent filter verification policy */
19724    void clearDefaultBrowserIfNeeded(String packageName) {
19725        for (int oneUserId : sUserManager.getUserIds()) {
19726            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19727        }
19728    }
19729
19730    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19731        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19732        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19733            if (packageName.equals(defaultBrowserPackageName)) {
19734                setDefaultBrowserPackageName(null, userId);
19735            }
19736        }
19737    }
19738
19739    @Override
19740    public void resetApplicationPreferences(int userId) {
19741        mContext.enforceCallingOrSelfPermission(
19742                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19743        final long identity = Binder.clearCallingIdentity();
19744        // writer
19745        try {
19746            synchronized (mPackages) {
19747                clearPackagePreferredActivitiesLPw(null, userId);
19748                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19749                // TODO: We have to reset the default SMS and Phone. This requires
19750                // significant refactoring to keep all default apps in the package
19751                // manager (cleaner but more work) or have the services provide
19752                // callbacks to the package manager to request a default app reset.
19753                applyFactoryDefaultBrowserLPw(userId);
19754                clearIntentFilterVerificationsLPw(userId);
19755                primeDomainVerificationsLPw(userId);
19756                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19757                scheduleWritePackageRestrictionsLocked(userId);
19758            }
19759            resetNetworkPolicies(userId);
19760        } finally {
19761            Binder.restoreCallingIdentity(identity);
19762        }
19763    }
19764
19765    @Override
19766    public int getPreferredActivities(List<IntentFilter> outFilters,
19767            List<ComponentName> outActivities, String packageName) {
19768
19769        int num = 0;
19770        final int userId = UserHandle.getCallingUserId();
19771        // reader
19772        synchronized (mPackages) {
19773            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19774            if (pir != null) {
19775                final Iterator<PreferredActivity> it = pir.filterIterator();
19776                while (it.hasNext()) {
19777                    final PreferredActivity pa = it.next();
19778                    if (packageName == null
19779                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19780                                    && pa.mPref.mAlways)) {
19781                        if (outFilters != null) {
19782                            outFilters.add(new IntentFilter(pa));
19783                        }
19784                        if (outActivities != null) {
19785                            outActivities.add(pa.mPref.mComponent);
19786                        }
19787                    }
19788                }
19789            }
19790        }
19791
19792        return num;
19793    }
19794
19795    @Override
19796    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19797            int userId) {
19798        int callingUid = Binder.getCallingUid();
19799        if (callingUid != Process.SYSTEM_UID) {
19800            throw new SecurityException(
19801                    "addPersistentPreferredActivity can only be run by the system");
19802        }
19803        if (filter.countActions() == 0) {
19804            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19805            return;
19806        }
19807        synchronized (mPackages) {
19808            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19809                    ":");
19810            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19811            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19812                    new PersistentPreferredActivity(filter, activity));
19813            scheduleWritePackageRestrictionsLocked(userId);
19814            postPreferredActivityChangedBroadcast(userId);
19815        }
19816    }
19817
19818    @Override
19819    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19820        int callingUid = Binder.getCallingUid();
19821        if (callingUid != Process.SYSTEM_UID) {
19822            throw new SecurityException(
19823                    "clearPackagePersistentPreferredActivities can only be run by the system");
19824        }
19825        ArrayList<PersistentPreferredActivity> removed = null;
19826        boolean changed = false;
19827        synchronized (mPackages) {
19828            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19829                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19830                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19831                        .valueAt(i);
19832                if (userId != thisUserId) {
19833                    continue;
19834                }
19835                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19836                while (it.hasNext()) {
19837                    PersistentPreferredActivity ppa = it.next();
19838                    // Mark entry for removal only if it matches the package name.
19839                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19840                        if (removed == null) {
19841                            removed = new ArrayList<PersistentPreferredActivity>();
19842                        }
19843                        removed.add(ppa);
19844                    }
19845                }
19846                if (removed != null) {
19847                    for (int j=0; j<removed.size(); j++) {
19848                        PersistentPreferredActivity ppa = removed.get(j);
19849                        ppir.removeFilter(ppa);
19850                    }
19851                    changed = true;
19852                }
19853            }
19854
19855            if (changed) {
19856                scheduleWritePackageRestrictionsLocked(userId);
19857                postPreferredActivityChangedBroadcast(userId);
19858            }
19859        }
19860    }
19861
19862    /**
19863     * Common machinery for picking apart a restored XML blob and passing
19864     * it to a caller-supplied functor to be applied to the running system.
19865     */
19866    private void restoreFromXml(XmlPullParser parser, int userId,
19867            String expectedStartTag, BlobXmlRestorer functor)
19868            throws IOException, XmlPullParserException {
19869        int type;
19870        while ((type = parser.next()) != XmlPullParser.START_TAG
19871                && type != XmlPullParser.END_DOCUMENT) {
19872        }
19873        if (type != XmlPullParser.START_TAG) {
19874            // oops didn't find a start tag?!
19875            if (DEBUG_BACKUP) {
19876                Slog.e(TAG, "Didn't find start tag during restore");
19877            }
19878            return;
19879        }
19880Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19881        // this is supposed to be TAG_PREFERRED_BACKUP
19882        if (!expectedStartTag.equals(parser.getName())) {
19883            if (DEBUG_BACKUP) {
19884                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19885            }
19886            return;
19887        }
19888
19889        // skip interfering stuff, then we're aligned with the backing implementation
19890        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19891Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19892        functor.apply(parser, userId);
19893    }
19894
19895    private interface BlobXmlRestorer {
19896        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19897    }
19898
19899    /**
19900     * Non-Binder method, support for the backup/restore mechanism: write the
19901     * full set of preferred activities in its canonical XML format.  Returns the
19902     * XML output as a byte array, or null if there is none.
19903     */
19904    @Override
19905    public byte[] getPreferredActivityBackup(int userId) {
19906        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19907            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19908        }
19909
19910        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19911        try {
19912            final XmlSerializer serializer = new FastXmlSerializer();
19913            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19914            serializer.startDocument(null, true);
19915            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19916
19917            synchronized (mPackages) {
19918                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19919            }
19920
19921            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19922            serializer.endDocument();
19923            serializer.flush();
19924        } catch (Exception e) {
19925            if (DEBUG_BACKUP) {
19926                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19927            }
19928            return null;
19929        }
19930
19931        return dataStream.toByteArray();
19932    }
19933
19934    @Override
19935    public void restorePreferredActivities(byte[] backup, int userId) {
19936        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19937            throw new SecurityException("Only the system may call restorePreferredActivities()");
19938        }
19939
19940        try {
19941            final XmlPullParser parser = Xml.newPullParser();
19942            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19943            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19944                    new BlobXmlRestorer() {
19945                        @Override
19946                        public void apply(XmlPullParser parser, int userId)
19947                                throws XmlPullParserException, IOException {
19948                            synchronized (mPackages) {
19949                                mSettings.readPreferredActivitiesLPw(parser, userId);
19950                            }
19951                        }
19952                    } );
19953        } catch (Exception e) {
19954            if (DEBUG_BACKUP) {
19955                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19956            }
19957        }
19958    }
19959
19960    /**
19961     * Non-Binder method, support for the backup/restore mechanism: write the
19962     * default browser (etc) settings in its canonical XML format.  Returns the default
19963     * browser XML representation as a byte array, or null if there is none.
19964     */
19965    @Override
19966    public byte[] getDefaultAppsBackup(int userId) {
19967        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19968            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19969        }
19970
19971        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19972        try {
19973            final XmlSerializer serializer = new FastXmlSerializer();
19974            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19975            serializer.startDocument(null, true);
19976            serializer.startTag(null, TAG_DEFAULT_APPS);
19977
19978            synchronized (mPackages) {
19979                mSettings.writeDefaultAppsLPr(serializer, userId);
19980            }
19981
19982            serializer.endTag(null, TAG_DEFAULT_APPS);
19983            serializer.endDocument();
19984            serializer.flush();
19985        } catch (Exception e) {
19986            if (DEBUG_BACKUP) {
19987                Slog.e(TAG, "Unable to write default apps for backup", e);
19988            }
19989            return null;
19990        }
19991
19992        return dataStream.toByteArray();
19993    }
19994
19995    @Override
19996    public void restoreDefaultApps(byte[] backup, int userId) {
19997        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19998            throw new SecurityException("Only the system may call restoreDefaultApps()");
19999        }
20000
20001        try {
20002            final XmlPullParser parser = Xml.newPullParser();
20003            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20004            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20005                    new BlobXmlRestorer() {
20006                        @Override
20007                        public void apply(XmlPullParser parser, int userId)
20008                                throws XmlPullParserException, IOException {
20009                            synchronized (mPackages) {
20010                                mSettings.readDefaultAppsLPw(parser, userId);
20011                            }
20012                        }
20013                    } );
20014        } catch (Exception e) {
20015            if (DEBUG_BACKUP) {
20016                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20017            }
20018        }
20019    }
20020
20021    @Override
20022    public byte[] getIntentFilterVerificationBackup(int userId) {
20023        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20024            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20025        }
20026
20027        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20028        try {
20029            final XmlSerializer serializer = new FastXmlSerializer();
20030            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20031            serializer.startDocument(null, true);
20032            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20033
20034            synchronized (mPackages) {
20035                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20036            }
20037
20038            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20039            serializer.endDocument();
20040            serializer.flush();
20041        } catch (Exception e) {
20042            if (DEBUG_BACKUP) {
20043                Slog.e(TAG, "Unable to write default apps for backup", e);
20044            }
20045            return null;
20046        }
20047
20048        return dataStream.toByteArray();
20049    }
20050
20051    @Override
20052    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20053        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20054            throw new SecurityException("Only the system may call restorePreferredActivities()");
20055        }
20056
20057        try {
20058            final XmlPullParser parser = Xml.newPullParser();
20059            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20060            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20061                    new BlobXmlRestorer() {
20062                        @Override
20063                        public void apply(XmlPullParser parser, int userId)
20064                                throws XmlPullParserException, IOException {
20065                            synchronized (mPackages) {
20066                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20067                                mSettings.writeLPr();
20068                            }
20069                        }
20070                    } );
20071        } catch (Exception e) {
20072            if (DEBUG_BACKUP) {
20073                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20074            }
20075        }
20076    }
20077
20078    @Override
20079    public byte[] getPermissionGrantBackup(int userId) {
20080        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20081            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20082        }
20083
20084        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20085        try {
20086            final XmlSerializer serializer = new FastXmlSerializer();
20087            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20088            serializer.startDocument(null, true);
20089            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20090
20091            synchronized (mPackages) {
20092                serializeRuntimePermissionGrantsLPr(serializer, userId);
20093            }
20094
20095            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20096            serializer.endDocument();
20097            serializer.flush();
20098        } catch (Exception e) {
20099            if (DEBUG_BACKUP) {
20100                Slog.e(TAG, "Unable to write default apps for backup", e);
20101            }
20102            return null;
20103        }
20104
20105        return dataStream.toByteArray();
20106    }
20107
20108    @Override
20109    public void restorePermissionGrants(byte[] backup, int userId) {
20110        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20111            throw new SecurityException("Only the system may call restorePermissionGrants()");
20112        }
20113
20114        try {
20115            final XmlPullParser parser = Xml.newPullParser();
20116            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20117            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20118                    new BlobXmlRestorer() {
20119                        @Override
20120                        public void apply(XmlPullParser parser, int userId)
20121                                throws XmlPullParserException, IOException {
20122                            synchronized (mPackages) {
20123                                processRestoredPermissionGrantsLPr(parser, userId);
20124                            }
20125                        }
20126                    } );
20127        } catch (Exception e) {
20128            if (DEBUG_BACKUP) {
20129                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20130            }
20131        }
20132    }
20133
20134    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20135            throws IOException {
20136        serializer.startTag(null, TAG_ALL_GRANTS);
20137
20138        final int N = mSettings.mPackages.size();
20139        for (int i = 0; i < N; i++) {
20140            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20141            boolean pkgGrantsKnown = false;
20142
20143            PermissionsState packagePerms = ps.getPermissionsState();
20144
20145            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20146                final int grantFlags = state.getFlags();
20147                // only look at grants that are not system/policy fixed
20148                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20149                    final boolean isGranted = state.isGranted();
20150                    // And only back up the user-twiddled state bits
20151                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20152                        final String packageName = mSettings.mPackages.keyAt(i);
20153                        if (!pkgGrantsKnown) {
20154                            serializer.startTag(null, TAG_GRANT);
20155                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20156                            pkgGrantsKnown = true;
20157                        }
20158
20159                        final boolean userSet =
20160                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20161                        final boolean userFixed =
20162                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20163                        final boolean revoke =
20164                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20165
20166                        serializer.startTag(null, TAG_PERMISSION);
20167                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20168                        if (isGranted) {
20169                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20170                        }
20171                        if (userSet) {
20172                            serializer.attribute(null, ATTR_USER_SET, "true");
20173                        }
20174                        if (userFixed) {
20175                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20176                        }
20177                        if (revoke) {
20178                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20179                        }
20180                        serializer.endTag(null, TAG_PERMISSION);
20181                    }
20182                }
20183            }
20184
20185            if (pkgGrantsKnown) {
20186                serializer.endTag(null, TAG_GRANT);
20187            }
20188        }
20189
20190        serializer.endTag(null, TAG_ALL_GRANTS);
20191    }
20192
20193    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20194            throws XmlPullParserException, IOException {
20195        String pkgName = null;
20196        int outerDepth = parser.getDepth();
20197        int type;
20198        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20199                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20200            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20201                continue;
20202            }
20203
20204            final String tagName = parser.getName();
20205            if (tagName.equals(TAG_GRANT)) {
20206                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20207                if (DEBUG_BACKUP) {
20208                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20209                }
20210            } else if (tagName.equals(TAG_PERMISSION)) {
20211
20212                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20213                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20214
20215                int newFlagSet = 0;
20216                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20217                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20218                }
20219                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20220                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20221                }
20222                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20223                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20224                }
20225                if (DEBUG_BACKUP) {
20226                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20227                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20228                }
20229                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20230                if (ps != null) {
20231                    // Already installed so we apply the grant immediately
20232                    if (DEBUG_BACKUP) {
20233                        Slog.v(TAG, "        + already installed; applying");
20234                    }
20235                    PermissionsState perms = ps.getPermissionsState();
20236                    BasePermission bp = mSettings.mPermissions.get(permName);
20237                    if (bp != null) {
20238                        if (isGranted) {
20239                            perms.grantRuntimePermission(bp, userId);
20240                        }
20241                        if (newFlagSet != 0) {
20242                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20243                        }
20244                    }
20245                } else {
20246                    // Need to wait for post-restore install to apply the grant
20247                    if (DEBUG_BACKUP) {
20248                        Slog.v(TAG, "        - not yet installed; saving for later");
20249                    }
20250                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20251                            isGranted, newFlagSet, userId);
20252                }
20253            } else {
20254                PackageManagerService.reportSettingsProblem(Log.WARN,
20255                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20256                XmlUtils.skipCurrentTag(parser);
20257            }
20258        }
20259
20260        scheduleWriteSettingsLocked();
20261        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20262    }
20263
20264    @Override
20265    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20266            int sourceUserId, int targetUserId, int flags) {
20267        mContext.enforceCallingOrSelfPermission(
20268                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20269        int callingUid = Binder.getCallingUid();
20270        enforceOwnerRights(ownerPackage, callingUid);
20271        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20272        if (intentFilter.countActions() == 0) {
20273            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20274            return;
20275        }
20276        synchronized (mPackages) {
20277            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20278                    ownerPackage, targetUserId, flags);
20279            CrossProfileIntentResolver resolver =
20280                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20281            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20282            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20283            if (existing != null) {
20284                int size = existing.size();
20285                for (int i = 0; i < size; i++) {
20286                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20287                        return;
20288                    }
20289                }
20290            }
20291            resolver.addFilter(newFilter);
20292            scheduleWritePackageRestrictionsLocked(sourceUserId);
20293        }
20294    }
20295
20296    @Override
20297    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20298        mContext.enforceCallingOrSelfPermission(
20299                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20300        int callingUid = Binder.getCallingUid();
20301        enforceOwnerRights(ownerPackage, callingUid);
20302        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20303        synchronized (mPackages) {
20304            CrossProfileIntentResolver resolver =
20305                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20306            ArraySet<CrossProfileIntentFilter> set =
20307                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20308            for (CrossProfileIntentFilter filter : set) {
20309                if (filter.getOwnerPackage().equals(ownerPackage)) {
20310                    resolver.removeFilter(filter);
20311                }
20312            }
20313            scheduleWritePackageRestrictionsLocked(sourceUserId);
20314        }
20315    }
20316
20317    // Enforcing that callingUid is owning pkg on userId
20318    private void enforceOwnerRights(String pkg, int callingUid) {
20319        // The system owns everything.
20320        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20321            return;
20322        }
20323        int callingUserId = UserHandle.getUserId(callingUid);
20324        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20325        if (pi == null) {
20326            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20327                    + callingUserId);
20328        }
20329        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20330            throw new SecurityException("Calling uid " + callingUid
20331                    + " does not own package " + pkg);
20332        }
20333    }
20334
20335    @Override
20336    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20337        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20338    }
20339
20340    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20341        UserManagerService ums = UserManagerService.getInstance();
20342        if (ums != null) {
20343            final UserInfo parent = ums.getProfileParent(userId);
20344            final int launcherUid = (parent != null) ? parent.id : userId;
20345            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20346            if (launcherComponent != null) {
20347                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20348                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20349                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20350                        .setPackage(launcherComponent.getPackageName());
20351                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20352            }
20353        }
20354    }
20355
20356    /**
20357     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20358     * then reports the most likely home activity or null if there are more than one.
20359     */
20360    private ComponentName getDefaultHomeActivity(int userId) {
20361        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20362        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20363        if (cn != null) {
20364            return cn;
20365        }
20366
20367        // Find the launcher with the highest priority and return that component if there are no
20368        // other home activity with the same priority.
20369        int lastPriority = Integer.MIN_VALUE;
20370        ComponentName lastComponent = null;
20371        final int size = allHomeCandidates.size();
20372        for (int i = 0; i < size; i++) {
20373            final ResolveInfo ri = allHomeCandidates.get(i);
20374            if (ri.priority > lastPriority) {
20375                lastComponent = ri.activityInfo.getComponentName();
20376                lastPriority = ri.priority;
20377            } else if (ri.priority == lastPriority) {
20378                // Two components found with same priority.
20379                lastComponent = null;
20380            }
20381        }
20382        return lastComponent;
20383    }
20384
20385    private Intent getHomeIntent() {
20386        Intent intent = new Intent(Intent.ACTION_MAIN);
20387        intent.addCategory(Intent.CATEGORY_HOME);
20388        intent.addCategory(Intent.CATEGORY_DEFAULT);
20389        return intent;
20390    }
20391
20392    private IntentFilter getHomeFilter() {
20393        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20394        filter.addCategory(Intent.CATEGORY_HOME);
20395        filter.addCategory(Intent.CATEGORY_DEFAULT);
20396        return filter;
20397    }
20398
20399    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20400            int userId) {
20401        Intent intent  = getHomeIntent();
20402        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20403                PackageManager.GET_META_DATA, userId);
20404        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20405                true, false, false, userId);
20406
20407        allHomeCandidates.clear();
20408        if (list != null) {
20409            for (ResolveInfo ri : list) {
20410                allHomeCandidates.add(ri);
20411            }
20412        }
20413        return (preferred == null || preferred.activityInfo == null)
20414                ? null
20415                : new ComponentName(preferred.activityInfo.packageName,
20416                        preferred.activityInfo.name);
20417    }
20418
20419    @Override
20420    public void setHomeActivity(ComponentName comp, int userId) {
20421        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20422        getHomeActivitiesAsUser(homeActivities, userId);
20423
20424        boolean found = false;
20425
20426        final int size = homeActivities.size();
20427        final ComponentName[] set = new ComponentName[size];
20428        for (int i = 0; i < size; i++) {
20429            final ResolveInfo candidate = homeActivities.get(i);
20430            final ActivityInfo info = candidate.activityInfo;
20431            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20432            set[i] = activityName;
20433            if (!found && activityName.equals(comp)) {
20434                found = true;
20435            }
20436        }
20437        if (!found) {
20438            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20439                    + userId);
20440        }
20441        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20442                set, comp, userId);
20443    }
20444
20445    private @Nullable String getSetupWizardPackageName() {
20446        final Intent intent = new Intent(Intent.ACTION_MAIN);
20447        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20448
20449        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20450                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20451                        | MATCH_DISABLED_COMPONENTS,
20452                UserHandle.myUserId());
20453        if (matches.size() == 1) {
20454            return matches.get(0).getComponentInfo().packageName;
20455        } else {
20456            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20457                    + ": matches=" + matches);
20458            return null;
20459        }
20460    }
20461
20462    private @Nullable String getStorageManagerPackageName() {
20463        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20464
20465        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20466                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20467                        | MATCH_DISABLED_COMPONENTS,
20468                UserHandle.myUserId());
20469        if (matches.size() == 1) {
20470            return matches.get(0).getComponentInfo().packageName;
20471        } else {
20472            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20473                    + matches.size() + ": matches=" + matches);
20474            return null;
20475        }
20476    }
20477
20478    @Override
20479    public void setApplicationEnabledSetting(String appPackageName,
20480            int newState, int flags, int userId, String callingPackage) {
20481        if (!sUserManager.exists(userId)) return;
20482        if (callingPackage == null) {
20483            callingPackage = Integer.toString(Binder.getCallingUid());
20484        }
20485        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20486    }
20487
20488    @Override
20489    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20490        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20491        synchronized (mPackages) {
20492            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20493            if (pkgSetting != null) {
20494                pkgSetting.setUpdateAvailable(updateAvailable);
20495            }
20496        }
20497    }
20498
20499    @Override
20500    public void setComponentEnabledSetting(ComponentName componentName,
20501            int newState, int flags, int userId) {
20502        if (!sUserManager.exists(userId)) return;
20503        setEnabledSetting(componentName.getPackageName(),
20504                componentName.getClassName(), newState, flags, userId, null);
20505    }
20506
20507    private void setEnabledSetting(final String packageName, String className, int newState,
20508            final int flags, int userId, String callingPackage) {
20509        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20510              || newState == COMPONENT_ENABLED_STATE_ENABLED
20511              || newState == COMPONENT_ENABLED_STATE_DISABLED
20512              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20513              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20514            throw new IllegalArgumentException("Invalid new component state: "
20515                    + newState);
20516        }
20517        PackageSetting pkgSetting;
20518        final int uid = Binder.getCallingUid();
20519        final int permission;
20520        if (uid == Process.SYSTEM_UID) {
20521            permission = PackageManager.PERMISSION_GRANTED;
20522        } else {
20523            permission = mContext.checkCallingOrSelfPermission(
20524                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20525        }
20526        enforceCrossUserPermission(uid, userId,
20527                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20528        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20529        boolean sendNow = false;
20530        boolean isApp = (className == null);
20531        String componentName = isApp ? packageName : className;
20532        int packageUid = -1;
20533        ArrayList<String> components;
20534
20535        // writer
20536        synchronized (mPackages) {
20537            pkgSetting = mSettings.mPackages.get(packageName);
20538            if (pkgSetting == null) {
20539                if (className == null) {
20540                    throw new IllegalArgumentException("Unknown package: " + packageName);
20541                }
20542                throw new IllegalArgumentException(
20543                        "Unknown component: " + packageName + "/" + className);
20544            }
20545        }
20546
20547        // Limit who can change which apps
20548        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20549            // Don't allow apps that don't have permission to modify other apps
20550            if (!allowedByPermission) {
20551                throw new SecurityException(
20552                        "Permission Denial: attempt to change component state from pid="
20553                        + Binder.getCallingPid()
20554                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20555            }
20556            // Don't allow changing protected packages.
20557            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20558                throw new SecurityException("Cannot disable a protected package: " + packageName);
20559            }
20560        }
20561
20562        synchronized (mPackages) {
20563            if (uid == Process.SHELL_UID
20564                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20565                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20566                // unless it is a test package.
20567                int oldState = pkgSetting.getEnabled(userId);
20568                if (className == null
20569                    &&
20570                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20571                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20572                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20573                    &&
20574                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20575                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20576                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20577                    // ok
20578                } else {
20579                    throw new SecurityException(
20580                            "Shell cannot change component state for " + packageName + "/"
20581                            + className + " to " + newState);
20582                }
20583            }
20584            if (className == null) {
20585                // We're dealing with an application/package level state change
20586                if (pkgSetting.getEnabled(userId) == newState) {
20587                    // Nothing to do
20588                    return;
20589                }
20590                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20591                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20592                    // Don't care about who enables an app.
20593                    callingPackage = null;
20594                }
20595                pkgSetting.setEnabled(newState, userId, callingPackage);
20596                // pkgSetting.pkg.mSetEnabled = newState;
20597            } else {
20598                // We're dealing with a component level state change
20599                // First, verify that this is a valid class name.
20600                PackageParser.Package pkg = pkgSetting.pkg;
20601                if (pkg == null || !pkg.hasComponentClassName(className)) {
20602                    if (pkg != null &&
20603                            pkg.applicationInfo.targetSdkVersion >=
20604                                    Build.VERSION_CODES.JELLY_BEAN) {
20605                        throw new IllegalArgumentException("Component class " + className
20606                                + " does not exist in " + packageName);
20607                    } else {
20608                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20609                                + className + " does not exist in " + packageName);
20610                    }
20611                }
20612                switch (newState) {
20613                case COMPONENT_ENABLED_STATE_ENABLED:
20614                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20615                        return;
20616                    }
20617                    break;
20618                case COMPONENT_ENABLED_STATE_DISABLED:
20619                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20620                        return;
20621                    }
20622                    break;
20623                case COMPONENT_ENABLED_STATE_DEFAULT:
20624                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20625                        return;
20626                    }
20627                    break;
20628                default:
20629                    Slog.e(TAG, "Invalid new component state: " + newState);
20630                    return;
20631                }
20632            }
20633            scheduleWritePackageRestrictionsLocked(userId);
20634            updateSequenceNumberLP(packageName, new int[] { userId });
20635            final long callingId = Binder.clearCallingIdentity();
20636            try {
20637                updateInstantAppInstallerLocked(packageName);
20638            } finally {
20639                Binder.restoreCallingIdentity(callingId);
20640            }
20641            components = mPendingBroadcasts.get(userId, packageName);
20642            final boolean newPackage = components == null;
20643            if (newPackage) {
20644                components = new ArrayList<String>();
20645            }
20646            if (!components.contains(componentName)) {
20647                components.add(componentName);
20648            }
20649            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20650                sendNow = true;
20651                // Purge entry from pending broadcast list if another one exists already
20652                // since we are sending one right away.
20653                mPendingBroadcasts.remove(userId, packageName);
20654            } else {
20655                if (newPackage) {
20656                    mPendingBroadcasts.put(userId, packageName, components);
20657                }
20658                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20659                    // Schedule a message
20660                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20661                }
20662            }
20663        }
20664
20665        long callingId = Binder.clearCallingIdentity();
20666        try {
20667            if (sendNow) {
20668                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20669                sendPackageChangedBroadcast(packageName,
20670                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20671            }
20672        } finally {
20673            Binder.restoreCallingIdentity(callingId);
20674        }
20675    }
20676
20677    @Override
20678    public void flushPackageRestrictionsAsUser(int userId) {
20679        if (!sUserManager.exists(userId)) {
20680            return;
20681        }
20682        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20683                false /* checkShell */, "flushPackageRestrictions");
20684        synchronized (mPackages) {
20685            mSettings.writePackageRestrictionsLPr(userId);
20686            mDirtyUsers.remove(userId);
20687            if (mDirtyUsers.isEmpty()) {
20688                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20689            }
20690        }
20691    }
20692
20693    private void sendPackageChangedBroadcast(String packageName,
20694            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20695        if (DEBUG_INSTALL)
20696            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20697                    + componentNames);
20698        Bundle extras = new Bundle(4);
20699        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20700        String nameList[] = new String[componentNames.size()];
20701        componentNames.toArray(nameList);
20702        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20703        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20704        extras.putInt(Intent.EXTRA_UID, packageUid);
20705        // If this is not reporting a change of the overall package, then only send it
20706        // to registered receivers.  We don't want to launch a swath of apps for every
20707        // little component state change.
20708        final int flags = !componentNames.contains(packageName)
20709                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20710        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20711                new int[] {UserHandle.getUserId(packageUid)});
20712    }
20713
20714    @Override
20715    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20716        if (!sUserManager.exists(userId)) return;
20717        final int uid = Binder.getCallingUid();
20718        final int permission = mContext.checkCallingOrSelfPermission(
20719                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20720        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20721        enforceCrossUserPermission(uid, userId,
20722                true /* requireFullPermission */, true /* checkShell */, "stop package");
20723        // writer
20724        synchronized (mPackages) {
20725            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20726                    allowedByPermission, uid, userId)) {
20727                scheduleWritePackageRestrictionsLocked(userId);
20728            }
20729        }
20730    }
20731
20732    @Override
20733    public String getInstallerPackageName(String packageName) {
20734        // reader
20735        synchronized (mPackages) {
20736            return mSettings.getInstallerPackageNameLPr(packageName);
20737        }
20738    }
20739
20740    public boolean isOrphaned(String packageName) {
20741        // reader
20742        synchronized (mPackages) {
20743            return mSettings.isOrphaned(packageName);
20744        }
20745    }
20746
20747    @Override
20748    public int getApplicationEnabledSetting(String packageName, int userId) {
20749        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20750        int uid = Binder.getCallingUid();
20751        enforceCrossUserPermission(uid, userId,
20752                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20753        // reader
20754        synchronized (mPackages) {
20755            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20756        }
20757    }
20758
20759    @Override
20760    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20761        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20762        int uid = Binder.getCallingUid();
20763        enforceCrossUserPermission(uid, userId,
20764                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20765        // reader
20766        synchronized (mPackages) {
20767            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20768        }
20769    }
20770
20771    @Override
20772    public void enterSafeMode() {
20773        enforceSystemOrRoot("Only the system can request entering safe mode");
20774
20775        if (!mSystemReady) {
20776            mSafeMode = true;
20777        }
20778    }
20779
20780    @Override
20781    public void systemReady() {
20782        mSystemReady = true;
20783        final ContentResolver resolver = mContext.getContentResolver();
20784        ContentObserver co = new ContentObserver(mHandler) {
20785            @Override
20786            public void onChange(boolean selfChange) {
20787                mEphemeralAppsDisabled =
20788                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20789                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20790            }
20791        };
20792        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20793                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20794                false, co, UserHandle.USER_SYSTEM);
20795        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20796                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20797        co.onChange(true);
20798
20799        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20800        // disabled after already being started.
20801        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20802                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20803
20804        // Read the compatibilty setting when the system is ready.
20805        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20806                mContext.getContentResolver(),
20807                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20808        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20809        if (DEBUG_SETTINGS) {
20810            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20811        }
20812
20813        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20814
20815        synchronized (mPackages) {
20816            // Verify that all of the preferred activity components actually
20817            // exist.  It is possible for applications to be updated and at
20818            // that point remove a previously declared activity component that
20819            // had been set as a preferred activity.  We try to clean this up
20820            // the next time we encounter that preferred activity, but it is
20821            // possible for the user flow to never be able to return to that
20822            // situation so here we do a sanity check to make sure we haven't
20823            // left any junk around.
20824            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20825            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20826                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20827                removed.clear();
20828                for (PreferredActivity pa : pir.filterSet()) {
20829                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20830                        removed.add(pa);
20831                    }
20832                }
20833                if (removed.size() > 0) {
20834                    for (int r=0; r<removed.size(); r++) {
20835                        PreferredActivity pa = removed.get(r);
20836                        Slog.w(TAG, "Removing dangling preferred activity: "
20837                                + pa.mPref.mComponent);
20838                        pir.removeFilter(pa);
20839                    }
20840                    mSettings.writePackageRestrictionsLPr(
20841                            mSettings.mPreferredActivities.keyAt(i));
20842                }
20843            }
20844
20845            for (int userId : UserManagerService.getInstance().getUserIds()) {
20846                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20847                    grantPermissionsUserIds = ArrayUtils.appendInt(
20848                            grantPermissionsUserIds, userId);
20849                }
20850            }
20851        }
20852        sUserManager.systemReady();
20853
20854        // If we upgraded grant all default permissions before kicking off.
20855        for (int userId : grantPermissionsUserIds) {
20856            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20857        }
20858
20859        // If we did not grant default permissions, we preload from this the
20860        // default permission exceptions lazily to ensure we don't hit the
20861        // disk on a new user creation.
20862        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20863            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20864        }
20865
20866        // Kick off any messages waiting for system ready
20867        if (mPostSystemReadyMessages != null) {
20868            for (Message msg : mPostSystemReadyMessages) {
20869                msg.sendToTarget();
20870            }
20871            mPostSystemReadyMessages = null;
20872        }
20873
20874        // Watch for external volumes that come and go over time
20875        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20876        storage.registerListener(mStorageListener);
20877
20878        mInstallerService.systemReady();
20879        mPackageDexOptimizer.systemReady();
20880
20881        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20882                StorageManagerInternal.class);
20883        StorageManagerInternal.addExternalStoragePolicy(
20884                new StorageManagerInternal.ExternalStorageMountPolicy() {
20885            @Override
20886            public int getMountMode(int uid, String packageName) {
20887                if (Process.isIsolated(uid)) {
20888                    return Zygote.MOUNT_EXTERNAL_NONE;
20889                }
20890                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20891                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20892                }
20893                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20894                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20895                }
20896                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20897                    return Zygote.MOUNT_EXTERNAL_READ;
20898                }
20899                return Zygote.MOUNT_EXTERNAL_WRITE;
20900            }
20901
20902            @Override
20903            public boolean hasExternalStorage(int uid, String packageName) {
20904                return true;
20905            }
20906        });
20907
20908        // Now that we're mostly running, clean up stale users and apps
20909        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20910        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20911
20912        if (mPrivappPermissionsViolations != null) {
20913            Slog.wtf(TAG,"Signature|privileged permissions not in "
20914                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20915            mPrivappPermissionsViolations = null;
20916        }
20917    }
20918
20919    public void waitForAppDataPrepared() {
20920        if (mPrepareAppDataFuture == null) {
20921            return;
20922        }
20923        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20924        mPrepareAppDataFuture = null;
20925    }
20926
20927    @Override
20928    public boolean isSafeMode() {
20929        return mSafeMode;
20930    }
20931
20932    @Override
20933    public boolean hasSystemUidErrors() {
20934        return mHasSystemUidErrors;
20935    }
20936
20937    static String arrayToString(int[] array) {
20938        StringBuffer buf = new StringBuffer(128);
20939        buf.append('[');
20940        if (array != null) {
20941            for (int i=0; i<array.length; i++) {
20942                if (i > 0) buf.append(", ");
20943                buf.append(array[i]);
20944            }
20945        }
20946        buf.append(']');
20947        return buf.toString();
20948    }
20949
20950    static class DumpState {
20951        public static final int DUMP_LIBS = 1 << 0;
20952        public static final int DUMP_FEATURES = 1 << 1;
20953        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20954        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20955        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20956        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20957        public static final int DUMP_PERMISSIONS = 1 << 6;
20958        public static final int DUMP_PACKAGES = 1 << 7;
20959        public static final int DUMP_SHARED_USERS = 1 << 8;
20960        public static final int DUMP_MESSAGES = 1 << 9;
20961        public static final int DUMP_PROVIDERS = 1 << 10;
20962        public static final int DUMP_VERIFIERS = 1 << 11;
20963        public static final int DUMP_PREFERRED = 1 << 12;
20964        public static final int DUMP_PREFERRED_XML = 1 << 13;
20965        public static final int DUMP_KEYSETS = 1 << 14;
20966        public static final int DUMP_VERSION = 1 << 15;
20967        public static final int DUMP_INSTALLS = 1 << 16;
20968        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20969        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20970        public static final int DUMP_FROZEN = 1 << 19;
20971        public static final int DUMP_DEXOPT = 1 << 20;
20972        public static final int DUMP_COMPILER_STATS = 1 << 21;
20973        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20974        public static final int DUMP_CHANGES = 1 << 23;
20975
20976        public static final int OPTION_SHOW_FILTERS = 1 << 0;
20977
20978        private int mTypes;
20979
20980        private int mOptions;
20981
20982        private boolean mTitlePrinted;
20983
20984        private SharedUserSetting mSharedUser;
20985
20986        public boolean isDumping(int type) {
20987            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20988                return true;
20989            }
20990
20991            return (mTypes & type) != 0;
20992        }
20993
20994        public void setDump(int type) {
20995            mTypes |= type;
20996        }
20997
20998        public boolean isOptionEnabled(int option) {
20999            return (mOptions & option) != 0;
21000        }
21001
21002        public void setOptionEnabled(int option) {
21003            mOptions |= option;
21004        }
21005
21006        public boolean onTitlePrinted() {
21007            final boolean printed = mTitlePrinted;
21008            mTitlePrinted = true;
21009            return printed;
21010        }
21011
21012        public boolean getTitlePrinted() {
21013            return mTitlePrinted;
21014        }
21015
21016        public void setTitlePrinted(boolean enabled) {
21017            mTitlePrinted = enabled;
21018        }
21019
21020        public SharedUserSetting getSharedUser() {
21021            return mSharedUser;
21022        }
21023
21024        public void setSharedUser(SharedUserSetting user) {
21025            mSharedUser = user;
21026        }
21027    }
21028
21029    @Override
21030    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21031            FileDescriptor err, String[] args, ShellCallback callback,
21032            ResultReceiver resultReceiver) {
21033        (new PackageManagerShellCommand(this)).exec(
21034                this, in, out, err, args, callback, resultReceiver);
21035    }
21036
21037    @Override
21038    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21039        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21040
21041        DumpState dumpState = new DumpState();
21042        boolean fullPreferred = false;
21043        boolean checkin = false;
21044
21045        String packageName = null;
21046        ArraySet<String> permissionNames = null;
21047
21048        int opti = 0;
21049        while (opti < args.length) {
21050            String opt = args[opti];
21051            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21052                break;
21053            }
21054            opti++;
21055
21056            if ("-a".equals(opt)) {
21057                // Right now we only know how to print all.
21058            } else if ("-h".equals(opt)) {
21059                pw.println("Package manager dump options:");
21060                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21061                pw.println("    --checkin: dump for a checkin");
21062                pw.println("    -f: print details of intent filters");
21063                pw.println("    -h: print this help");
21064                pw.println("  cmd may be one of:");
21065                pw.println("    l[ibraries]: list known shared libraries");
21066                pw.println("    f[eatures]: list device features");
21067                pw.println("    k[eysets]: print known keysets");
21068                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21069                pw.println("    perm[issions]: dump permissions");
21070                pw.println("    permission [name ...]: dump declaration and use of given permission");
21071                pw.println("    pref[erred]: print preferred package settings");
21072                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21073                pw.println("    prov[iders]: dump content providers");
21074                pw.println("    p[ackages]: dump installed packages");
21075                pw.println("    s[hared-users]: dump shared user IDs");
21076                pw.println("    m[essages]: print collected runtime messages");
21077                pw.println("    v[erifiers]: print package verifier info");
21078                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21079                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21080                pw.println("    version: print database version info");
21081                pw.println("    write: write current settings now");
21082                pw.println("    installs: details about install sessions");
21083                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21084                pw.println("    dexopt: dump dexopt state");
21085                pw.println("    compiler-stats: dump compiler statistics");
21086                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21087                pw.println("    <package.name>: info about given package");
21088                return;
21089            } else if ("--checkin".equals(opt)) {
21090                checkin = true;
21091            } else if ("-f".equals(opt)) {
21092                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21093            } else if ("--proto".equals(opt)) {
21094                dumpProto(fd);
21095                return;
21096            } else {
21097                pw.println("Unknown argument: " + opt + "; use -h for help");
21098            }
21099        }
21100
21101        // Is the caller requesting to dump a particular piece of data?
21102        if (opti < args.length) {
21103            String cmd = args[opti];
21104            opti++;
21105            // Is this a package name?
21106            if ("android".equals(cmd) || cmd.contains(".")) {
21107                packageName = cmd;
21108                // When dumping a single package, we always dump all of its
21109                // filter information since the amount of data will be reasonable.
21110                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21111            } else if ("check-permission".equals(cmd)) {
21112                if (opti >= args.length) {
21113                    pw.println("Error: check-permission missing permission argument");
21114                    return;
21115                }
21116                String perm = args[opti];
21117                opti++;
21118                if (opti >= args.length) {
21119                    pw.println("Error: check-permission missing package argument");
21120                    return;
21121                }
21122
21123                String pkg = args[opti];
21124                opti++;
21125                int user = UserHandle.getUserId(Binder.getCallingUid());
21126                if (opti < args.length) {
21127                    try {
21128                        user = Integer.parseInt(args[opti]);
21129                    } catch (NumberFormatException e) {
21130                        pw.println("Error: check-permission user argument is not a number: "
21131                                + args[opti]);
21132                        return;
21133                    }
21134                }
21135
21136                // Normalize package name to handle renamed packages and static libs
21137                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21138
21139                pw.println(checkPermission(perm, pkg, user));
21140                return;
21141            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21142                dumpState.setDump(DumpState.DUMP_LIBS);
21143            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21144                dumpState.setDump(DumpState.DUMP_FEATURES);
21145            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21146                if (opti >= args.length) {
21147                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21148                            | DumpState.DUMP_SERVICE_RESOLVERS
21149                            | DumpState.DUMP_RECEIVER_RESOLVERS
21150                            | DumpState.DUMP_CONTENT_RESOLVERS);
21151                } else {
21152                    while (opti < args.length) {
21153                        String name = args[opti];
21154                        if ("a".equals(name) || "activity".equals(name)) {
21155                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21156                        } else if ("s".equals(name) || "service".equals(name)) {
21157                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21158                        } else if ("r".equals(name) || "receiver".equals(name)) {
21159                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21160                        } else if ("c".equals(name) || "content".equals(name)) {
21161                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21162                        } else {
21163                            pw.println("Error: unknown resolver table type: " + name);
21164                            return;
21165                        }
21166                        opti++;
21167                    }
21168                }
21169            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21170                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21171            } else if ("permission".equals(cmd)) {
21172                if (opti >= args.length) {
21173                    pw.println("Error: permission requires permission name");
21174                    return;
21175                }
21176                permissionNames = new ArraySet<>();
21177                while (opti < args.length) {
21178                    permissionNames.add(args[opti]);
21179                    opti++;
21180                }
21181                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21182                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21183            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21184                dumpState.setDump(DumpState.DUMP_PREFERRED);
21185            } else if ("preferred-xml".equals(cmd)) {
21186                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21187                if (opti < args.length && "--full".equals(args[opti])) {
21188                    fullPreferred = true;
21189                    opti++;
21190                }
21191            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21192                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21193            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21194                dumpState.setDump(DumpState.DUMP_PACKAGES);
21195            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21196                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21197            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21198                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21199            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21200                dumpState.setDump(DumpState.DUMP_MESSAGES);
21201            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21202                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21203            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21204                    || "intent-filter-verifiers".equals(cmd)) {
21205                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21206            } else if ("version".equals(cmd)) {
21207                dumpState.setDump(DumpState.DUMP_VERSION);
21208            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21209                dumpState.setDump(DumpState.DUMP_KEYSETS);
21210            } else if ("installs".equals(cmd)) {
21211                dumpState.setDump(DumpState.DUMP_INSTALLS);
21212            } else if ("frozen".equals(cmd)) {
21213                dumpState.setDump(DumpState.DUMP_FROZEN);
21214            } else if ("dexopt".equals(cmd)) {
21215                dumpState.setDump(DumpState.DUMP_DEXOPT);
21216            } else if ("compiler-stats".equals(cmd)) {
21217                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21218            } else if ("enabled-overlays".equals(cmd)) {
21219                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
21220            } else if ("changes".equals(cmd)) {
21221                dumpState.setDump(DumpState.DUMP_CHANGES);
21222            } else if ("write".equals(cmd)) {
21223                synchronized (mPackages) {
21224                    mSettings.writeLPr();
21225                    pw.println("Settings written.");
21226                    return;
21227                }
21228            }
21229        }
21230
21231        if (checkin) {
21232            pw.println("vers,1");
21233        }
21234
21235        // reader
21236        synchronized (mPackages) {
21237            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21238                if (!checkin) {
21239                    if (dumpState.onTitlePrinted())
21240                        pw.println();
21241                    pw.println("Database versions:");
21242                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21243                }
21244            }
21245
21246            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21247                if (!checkin) {
21248                    if (dumpState.onTitlePrinted())
21249                        pw.println();
21250                    pw.println("Verifiers:");
21251                    pw.print("  Required: ");
21252                    pw.print(mRequiredVerifierPackage);
21253                    pw.print(" (uid=");
21254                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21255                            UserHandle.USER_SYSTEM));
21256                    pw.println(")");
21257                } else if (mRequiredVerifierPackage != null) {
21258                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21259                    pw.print(",");
21260                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21261                            UserHandle.USER_SYSTEM));
21262                }
21263            }
21264
21265            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21266                    packageName == null) {
21267                if (mIntentFilterVerifierComponent != null) {
21268                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21269                    if (!checkin) {
21270                        if (dumpState.onTitlePrinted())
21271                            pw.println();
21272                        pw.println("Intent Filter Verifier:");
21273                        pw.print("  Using: ");
21274                        pw.print(verifierPackageName);
21275                        pw.print(" (uid=");
21276                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21277                                UserHandle.USER_SYSTEM));
21278                        pw.println(")");
21279                    } else if (verifierPackageName != null) {
21280                        pw.print("ifv,"); pw.print(verifierPackageName);
21281                        pw.print(",");
21282                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21283                                UserHandle.USER_SYSTEM));
21284                    }
21285                } else {
21286                    pw.println();
21287                    pw.println("No Intent Filter Verifier available!");
21288                }
21289            }
21290
21291            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21292                boolean printedHeader = false;
21293                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21294                while (it.hasNext()) {
21295                    String libName = it.next();
21296                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21297                    if (versionedLib == null) {
21298                        continue;
21299                    }
21300                    final int versionCount = versionedLib.size();
21301                    for (int i = 0; i < versionCount; i++) {
21302                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21303                        if (!checkin) {
21304                            if (!printedHeader) {
21305                                if (dumpState.onTitlePrinted())
21306                                    pw.println();
21307                                pw.println("Libraries:");
21308                                printedHeader = true;
21309                            }
21310                            pw.print("  ");
21311                        } else {
21312                            pw.print("lib,");
21313                        }
21314                        pw.print(libEntry.info.getName());
21315                        if (libEntry.info.isStatic()) {
21316                            pw.print(" version=" + libEntry.info.getVersion());
21317                        }
21318                        if (!checkin) {
21319                            pw.print(" -> ");
21320                        }
21321                        if (libEntry.path != null) {
21322                            pw.print(" (jar) ");
21323                            pw.print(libEntry.path);
21324                        } else {
21325                            pw.print(" (apk) ");
21326                            pw.print(libEntry.apk);
21327                        }
21328                        pw.println();
21329                    }
21330                }
21331            }
21332
21333            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21334                if (dumpState.onTitlePrinted())
21335                    pw.println();
21336                if (!checkin) {
21337                    pw.println("Features:");
21338                }
21339
21340                synchronized (mAvailableFeatures) {
21341                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21342                        if (checkin) {
21343                            pw.print("feat,");
21344                            pw.print(feat.name);
21345                            pw.print(",");
21346                            pw.println(feat.version);
21347                        } else {
21348                            pw.print("  ");
21349                            pw.print(feat.name);
21350                            if (feat.version > 0) {
21351                                pw.print(" version=");
21352                                pw.print(feat.version);
21353                            }
21354                            pw.println();
21355                        }
21356                    }
21357                }
21358            }
21359
21360            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21361                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21362                        : "Activity Resolver Table:", "  ", packageName,
21363                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21364                    dumpState.setTitlePrinted(true);
21365                }
21366            }
21367            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21368                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21369                        : "Receiver Resolver Table:", "  ", packageName,
21370                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21371                    dumpState.setTitlePrinted(true);
21372                }
21373            }
21374            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21375                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21376                        : "Service Resolver Table:", "  ", packageName,
21377                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21378                    dumpState.setTitlePrinted(true);
21379                }
21380            }
21381            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21382                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21383                        : "Provider Resolver Table:", "  ", packageName,
21384                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21385                    dumpState.setTitlePrinted(true);
21386                }
21387            }
21388
21389            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21390                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21391                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21392                    int user = mSettings.mPreferredActivities.keyAt(i);
21393                    if (pir.dump(pw,
21394                            dumpState.getTitlePrinted()
21395                                ? "\nPreferred Activities User " + user + ":"
21396                                : "Preferred Activities User " + user + ":", "  ",
21397                            packageName, true, false)) {
21398                        dumpState.setTitlePrinted(true);
21399                    }
21400                }
21401            }
21402
21403            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21404                pw.flush();
21405                FileOutputStream fout = new FileOutputStream(fd);
21406                BufferedOutputStream str = new BufferedOutputStream(fout);
21407                XmlSerializer serializer = new FastXmlSerializer();
21408                try {
21409                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21410                    serializer.startDocument(null, true);
21411                    serializer.setFeature(
21412                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21413                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21414                    serializer.endDocument();
21415                    serializer.flush();
21416                } catch (IllegalArgumentException e) {
21417                    pw.println("Failed writing: " + e);
21418                } catch (IllegalStateException e) {
21419                    pw.println("Failed writing: " + e);
21420                } catch (IOException e) {
21421                    pw.println("Failed writing: " + e);
21422                }
21423            }
21424
21425            if (!checkin
21426                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21427                    && packageName == null) {
21428                pw.println();
21429                int count = mSettings.mPackages.size();
21430                if (count == 0) {
21431                    pw.println("No applications!");
21432                    pw.println();
21433                } else {
21434                    final String prefix = "  ";
21435                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21436                    if (allPackageSettings.size() == 0) {
21437                        pw.println("No domain preferred apps!");
21438                        pw.println();
21439                    } else {
21440                        pw.println("App verification status:");
21441                        pw.println();
21442                        count = 0;
21443                        for (PackageSetting ps : allPackageSettings) {
21444                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21445                            if (ivi == null || ivi.getPackageName() == null) continue;
21446                            pw.println(prefix + "Package: " + ivi.getPackageName());
21447                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21448                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21449                            pw.println();
21450                            count++;
21451                        }
21452                        if (count == 0) {
21453                            pw.println(prefix + "No app verification established.");
21454                            pw.println();
21455                        }
21456                        for (int userId : sUserManager.getUserIds()) {
21457                            pw.println("App linkages for user " + userId + ":");
21458                            pw.println();
21459                            count = 0;
21460                            for (PackageSetting ps : allPackageSettings) {
21461                                final long status = ps.getDomainVerificationStatusForUser(userId);
21462                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21463                                        && !DEBUG_DOMAIN_VERIFICATION) {
21464                                    continue;
21465                                }
21466                                pw.println(prefix + "Package: " + ps.name);
21467                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21468                                String statusStr = IntentFilterVerificationInfo.
21469                                        getStatusStringFromValue(status);
21470                                pw.println(prefix + "Status:  " + statusStr);
21471                                pw.println();
21472                                count++;
21473                            }
21474                            if (count == 0) {
21475                                pw.println(prefix + "No configured app linkages.");
21476                                pw.println();
21477                            }
21478                        }
21479                    }
21480                }
21481            }
21482
21483            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21484                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21485                if (packageName == null && permissionNames == null) {
21486                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21487                        if (iperm == 0) {
21488                            if (dumpState.onTitlePrinted())
21489                                pw.println();
21490                            pw.println("AppOp Permissions:");
21491                        }
21492                        pw.print("  AppOp Permission ");
21493                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21494                        pw.println(":");
21495                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21496                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21497                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21498                        }
21499                    }
21500                }
21501            }
21502
21503            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21504                boolean printedSomething = false;
21505                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21506                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21507                        continue;
21508                    }
21509                    if (!printedSomething) {
21510                        if (dumpState.onTitlePrinted())
21511                            pw.println();
21512                        pw.println("Registered ContentProviders:");
21513                        printedSomething = true;
21514                    }
21515                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21516                    pw.print("    "); pw.println(p.toString());
21517                }
21518                printedSomething = false;
21519                for (Map.Entry<String, PackageParser.Provider> entry :
21520                        mProvidersByAuthority.entrySet()) {
21521                    PackageParser.Provider p = entry.getValue();
21522                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21523                        continue;
21524                    }
21525                    if (!printedSomething) {
21526                        if (dumpState.onTitlePrinted())
21527                            pw.println();
21528                        pw.println("ContentProvider Authorities:");
21529                        printedSomething = true;
21530                    }
21531                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21532                    pw.print("    "); pw.println(p.toString());
21533                    if (p.info != null && p.info.applicationInfo != null) {
21534                        final String appInfo = p.info.applicationInfo.toString();
21535                        pw.print("      applicationInfo="); pw.println(appInfo);
21536                    }
21537                }
21538            }
21539
21540            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21541                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21542            }
21543
21544            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21545                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21546            }
21547
21548            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21549                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21550            }
21551
21552            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21553                if (dumpState.onTitlePrinted()) pw.println();
21554                pw.println("Package Changes:");
21555                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21556                final int K = mChangedPackages.size();
21557                for (int i = 0; i < K; i++) {
21558                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21559                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21560                    final int N = changes.size();
21561                    if (N == 0) {
21562                        pw.print("    "); pw.println("No packages changed");
21563                    } else {
21564                        for (int j = 0; j < N; j++) {
21565                            final String pkgName = changes.valueAt(j);
21566                            final int sequenceNumber = changes.keyAt(j);
21567                            pw.print("    ");
21568                            pw.print("seq=");
21569                            pw.print(sequenceNumber);
21570                            pw.print(", package=");
21571                            pw.println(pkgName);
21572                        }
21573                    }
21574                }
21575            }
21576
21577            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21578                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21579            }
21580
21581            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21582                // XXX should handle packageName != null by dumping only install data that
21583                // the given package is involved with.
21584                if (dumpState.onTitlePrinted()) pw.println();
21585
21586                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21587                ipw.println();
21588                ipw.println("Frozen packages:");
21589                ipw.increaseIndent();
21590                if (mFrozenPackages.size() == 0) {
21591                    ipw.println("(none)");
21592                } else {
21593                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21594                        ipw.println(mFrozenPackages.valueAt(i));
21595                    }
21596                }
21597                ipw.decreaseIndent();
21598            }
21599
21600            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21601                if (dumpState.onTitlePrinted()) pw.println();
21602                dumpDexoptStateLPr(pw, packageName);
21603            }
21604
21605            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21606                if (dumpState.onTitlePrinted()) pw.println();
21607                dumpCompilerStatsLPr(pw, packageName);
21608            }
21609
21610            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21611                if (dumpState.onTitlePrinted()) pw.println();
21612                dumpEnabledOverlaysLPr(pw);
21613            }
21614
21615            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21616                if (dumpState.onTitlePrinted()) pw.println();
21617                mSettings.dumpReadMessagesLPr(pw, dumpState);
21618
21619                pw.println();
21620                pw.println("Package warning messages:");
21621                BufferedReader in = null;
21622                String line = null;
21623                try {
21624                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21625                    while ((line = in.readLine()) != null) {
21626                        if (line.contains("ignored: updated version")) continue;
21627                        pw.println(line);
21628                    }
21629                } catch (IOException ignored) {
21630                } finally {
21631                    IoUtils.closeQuietly(in);
21632                }
21633            }
21634
21635            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21636                BufferedReader in = null;
21637                String line = null;
21638                try {
21639                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21640                    while ((line = in.readLine()) != null) {
21641                        if (line.contains("ignored: updated version")) continue;
21642                        pw.print("msg,");
21643                        pw.println(line);
21644                    }
21645                } catch (IOException ignored) {
21646                } finally {
21647                    IoUtils.closeQuietly(in);
21648                }
21649            }
21650        }
21651
21652        // PackageInstaller should be called outside of mPackages lock
21653        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21654            // XXX should handle packageName != null by dumping only install data that
21655            // the given package is involved with.
21656            if (dumpState.onTitlePrinted()) pw.println();
21657            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21658        }
21659    }
21660
21661    private void dumpProto(FileDescriptor fd) {
21662        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21663
21664        synchronized (mPackages) {
21665            final long requiredVerifierPackageToken =
21666                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21667            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21668            proto.write(
21669                    PackageServiceDumpProto.PackageShortProto.UID,
21670                    getPackageUid(
21671                            mRequiredVerifierPackage,
21672                            MATCH_DEBUG_TRIAGED_MISSING,
21673                            UserHandle.USER_SYSTEM));
21674            proto.end(requiredVerifierPackageToken);
21675
21676            if (mIntentFilterVerifierComponent != null) {
21677                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21678                final long verifierPackageToken =
21679                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21680                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21681                proto.write(
21682                        PackageServiceDumpProto.PackageShortProto.UID,
21683                        getPackageUid(
21684                                verifierPackageName,
21685                                MATCH_DEBUG_TRIAGED_MISSING,
21686                                UserHandle.USER_SYSTEM));
21687                proto.end(verifierPackageToken);
21688            }
21689
21690            dumpSharedLibrariesProto(proto);
21691            dumpFeaturesProto(proto);
21692            mSettings.dumpPackagesProto(proto);
21693            mSettings.dumpSharedUsersProto(proto);
21694            dumpMessagesProto(proto);
21695        }
21696        proto.flush();
21697    }
21698
21699    private void dumpMessagesProto(ProtoOutputStream proto) {
21700        BufferedReader in = null;
21701        String line = null;
21702        try {
21703            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21704            while ((line = in.readLine()) != null) {
21705                if (line.contains("ignored: updated version")) continue;
21706                proto.write(PackageServiceDumpProto.MESSAGES, line);
21707            }
21708        } catch (IOException ignored) {
21709        } finally {
21710            IoUtils.closeQuietly(in);
21711        }
21712    }
21713
21714    private void dumpFeaturesProto(ProtoOutputStream proto) {
21715        synchronized (mAvailableFeatures) {
21716            final int count = mAvailableFeatures.size();
21717            for (int i = 0; i < count; i++) {
21718                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21719                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21720                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21721                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21722                proto.end(featureToken);
21723            }
21724        }
21725    }
21726
21727    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21728        final int count = mSharedLibraries.size();
21729        for (int i = 0; i < count; i++) {
21730            final String libName = mSharedLibraries.keyAt(i);
21731            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21732            if (versionedLib == null) {
21733                continue;
21734            }
21735            final int versionCount = versionedLib.size();
21736            for (int j = 0; j < versionCount; j++) {
21737                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21738                final long sharedLibraryToken =
21739                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21740                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21741                final boolean isJar = (libEntry.path != null);
21742                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21743                if (isJar) {
21744                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21745                } else {
21746                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21747                }
21748                proto.end(sharedLibraryToken);
21749            }
21750        }
21751    }
21752
21753    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21754        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21755        ipw.println();
21756        ipw.println("Dexopt state:");
21757        ipw.increaseIndent();
21758        Collection<PackageParser.Package> packages = null;
21759        if (packageName != null) {
21760            PackageParser.Package targetPackage = mPackages.get(packageName);
21761            if (targetPackage != null) {
21762                packages = Collections.singletonList(targetPackage);
21763            } else {
21764                ipw.println("Unable to find package: " + packageName);
21765                return;
21766            }
21767        } else {
21768            packages = mPackages.values();
21769        }
21770
21771        for (PackageParser.Package pkg : packages) {
21772            ipw.println("[" + pkg.packageName + "]");
21773            ipw.increaseIndent();
21774            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21775            ipw.decreaseIndent();
21776        }
21777    }
21778
21779    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21780        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21781        ipw.println();
21782        ipw.println("Compiler stats:");
21783        ipw.increaseIndent();
21784        Collection<PackageParser.Package> packages = null;
21785        if (packageName != null) {
21786            PackageParser.Package targetPackage = mPackages.get(packageName);
21787            if (targetPackage != null) {
21788                packages = Collections.singletonList(targetPackage);
21789            } else {
21790                ipw.println("Unable to find package: " + packageName);
21791                return;
21792            }
21793        } else {
21794            packages = mPackages.values();
21795        }
21796
21797        for (PackageParser.Package pkg : packages) {
21798            ipw.println("[" + pkg.packageName + "]");
21799            ipw.increaseIndent();
21800
21801            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21802            if (stats == null) {
21803                ipw.println("(No recorded stats)");
21804            } else {
21805                stats.dump(ipw);
21806            }
21807            ipw.decreaseIndent();
21808        }
21809    }
21810
21811    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21812        pw.println("Enabled overlay paths:");
21813        final int N = mEnabledOverlayPaths.size();
21814        for (int i = 0; i < N; i++) {
21815            final int userId = mEnabledOverlayPaths.keyAt(i);
21816            pw.println(String.format("    User %d:", userId));
21817            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21818                mEnabledOverlayPaths.valueAt(i);
21819            final int M = userSpecificOverlays.size();
21820            for (int j = 0; j < M; j++) {
21821                final String targetPackageName = userSpecificOverlays.keyAt(j);
21822                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21823                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21824            }
21825        }
21826    }
21827
21828    private String dumpDomainString(String packageName) {
21829        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21830                .getList();
21831        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21832
21833        ArraySet<String> result = new ArraySet<>();
21834        if (iviList.size() > 0) {
21835            for (IntentFilterVerificationInfo ivi : iviList) {
21836                for (String host : ivi.getDomains()) {
21837                    result.add(host);
21838                }
21839            }
21840        }
21841        if (filters != null && filters.size() > 0) {
21842            for (IntentFilter filter : filters) {
21843                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21844                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21845                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21846                    result.addAll(filter.getHostsList());
21847                }
21848            }
21849        }
21850
21851        StringBuilder sb = new StringBuilder(result.size() * 16);
21852        for (String domain : result) {
21853            if (sb.length() > 0) sb.append(" ");
21854            sb.append(domain);
21855        }
21856        return sb.toString();
21857    }
21858
21859    // ------- apps on sdcard specific code -------
21860    static final boolean DEBUG_SD_INSTALL = false;
21861
21862    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21863
21864    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21865
21866    private boolean mMediaMounted = false;
21867
21868    static String getEncryptKey() {
21869        try {
21870            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21871                    SD_ENCRYPTION_KEYSTORE_NAME);
21872            if (sdEncKey == null) {
21873                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21874                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21875                if (sdEncKey == null) {
21876                    Slog.e(TAG, "Failed to create encryption keys");
21877                    return null;
21878                }
21879            }
21880            return sdEncKey;
21881        } catch (NoSuchAlgorithmException nsae) {
21882            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21883            return null;
21884        } catch (IOException ioe) {
21885            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21886            return null;
21887        }
21888    }
21889
21890    /*
21891     * Update media status on PackageManager.
21892     */
21893    @Override
21894    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21895        int callingUid = Binder.getCallingUid();
21896        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21897            throw new SecurityException("Media status can only be updated by the system");
21898        }
21899        // reader; this apparently protects mMediaMounted, but should probably
21900        // be a different lock in that case.
21901        synchronized (mPackages) {
21902            Log.i(TAG, "Updating external media status from "
21903                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
21904                    + (mediaStatus ? "mounted" : "unmounted"));
21905            if (DEBUG_SD_INSTALL)
21906                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21907                        + ", mMediaMounted=" + mMediaMounted);
21908            if (mediaStatus == mMediaMounted) {
21909                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21910                        : 0, -1);
21911                mHandler.sendMessage(msg);
21912                return;
21913            }
21914            mMediaMounted = mediaStatus;
21915        }
21916        // Queue up an async operation since the package installation may take a
21917        // little while.
21918        mHandler.post(new Runnable() {
21919            public void run() {
21920                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21921            }
21922        });
21923    }
21924
21925    /**
21926     * Called by StorageManagerService when the initial ASECs to scan are available.
21927     * Should block until all the ASEC containers are finished being scanned.
21928     */
21929    public void scanAvailableAsecs() {
21930        updateExternalMediaStatusInner(true, false, false);
21931    }
21932
21933    /*
21934     * Collect information of applications on external media, map them against
21935     * existing containers and update information based on current mount status.
21936     * Please note that we always have to report status if reportStatus has been
21937     * set to true especially when unloading packages.
21938     */
21939    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21940            boolean externalStorage) {
21941        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21942        int[] uidArr = EmptyArray.INT;
21943
21944        final String[] list = PackageHelper.getSecureContainerList();
21945        if (ArrayUtils.isEmpty(list)) {
21946            Log.i(TAG, "No secure containers found");
21947        } else {
21948            // Process list of secure containers and categorize them
21949            // as active or stale based on their package internal state.
21950
21951            // reader
21952            synchronized (mPackages) {
21953                for (String cid : list) {
21954                    // Leave stages untouched for now; installer service owns them
21955                    if (PackageInstallerService.isStageName(cid)) continue;
21956
21957                    if (DEBUG_SD_INSTALL)
21958                        Log.i(TAG, "Processing container " + cid);
21959                    String pkgName = getAsecPackageName(cid);
21960                    if (pkgName == null) {
21961                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
21962                        continue;
21963                    }
21964                    if (DEBUG_SD_INSTALL)
21965                        Log.i(TAG, "Looking for pkg : " + pkgName);
21966
21967                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
21968                    if (ps == null) {
21969                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21970                        continue;
21971                    }
21972
21973                    /*
21974                     * Skip packages that are not external if we're unmounting
21975                     * external storage.
21976                     */
21977                    if (externalStorage && !isMounted && !isExternal(ps)) {
21978                        continue;
21979                    }
21980
21981                    final AsecInstallArgs args = new AsecInstallArgs(cid,
21982                            getAppDexInstructionSets(ps), ps.isForwardLocked());
21983                    // The package status is changed only if the code path
21984                    // matches between settings and the container id.
21985                    if (ps.codePathString != null
21986                            && ps.codePathString.startsWith(args.getCodePath())) {
21987                        if (DEBUG_SD_INSTALL) {
21988                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21989                                    + " at code path: " + ps.codePathString);
21990                        }
21991
21992                        // We do have a valid package installed on sdcard
21993                        processCids.put(args, ps.codePathString);
21994                        final int uid = ps.appId;
21995                        if (uid != -1) {
21996                            uidArr = ArrayUtils.appendInt(uidArr, uid);
21997                        }
21998                    } else {
21999                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
22000                                + ps.codePathString);
22001                    }
22002                }
22003            }
22004
22005            Arrays.sort(uidArr);
22006        }
22007
22008        // Process packages with valid entries.
22009        if (isMounted) {
22010            if (DEBUG_SD_INSTALL)
22011                Log.i(TAG, "Loading packages");
22012            loadMediaPackages(processCids, uidArr, externalStorage);
22013            startCleaningPackages();
22014            mInstallerService.onSecureContainersAvailable();
22015        } else {
22016            if (DEBUG_SD_INSTALL)
22017                Log.i(TAG, "Unloading packages");
22018            unloadMediaPackages(processCids, uidArr, reportStatus);
22019        }
22020    }
22021
22022    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22023            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22024        final int size = infos.size();
22025        final String[] packageNames = new String[size];
22026        final int[] packageUids = new int[size];
22027        for (int i = 0; i < size; i++) {
22028            final ApplicationInfo info = infos.get(i);
22029            packageNames[i] = info.packageName;
22030            packageUids[i] = info.uid;
22031        }
22032        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22033                finishedReceiver);
22034    }
22035
22036    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22037            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22038        sendResourcesChangedBroadcast(mediaStatus, replacing,
22039                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22040    }
22041
22042    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22043            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22044        int size = pkgList.length;
22045        if (size > 0) {
22046            // Send broadcasts here
22047            Bundle extras = new Bundle();
22048            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22049            if (uidArr != null) {
22050                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22051            }
22052            if (replacing) {
22053                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22054            }
22055            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22056                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22057            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
22058        }
22059    }
22060
22061   /*
22062     * Look at potentially valid container ids from processCids If package
22063     * information doesn't match the one on record or package scanning fails,
22064     * the cid is added to list of removeCids. We currently don't delete stale
22065     * containers.
22066     */
22067    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
22068            boolean externalStorage) {
22069        ArrayList<String> pkgList = new ArrayList<String>();
22070        Set<AsecInstallArgs> keys = processCids.keySet();
22071
22072        for (AsecInstallArgs args : keys) {
22073            String codePath = processCids.get(args);
22074            if (DEBUG_SD_INSTALL)
22075                Log.i(TAG, "Loading container : " + args.cid);
22076            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
22077            try {
22078                // Make sure there are no container errors first.
22079                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
22080                    Slog.e(TAG, "Failed to mount cid : " + args.cid
22081                            + " when installing from sdcard");
22082                    continue;
22083                }
22084                // Check code path here.
22085                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
22086                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
22087                            + " does not match one in settings " + codePath);
22088                    continue;
22089                }
22090                // Parse package
22091                int parseFlags = mDefParseFlags;
22092                if (args.isExternalAsec()) {
22093                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
22094                }
22095                if (args.isFwdLocked()) {
22096                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
22097                }
22098
22099                synchronized (mInstallLock) {
22100                    PackageParser.Package pkg = null;
22101                    try {
22102                        // Sadly we don't know the package name yet to freeze it
22103                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
22104                                SCAN_IGNORE_FROZEN, 0, null);
22105                    } catch (PackageManagerException e) {
22106                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
22107                    }
22108                    // Scan the package
22109                    if (pkg != null) {
22110                        /*
22111                         * TODO why is the lock being held? doPostInstall is
22112                         * called in other places without the lock. This needs
22113                         * to be straightened out.
22114                         */
22115                        // writer
22116                        synchronized (mPackages) {
22117                            retCode = PackageManager.INSTALL_SUCCEEDED;
22118                            pkgList.add(pkg.packageName);
22119                            // Post process args
22120                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
22121                                    pkg.applicationInfo.uid);
22122                        }
22123                    } else {
22124                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
22125                    }
22126                }
22127
22128            } finally {
22129                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
22130                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
22131                }
22132            }
22133        }
22134        // writer
22135        synchronized (mPackages) {
22136            // If the platform SDK has changed since the last time we booted,
22137            // we need to re-grant app permission to catch any new ones that
22138            // appear. This is really a hack, and means that apps can in some
22139            // cases get permissions that the user didn't initially explicitly
22140            // allow... it would be nice to have some better way to handle
22141            // this situation.
22142            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
22143                    : mSettings.getInternalVersion();
22144            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
22145                    : StorageManager.UUID_PRIVATE_INTERNAL;
22146
22147            int updateFlags = UPDATE_PERMISSIONS_ALL;
22148            if (ver.sdkVersion != mSdkVersion) {
22149                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22150                        + mSdkVersion + "; regranting permissions for external");
22151                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22152            }
22153            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22154
22155            // Yay, everything is now upgraded
22156            ver.forceCurrent();
22157
22158            // can downgrade to reader
22159            // Persist settings
22160            mSettings.writeLPr();
22161        }
22162        // Send a broadcast to let everyone know we are done processing
22163        if (pkgList.size() > 0) {
22164            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
22165        }
22166    }
22167
22168   /*
22169     * Utility method to unload a list of specified containers
22170     */
22171    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
22172        // Just unmount all valid containers.
22173        for (AsecInstallArgs arg : cidArgs) {
22174            synchronized (mInstallLock) {
22175                arg.doPostDeleteLI(false);
22176           }
22177       }
22178   }
22179
22180    /*
22181     * Unload packages mounted on external media. This involves deleting package
22182     * data from internal structures, sending broadcasts about disabled packages,
22183     * gc'ing to free up references, unmounting all secure containers
22184     * corresponding to packages on external media, and posting a
22185     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
22186     * that we always have to post this message if status has been requested no
22187     * matter what.
22188     */
22189    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
22190            final boolean reportStatus) {
22191        if (DEBUG_SD_INSTALL)
22192            Log.i(TAG, "unloading media packages");
22193        ArrayList<String> pkgList = new ArrayList<String>();
22194        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
22195        final Set<AsecInstallArgs> keys = processCids.keySet();
22196        for (AsecInstallArgs args : keys) {
22197            String pkgName = args.getPackageName();
22198            if (DEBUG_SD_INSTALL)
22199                Log.i(TAG, "Trying to unload pkg : " + pkgName);
22200            // Delete package internally
22201            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22202            synchronized (mInstallLock) {
22203                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22204                final boolean res;
22205                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
22206                        "unloadMediaPackages")) {
22207                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
22208                            null);
22209                }
22210                if (res) {
22211                    pkgList.add(pkgName);
22212                } else {
22213                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
22214                    failedList.add(args);
22215                }
22216            }
22217        }
22218
22219        // reader
22220        synchronized (mPackages) {
22221            // We didn't update the settings after removing each package;
22222            // write them now for all packages.
22223            mSettings.writeLPr();
22224        }
22225
22226        // We have to absolutely send UPDATED_MEDIA_STATUS only
22227        // after confirming that all the receivers processed the ordered
22228        // broadcast when packages get disabled, force a gc to clean things up.
22229        // and unload all the containers.
22230        if (pkgList.size() > 0) {
22231            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
22232                    new IIntentReceiver.Stub() {
22233                public void performReceive(Intent intent, int resultCode, String data,
22234                        Bundle extras, boolean ordered, boolean sticky,
22235                        int sendingUser) throws RemoteException {
22236                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
22237                            reportStatus ? 1 : 0, 1, keys);
22238                    mHandler.sendMessage(msg);
22239                }
22240            });
22241        } else {
22242            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
22243                    keys);
22244            mHandler.sendMessage(msg);
22245        }
22246    }
22247
22248    private void loadPrivatePackages(final VolumeInfo vol) {
22249        mHandler.post(new Runnable() {
22250            @Override
22251            public void run() {
22252                loadPrivatePackagesInner(vol);
22253            }
22254        });
22255    }
22256
22257    private void loadPrivatePackagesInner(VolumeInfo vol) {
22258        final String volumeUuid = vol.fsUuid;
22259        if (TextUtils.isEmpty(volumeUuid)) {
22260            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22261            return;
22262        }
22263
22264        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22265        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22266        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22267
22268        final VersionInfo ver;
22269        final List<PackageSetting> packages;
22270        synchronized (mPackages) {
22271            ver = mSettings.findOrCreateVersion(volumeUuid);
22272            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22273        }
22274
22275        for (PackageSetting ps : packages) {
22276            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22277            synchronized (mInstallLock) {
22278                final PackageParser.Package pkg;
22279                try {
22280                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22281                    loaded.add(pkg.applicationInfo);
22282
22283                } catch (PackageManagerException e) {
22284                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22285                }
22286
22287                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22288                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22289                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22290                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22291                }
22292            }
22293        }
22294
22295        // Reconcile app data for all started/unlocked users
22296        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22297        final UserManager um = mContext.getSystemService(UserManager.class);
22298        UserManagerInternal umInternal = getUserManagerInternal();
22299        for (UserInfo user : um.getUsers()) {
22300            final int flags;
22301            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22302                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22303            } else if (umInternal.isUserRunning(user.id)) {
22304                flags = StorageManager.FLAG_STORAGE_DE;
22305            } else {
22306                continue;
22307            }
22308
22309            try {
22310                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22311                synchronized (mInstallLock) {
22312                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22313                }
22314            } catch (IllegalStateException e) {
22315                // Device was probably ejected, and we'll process that event momentarily
22316                Slog.w(TAG, "Failed to prepare storage: " + e);
22317            }
22318        }
22319
22320        synchronized (mPackages) {
22321            int updateFlags = UPDATE_PERMISSIONS_ALL;
22322            if (ver.sdkVersion != mSdkVersion) {
22323                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22324                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22325                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22326            }
22327            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22328
22329            // Yay, everything is now upgraded
22330            ver.forceCurrent();
22331
22332            mSettings.writeLPr();
22333        }
22334
22335        for (PackageFreezer freezer : freezers) {
22336            freezer.close();
22337        }
22338
22339        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22340        sendResourcesChangedBroadcast(true, false, loaded, null);
22341    }
22342
22343    private void unloadPrivatePackages(final VolumeInfo vol) {
22344        mHandler.post(new Runnable() {
22345            @Override
22346            public void run() {
22347                unloadPrivatePackagesInner(vol);
22348            }
22349        });
22350    }
22351
22352    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22353        final String volumeUuid = vol.fsUuid;
22354        if (TextUtils.isEmpty(volumeUuid)) {
22355            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22356            return;
22357        }
22358
22359        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22360        synchronized (mInstallLock) {
22361        synchronized (mPackages) {
22362            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22363            for (PackageSetting ps : packages) {
22364                if (ps.pkg == null) continue;
22365
22366                final ApplicationInfo info = ps.pkg.applicationInfo;
22367                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22368                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22369
22370                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22371                        "unloadPrivatePackagesInner")) {
22372                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22373                            false, null)) {
22374                        unloaded.add(info);
22375                    } else {
22376                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22377                    }
22378                }
22379
22380                // Try very hard to release any references to this package
22381                // so we don't risk the system server being killed due to
22382                // open FDs
22383                AttributeCache.instance().removePackage(ps.name);
22384            }
22385
22386            mSettings.writeLPr();
22387        }
22388        }
22389
22390        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22391        sendResourcesChangedBroadcast(false, false, unloaded, null);
22392
22393        // Try very hard to release any references to this path so we don't risk
22394        // the system server being killed due to open FDs
22395        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22396
22397        for (int i = 0; i < 3; i++) {
22398            System.gc();
22399            System.runFinalization();
22400        }
22401    }
22402
22403    private void assertPackageKnown(String volumeUuid, String packageName)
22404            throws PackageManagerException {
22405        synchronized (mPackages) {
22406            // Normalize package name to handle renamed packages
22407            packageName = normalizePackageNameLPr(packageName);
22408
22409            final PackageSetting ps = mSettings.mPackages.get(packageName);
22410            if (ps == null) {
22411                throw new PackageManagerException("Package " + packageName + " is unknown");
22412            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22413                throw new PackageManagerException(
22414                        "Package " + packageName + " found on unknown volume " + volumeUuid
22415                                + "; expected volume " + ps.volumeUuid);
22416            }
22417        }
22418    }
22419
22420    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22421            throws PackageManagerException {
22422        synchronized (mPackages) {
22423            // Normalize package name to handle renamed packages
22424            packageName = normalizePackageNameLPr(packageName);
22425
22426            final PackageSetting ps = mSettings.mPackages.get(packageName);
22427            if (ps == null) {
22428                throw new PackageManagerException("Package " + packageName + " is unknown");
22429            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22430                throw new PackageManagerException(
22431                        "Package " + packageName + " found on unknown volume " + volumeUuid
22432                                + "; expected volume " + ps.volumeUuid);
22433            } else if (!ps.getInstalled(userId)) {
22434                throw new PackageManagerException(
22435                        "Package " + packageName + " not installed for user " + userId);
22436            }
22437        }
22438    }
22439
22440    private List<String> collectAbsoluteCodePaths() {
22441        synchronized (mPackages) {
22442            List<String> codePaths = new ArrayList<>();
22443            final int packageCount = mSettings.mPackages.size();
22444            for (int i = 0; i < packageCount; i++) {
22445                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22446                codePaths.add(ps.codePath.getAbsolutePath());
22447            }
22448            return codePaths;
22449        }
22450    }
22451
22452    /**
22453     * Examine all apps present on given mounted volume, and destroy apps that
22454     * aren't expected, either due to uninstallation or reinstallation on
22455     * another volume.
22456     */
22457    private void reconcileApps(String volumeUuid) {
22458        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22459        List<File> filesToDelete = null;
22460
22461        final File[] files = FileUtils.listFilesOrEmpty(
22462                Environment.getDataAppDirectory(volumeUuid));
22463        for (File file : files) {
22464            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22465                    && !PackageInstallerService.isStageName(file.getName());
22466            if (!isPackage) {
22467                // Ignore entries which are not packages
22468                continue;
22469            }
22470
22471            String absolutePath = file.getAbsolutePath();
22472
22473            boolean pathValid = false;
22474            final int absoluteCodePathCount = absoluteCodePaths.size();
22475            for (int i = 0; i < absoluteCodePathCount; i++) {
22476                String absoluteCodePath = absoluteCodePaths.get(i);
22477                if (absolutePath.startsWith(absoluteCodePath)) {
22478                    pathValid = true;
22479                    break;
22480                }
22481            }
22482
22483            if (!pathValid) {
22484                if (filesToDelete == null) {
22485                    filesToDelete = new ArrayList<>();
22486                }
22487                filesToDelete.add(file);
22488            }
22489        }
22490
22491        if (filesToDelete != null) {
22492            final int fileToDeleteCount = filesToDelete.size();
22493            for (int i = 0; i < fileToDeleteCount; i++) {
22494                File fileToDelete = filesToDelete.get(i);
22495                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22496                synchronized (mInstallLock) {
22497                    removeCodePathLI(fileToDelete);
22498                }
22499            }
22500        }
22501    }
22502
22503    /**
22504     * Reconcile all app data for the given user.
22505     * <p>
22506     * Verifies that directories exist and that ownership and labeling is
22507     * correct for all installed apps on all mounted volumes.
22508     */
22509    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22510        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22511        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22512            final String volumeUuid = vol.getFsUuid();
22513            synchronized (mInstallLock) {
22514                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22515            }
22516        }
22517    }
22518
22519    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22520            boolean migrateAppData) {
22521        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22522    }
22523
22524    /**
22525     * Reconcile all app data on given mounted volume.
22526     * <p>
22527     * Destroys app data that isn't expected, either due to uninstallation or
22528     * reinstallation on another volume.
22529     * <p>
22530     * Verifies that directories exist and that ownership and labeling is
22531     * correct for all installed apps.
22532     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22533     */
22534    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22535            boolean migrateAppData, boolean onlyCoreApps) {
22536        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22537                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22538        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22539
22540        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22541        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22542
22543        // First look for stale data that doesn't belong, and check if things
22544        // have changed since we did our last restorecon
22545        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22546            if (StorageManager.isFileEncryptedNativeOrEmulated()
22547                    && !StorageManager.isUserKeyUnlocked(userId)) {
22548                throw new RuntimeException(
22549                        "Yikes, someone asked us to reconcile CE storage while " + userId
22550                                + " was still locked; this would have caused massive data loss!");
22551            }
22552
22553            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22554            for (File file : files) {
22555                final String packageName = file.getName();
22556                try {
22557                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22558                } catch (PackageManagerException e) {
22559                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22560                    try {
22561                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22562                                StorageManager.FLAG_STORAGE_CE, 0);
22563                    } catch (InstallerException e2) {
22564                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22565                    }
22566                }
22567            }
22568        }
22569        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22570            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22571            for (File file : files) {
22572                final String packageName = file.getName();
22573                try {
22574                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22575                } catch (PackageManagerException e) {
22576                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22577                    try {
22578                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22579                                StorageManager.FLAG_STORAGE_DE, 0);
22580                    } catch (InstallerException e2) {
22581                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22582                    }
22583                }
22584            }
22585        }
22586
22587        // Ensure that data directories are ready to roll for all packages
22588        // installed for this volume and user
22589        final List<PackageSetting> packages;
22590        synchronized (mPackages) {
22591            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22592        }
22593        int preparedCount = 0;
22594        for (PackageSetting ps : packages) {
22595            final String packageName = ps.name;
22596            if (ps.pkg == null) {
22597                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22598                // TODO: might be due to legacy ASEC apps; we should circle back
22599                // and reconcile again once they're scanned
22600                continue;
22601            }
22602            // Skip non-core apps if requested
22603            if (onlyCoreApps && !ps.pkg.coreApp) {
22604                result.add(packageName);
22605                continue;
22606            }
22607
22608            if (ps.getInstalled(userId)) {
22609                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22610                preparedCount++;
22611            }
22612        }
22613
22614        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22615        return result;
22616    }
22617
22618    /**
22619     * Prepare app data for the given app just after it was installed or
22620     * upgraded. This method carefully only touches users that it's installed
22621     * for, and it forces a restorecon to handle any seinfo changes.
22622     * <p>
22623     * Verifies that directories exist and that ownership and labeling is
22624     * correct for all installed apps. If there is an ownership mismatch, it
22625     * will try recovering system apps by wiping data; third-party app data is
22626     * left intact.
22627     * <p>
22628     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22629     */
22630    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22631        final PackageSetting ps;
22632        synchronized (mPackages) {
22633            ps = mSettings.mPackages.get(pkg.packageName);
22634            mSettings.writeKernelMappingLPr(ps);
22635        }
22636
22637        final UserManager um = mContext.getSystemService(UserManager.class);
22638        UserManagerInternal umInternal = getUserManagerInternal();
22639        for (UserInfo user : um.getUsers()) {
22640            final int flags;
22641            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22642                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22643            } else if (umInternal.isUserRunning(user.id)) {
22644                flags = StorageManager.FLAG_STORAGE_DE;
22645            } else {
22646                continue;
22647            }
22648
22649            if (ps.getInstalled(user.id)) {
22650                // TODO: when user data is locked, mark that we're still dirty
22651                prepareAppDataLIF(pkg, user.id, flags);
22652            }
22653        }
22654    }
22655
22656    /**
22657     * Prepare app data for the given app.
22658     * <p>
22659     * Verifies that directories exist and that ownership and labeling is
22660     * correct for all installed apps. If there is an ownership mismatch, this
22661     * will try recovering system apps by wiping data; third-party app data is
22662     * left intact.
22663     */
22664    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22665        if (pkg == null) {
22666            Slog.wtf(TAG, "Package was null!", new Throwable());
22667            return;
22668        }
22669        prepareAppDataLeafLIF(pkg, userId, flags);
22670        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22671        for (int i = 0; i < childCount; i++) {
22672            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22673        }
22674    }
22675
22676    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22677            boolean maybeMigrateAppData) {
22678        prepareAppDataLIF(pkg, userId, flags);
22679
22680        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22681            // We may have just shuffled around app data directories, so
22682            // prepare them one more time
22683            prepareAppDataLIF(pkg, userId, flags);
22684        }
22685    }
22686
22687    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22688        if (DEBUG_APP_DATA) {
22689            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22690                    + Integer.toHexString(flags));
22691        }
22692
22693        final String volumeUuid = pkg.volumeUuid;
22694        final String packageName = pkg.packageName;
22695        final ApplicationInfo app = pkg.applicationInfo;
22696        final int appId = UserHandle.getAppId(app.uid);
22697
22698        Preconditions.checkNotNull(app.seInfo);
22699
22700        long ceDataInode = -1;
22701        try {
22702            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22703                    appId, app.seInfo, app.targetSdkVersion);
22704        } catch (InstallerException e) {
22705            if (app.isSystemApp()) {
22706                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22707                        + ", but trying to recover: " + e);
22708                destroyAppDataLeafLIF(pkg, userId, flags);
22709                try {
22710                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22711                            appId, app.seInfo, app.targetSdkVersion);
22712                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22713                } catch (InstallerException e2) {
22714                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22715                }
22716            } else {
22717                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22718            }
22719        }
22720
22721        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22722            // TODO: mark this structure as dirty so we persist it!
22723            synchronized (mPackages) {
22724                final PackageSetting ps = mSettings.mPackages.get(packageName);
22725                if (ps != null) {
22726                    ps.setCeDataInode(ceDataInode, userId);
22727                }
22728            }
22729        }
22730
22731        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22732    }
22733
22734    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22735        if (pkg == null) {
22736            Slog.wtf(TAG, "Package was null!", new Throwable());
22737            return;
22738        }
22739        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22740        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22741        for (int i = 0; i < childCount; i++) {
22742            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22743        }
22744    }
22745
22746    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22747        final String volumeUuid = pkg.volumeUuid;
22748        final String packageName = pkg.packageName;
22749        final ApplicationInfo app = pkg.applicationInfo;
22750
22751        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22752            // Create a native library symlink only if we have native libraries
22753            // and if the native libraries are 32 bit libraries. We do not provide
22754            // this symlink for 64 bit libraries.
22755            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22756                final String nativeLibPath = app.nativeLibraryDir;
22757                try {
22758                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22759                            nativeLibPath, userId);
22760                } catch (InstallerException e) {
22761                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22762                }
22763            }
22764        }
22765    }
22766
22767    /**
22768     * For system apps on non-FBE devices, this method migrates any existing
22769     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22770     * requested by the app.
22771     */
22772    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22773        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22774                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22775            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22776                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22777            try {
22778                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22779                        storageTarget);
22780            } catch (InstallerException e) {
22781                logCriticalInfo(Log.WARN,
22782                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22783            }
22784            return true;
22785        } else {
22786            return false;
22787        }
22788    }
22789
22790    public PackageFreezer freezePackage(String packageName, String killReason) {
22791        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22792    }
22793
22794    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22795        return new PackageFreezer(packageName, userId, killReason);
22796    }
22797
22798    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22799            String killReason) {
22800        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22801    }
22802
22803    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22804            String killReason) {
22805        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22806            return new PackageFreezer();
22807        } else {
22808            return freezePackage(packageName, userId, killReason);
22809        }
22810    }
22811
22812    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22813            String killReason) {
22814        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22815    }
22816
22817    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22818            String killReason) {
22819        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22820            return new PackageFreezer();
22821        } else {
22822            return freezePackage(packageName, userId, killReason);
22823        }
22824    }
22825
22826    /**
22827     * Class that freezes and kills the given package upon creation, and
22828     * unfreezes it upon closing. This is typically used when doing surgery on
22829     * app code/data to prevent the app from running while you're working.
22830     */
22831    private class PackageFreezer implements AutoCloseable {
22832        private final String mPackageName;
22833        private final PackageFreezer[] mChildren;
22834
22835        private final boolean mWeFroze;
22836
22837        private final AtomicBoolean mClosed = new AtomicBoolean();
22838        private final CloseGuard mCloseGuard = CloseGuard.get();
22839
22840        /**
22841         * Create and return a stub freezer that doesn't actually do anything,
22842         * typically used when someone requested
22843         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22844         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22845         */
22846        public PackageFreezer() {
22847            mPackageName = null;
22848            mChildren = null;
22849            mWeFroze = false;
22850            mCloseGuard.open("close");
22851        }
22852
22853        public PackageFreezer(String packageName, int userId, String killReason) {
22854            synchronized (mPackages) {
22855                mPackageName = packageName;
22856                mWeFroze = mFrozenPackages.add(mPackageName);
22857
22858                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22859                if (ps != null) {
22860                    killApplication(ps.name, ps.appId, userId, killReason);
22861                }
22862
22863                final PackageParser.Package p = mPackages.get(packageName);
22864                if (p != null && p.childPackages != null) {
22865                    final int N = p.childPackages.size();
22866                    mChildren = new PackageFreezer[N];
22867                    for (int i = 0; i < N; i++) {
22868                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22869                                userId, killReason);
22870                    }
22871                } else {
22872                    mChildren = null;
22873                }
22874            }
22875            mCloseGuard.open("close");
22876        }
22877
22878        @Override
22879        protected void finalize() throws Throwable {
22880            try {
22881                if (mCloseGuard != null) {
22882                    mCloseGuard.warnIfOpen();
22883                }
22884
22885                close();
22886            } finally {
22887                super.finalize();
22888            }
22889        }
22890
22891        @Override
22892        public void close() {
22893            mCloseGuard.close();
22894            if (mClosed.compareAndSet(false, true)) {
22895                synchronized (mPackages) {
22896                    if (mWeFroze) {
22897                        mFrozenPackages.remove(mPackageName);
22898                    }
22899
22900                    if (mChildren != null) {
22901                        for (PackageFreezer freezer : mChildren) {
22902                            freezer.close();
22903                        }
22904                    }
22905                }
22906            }
22907        }
22908    }
22909
22910    /**
22911     * Verify that given package is currently frozen.
22912     */
22913    private void checkPackageFrozen(String packageName) {
22914        synchronized (mPackages) {
22915            if (!mFrozenPackages.contains(packageName)) {
22916                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22917            }
22918        }
22919    }
22920
22921    @Override
22922    public int movePackage(final String packageName, final String volumeUuid) {
22923        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22924
22925        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22926        final int moveId = mNextMoveId.getAndIncrement();
22927        mHandler.post(new Runnable() {
22928            @Override
22929            public void run() {
22930                try {
22931                    movePackageInternal(packageName, volumeUuid, moveId, user);
22932                } catch (PackageManagerException e) {
22933                    Slog.w(TAG, "Failed to move " + packageName, e);
22934                    mMoveCallbacks.notifyStatusChanged(moveId,
22935                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22936                }
22937            }
22938        });
22939        return moveId;
22940    }
22941
22942    private void movePackageInternal(final String packageName, final String volumeUuid,
22943            final int moveId, UserHandle user) throws PackageManagerException {
22944        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22945        final PackageManager pm = mContext.getPackageManager();
22946
22947        final boolean currentAsec;
22948        final String currentVolumeUuid;
22949        final File codeFile;
22950        final String installerPackageName;
22951        final String packageAbiOverride;
22952        final int appId;
22953        final String seinfo;
22954        final String label;
22955        final int targetSdkVersion;
22956        final PackageFreezer freezer;
22957        final int[] installedUserIds;
22958
22959        // reader
22960        synchronized (mPackages) {
22961            final PackageParser.Package pkg = mPackages.get(packageName);
22962            final PackageSetting ps = mSettings.mPackages.get(packageName);
22963            if (pkg == null || ps == null) {
22964                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22965            }
22966
22967            if (pkg.applicationInfo.isSystemApp()) {
22968                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22969                        "Cannot move system application");
22970            }
22971
22972            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22973            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22974                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22975            if (isInternalStorage && !allow3rdPartyOnInternal) {
22976                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22977                        "3rd party apps are not allowed on internal storage");
22978            }
22979
22980            if (pkg.applicationInfo.isExternalAsec()) {
22981                currentAsec = true;
22982                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22983            } else if (pkg.applicationInfo.isForwardLocked()) {
22984                currentAsec = true;
22985                currentVolumeUuid = "forward_locked";
22986            } else {
22987                currentAsec = false;
22988                currentVolumeUuid = ps.volumeUuid;
22989
22990                final File probe = new File(pkg.codePath);
22991                final File probeOat = new File(probe, "oat");
22992                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22993                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22994                            "Move only supported for modern cluster style installs");
22995                }
22996            }
22997
22998            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22999                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23000                        "Package already moved to " + volumeUuid);
23001            }
23002            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23003                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23004                        "Device admin cannot be moved");
23005            }
23006
23007            if (mFrozenPackages.contains(packageName)) {
23008                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23009                        "Failed to move already frozen package");
23010            }
23011
23012            codeFile = new File(pkg.codePath);
23013            installerPackageName = ps.installerPackageName;
23014            packageAbiOverride = ps.cpuAbiOverrideString;
23015            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23016            seinfo = pkg.applicationInfo.seInfo;
23017            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23018            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23019            freezer = freezePackage(packageName, "movePackageInternal");
23020            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23021        }
23022
23023        final Bundle extras = new Bundle();
23024        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23025        extras.putString(Intent.EXTRA_TITLE, label);
23026        mMoveCallbacks.notifyCreated(moveId, extras);
23027
23028        int installFlags;
23029        final boolean moveCompleteApp;
23030        final File measurePath;
23031
23032        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23033            installFlags = INSTALL_INTERNAL;
23034            moveCompleteApp = !currentAsec;
23035            measurePath = Environment.getDataAppDirectory(volumeUuid);
23036        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23037            installFlags = INSTALL_EXTERNAL;
23038            moveCompleteApp = false;
23039            measurePath = storage.getPrimaryPhysicalVolume().getPath();
23040        } else {
23041            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23042            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23043                    || !volume.isMountedWritable()) {
23044                freezer.close();
23045                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23046                        "Move location not mounted private volume");
23047            }
23048
23049            Preconditions.checkState(!currentAsec);
23050
23051            installFlags = INSTALL_INTERNAL;
23052            moveCompleteApp = true;
23053            measurePath = Environment.getDataAppDirectory(volumeUuid);
23054        }
23055
23056        final PackageStats stats = new PackageStats(null, -1);
23057        synchronized (mInstaller) {
23058            for (int userId : installedUserIds) {
23059                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23060                    freezer.close();
23061                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23062                            "Failed to measure package size");
23063                }
23064            }
23065        }
23066
23067        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23068                + stats.dataSize);
23069
23070        final long startFreeBytes = measurePath.getUsableSpace();
23071        final long sizeBytes;
23072        if (moveCompleteApp) {
23073            sizeBytes = stats.codeSize + stats.dataSize;
23074        } else {
23075            sizeBytes = stats.codeSize;
23076        }
23077
23078        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23079            freezer.close();
23080            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23081                    "Not enough free space to move");
23082        }
23083
23084        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23085
23086        final CountDownLatch installedLatch = new CountDownLatch(1);
23087        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23088            @Override
23089            public void onUserActionRequired(Intent intent) throws RemoteException {
23090                throw new IllegalStateException();
23091            }
23092
23093            @Override
23094            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23095                    Bundle extras) throws RemoteException {
23096                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23097                        + PackageManager.installStatusToString(returnCode, msg));
23098
23099                installedLatch.countDown();
23100                freezer.close();
23101
23102                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23103                switch (status) {
23104                    case PackageInstaller.STATUS_SUCCESS:
23105                        mMoveCallbacks.notifyStatusChanged(moveId,
23106                                PackageManager.MOVE_SUCCEEDED);
23107                        break;
23108                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23109                        mMoveCallbacks.notifyStatusChanged(moveId,
23110                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23111                        break;
23112                    default:
23113                        mMoveCallbacks.notifyStatusChanged(moveId,
23114                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23115                        break;
23116                }
23117            }
23118        };
23119
23120        final MoveInfo move;
23121        if (moveCompleteApp) {
23122            // Kick off a thread to report progress estimates
23123            new Thread() {
23124                @Override
23125                public void run() {
23126                    while (true) {
23127                        try {
23128                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23129                                break;
23130                            }
23131                        } catch (InterruptedException ignored) {
23132                        }
23133
23134                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23135                        final int progress = 10 + (int) MathUtils.constrain(
23136                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23137                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23138                    }
23139                }
23140            }.start();
23141
23142            final String dataAppName = codeFile.getName();
23143            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23144                    dataAppName, appId, seinfo, targetSdkVersion);
23145        } else {
23146            move = null;
23147        }
23148
23149        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23150
23151        final Message msg = mHandler.obtainMessage(INIT_COPY);
23152        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23153        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23154                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23155                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23156                PackageManager.INSTALL_REASON_UNKNOWN);
23157        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23158        msg.obj = params;
23159
23160        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23161                System.identityHashCode(msg.obj));
23162        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23163                System.identityHashCode(msg.obj));
23164
23165        mHandler.sendMessage(msg);
23166    }
23167
23168    @Override
23169    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23170        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23171
23172        final int realMoveId = mNextMoveId.getAndIncrement();
23173        final Bundle extras = new Bundle();
23174        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23175        mMoveCallbacks.notifyCreated(realMoveId, extras);
23176
23177        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23178            @Override
23179            public void onCreated(int moveId, Bundle extras) {
23180                // Ignored
23181            }
23182
23183            @Override
23184            public void onStatusChanged(int moveId, int status, long estMillis) {
23185                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23186            }
23187        };
23188
23189        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23190        storage.setPrimaryStorageUuid(volumeUuid, callback);
23191        return realMoveId;
23192    }
23193
23194    @Override
23195    public int getMoveStatus(int moveId) {
23196        mContext.enforceCallingOrSelfPermission(
23197                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23198        return mMoveCallbacks.mLastStatus.get(moveId);
23199    }
23200
23201    @Override
23202    public void registerMoveCallback(IPackageMoveObserver callback) {
23203        mContext.enforceCallingOrSelfPermission(
23204                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23205        mMoveCallbacks.register(callback);
23206    }
23207
23208    @Override
23209    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23210        mContext.enforceCallingOrSelfPermission(
23211                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23212        mMoveCallbacks.unregister(callback);
23213    }
23214
23215    @Override
23216    public boolean setInstallLocation(int loc) {
23217        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23218                null);
23219        if (getInstallLocation() == loc) {
23220            return true;
23221        }
23222        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23223                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23224            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23225                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23226            return true;
23227        }
23228        return false;
23229   }
23230
23231    @Override
23232    public int getInstallLocation() {
23233        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23234                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23235                PackageHelper.APP_INSTALL_AUTO);
23236    }
23237
23238    /** Called by UserManagerService */
23239    void cleanUpUser(UserManagerService userManager, int userHandle) {
23240        synchronized (mPackages) {
23241            mDirtyUsers.remove(userHandle);
23242            mUserNeedsBadging.delete(userHandle);
23243            mSettings.removeUserLPw(userHandle);
23244            mPendingBroadcasts.remove(userHandle);
23245            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23246            removeUnusedPackagesLPw(userManager, userHandle);
23247        }
23248    }
23249
23250    /**
23251     * We're removing userHandle and would like to remove any downloaded packages
23252     * that are no longer in use by any other user.
23253     * @param userHandle the user being removed
23254     */
23255    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23256        final boolean DEBUG_CLEAN_APKS = false;
23257        int [] users = userManager.getUserIds();
23258        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23259        while (psit.hasNext()) {
23260            PackageSetting ps = psit.next();
23261            if (ps.pkg == null) {
23262                continue;
23263            }
23264            final String packageName = ps.pkg.packageName;
23265            // Skip over if system app
23266            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23267                continue;
23268            }
23269            if (DEBUG_CLEAN_APKS) {
23270                Slog.i(TAG, "Checking package " + packageName);
23271            }
23272            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23273            if (keep) {
23274                if (DEBUG_CLEAN_APKS) {
23275                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23276                }
23277            } else {
23278                for (int i = 0; i < users.length; i++) {
23279                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23280                        keep = true;
23281                        if (DEBUG_CLEAN_APKS) {
23282                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23283                                    + users[i]);
23284                        }
23285                        break;
23286                    }
23287                }
23288            }
23289            if (!keep) {
23290                if (DEBUG_CLEAN_APKS) {
23291                    Slog.i(TAG, "  Removing package " + packageName);
23292                }
23293                mHandler.post(new Runnable() {
23294                    public void run() {
23295                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23296                                userHandle, 0);
23297                    } //end run
23298                });
23299            }
23300        }
23301    }
23302
23303    /** Called by UserManagerService */
23304    void createNewUser(int userId, String[] disallowedPackages) {
23305        synchronized (mInstallLock) {
23306            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23307        }
23308        synchronized (mPackages) {
23309            scheduleWritePackageRestrictionsLocked(userId);
23310            scheduleWritePackageListLocked(userId);
23311            applyFactoryDefaultBrowserLPw(userId);
23312            primeDomainVerificationsLPw(userId);
23313        }
23314    }
23315
23316    void onNewUserCreated(final int userId) {
23317        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23318        // If permission review for legacy apps is required, we represent
23319        // dagerous permissions for such apps as always granted runtime
23320        // permissions to keep per user flag state whether review is needed.
23321        // Hence, if a new user is added we have to propagate dangerous
23322        // permission grants for these legacy apps.
23323        if (mPermissionReviewRequired) {
23324            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23325                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23326        }
23327    }
23328
23329    @Override
23330    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23331        mContext.enforceCallingOrSelfPermission(
23332                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23333                "Only package verification agents can read the verifier device identity");
23334
23335        synchronized (mPackages) {
23336            return mSettings.getVerifierDeviceIdentityLPw();
23337        }
23338    }
23339
23340    @Override
23341    public void setPermissionEnforced(String permission, boolean enforced) {
23342        // TODO: Now that we no longer change GID for storage, this should to away.
23343        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23344                "setPermissionEnforced");
23345        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23346            synchronized (mPackages) {
23347                if (mSettings.mReadExternalStorageEnforced == null
23348                        || mSettings.mReadExternalStorageEnforced != enforced) {
23349                    mSettings.mReadExternalStorageEnforced = enforced;
23350                    mSettings.writeLPr();
23351                }
23352            }
23353            // kill any non-foreground processes so we restart them and
23354            // grant/revoke the GID.
23355            final IActivityManager am = ActivityManager.getService();
23356            if (am != null) {
23357                final long token = Binder.clearCallingIdentity();
23358                try {
23359                    am.killProcessesBelowForeground("setPermissionEnforcement");
23360                } catch (RemoteException e) {
23361                } finally {
23362                    Binder.restoreCallingIdentity(token);
23363                }
23364            }
23365        } else {
23366            throw new IllegalArgumentException("No selective enforcement for " + permission);
23367        }
23368    }
23369
23370    @Override
23371    @Deprecated
23372    public boolean isPermissionEnforced(String permission) {
23373        return true;
23374    }
23375
23376    @Override
23377    public boolean isStorageLow() {
23378        final long token = Binder.clearCallingIdentity();
23379        try {
23380            final DeviceStorageMonitorInternal
23381                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23382            if (dsm != null) {
23383                return dsm.isMemoryLow();
23384            } else {
23385                return false;
23386            }
23387        } finally {
23388            Binder.restoreCallingIdentity(token);
23389        }
23390    }
23391
23392    @Override
23393    public IPackageInstaller getPackageInstaller() {
23394        return mInstallerService;
23395    }
23396
23397    private boolean userNeedsBadging(int userId) {
23398        int index = mUserNeedsBadging.indexOfKey(userId);
23399        if (index < 0) {
23400            final UserInfo userInfo;
23401            final long token = Binder.clearCallingIdentity();
23402            try {
23403                userInfo = sUserManager.getUserInfo(userId);
23404            } finally {
23405                Binder.restoreCallingIdentity(token);
23406            }
23407            final boolean b;
23408            if (userInfo != null && userInfo.isManagedProfile()) {
23409                b = true;
23410            } else {
23411                b = false;
23412            }
23413            mUserNeedsBadging.put(userId, b);
23414            return b;
23415        }
23416        return mUserNeedsBadging.valueAt(index);
23417    }
23418
23419    @Override
23420    public KeySet getKeySetByAlias(String packageName, String alias) {
23421        if (packageName == null || alias == null) {
23422            return null;
23423        }
23424        synchronized(mPackages) {
23425            final PackageParser.Package pkg = mPackages.get(packageName);
23426            if (pkg == null) {
23427                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23428                throw new IllegalArgumentException("Unknown package: " + packageName);
23429            }
23430            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23431            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23432        }
23433    }
23434
23435    @Override
23436    public KeySet getSigningKeySet(String packageName) {
23437        if (packageName == null) {
23438            return null;
23439        }
23440        synchronized(mPackages) {
23441            final PackageParser.Package pkg = mPackages.get(packageName);
23442            if (pkg == null) {
23443                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23444                throw new IllegalArgumentException("Unknown package: " + packageName);
23445            }
23446            if (pkg.applicationInfo.uid != Binder.getCallingUid()
23447                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
23448                throw new SecurityException("May not access signing KeySet of other apps.");
23449            }
23450            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23451            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23452        }
23453    }
23454
23455    @Override
23456    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23457        if (packageName == null || ks == null) {
23458            return false;
23459        }
23460        synchronized(mPackages) {
23461            final PackageParser.Package pkg = mPackages.get(packageName);
23462            if (pkg == null) {
23463                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23464                throw new IllegalArgumentException("Unknown package: " + packageName);
23465            }
23466            IBinder ksh = ks.getToken();
23467            if (ksh instanceof KeySetHandle) {
23468                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23469                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23470            }
23471            return false;
23472        }
23473    }
23474
23475    @Override
23476    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23477        if (packageName == null || ks == null) {
23478            return false;
23479        }
23480        synchronized(mPackages) {
23481            final PackageParser.Package pkg = mPackages.get(packageName);
23482            if (pkg == null) {
23483                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23484                throw new IllegalArgumentException("Unknown package: " + packageName);
23485            }
23486            IBinder ksh = ks.getToken();
23487            if (ksh instanceof KeySetHandle) {
23488                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23489                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23490            }
23491            return false;
23492        }
23493    }
23494
23495    private void deletePackageIfUnusedLPr(final String packageName) {
23496        PackageSetting ps = mSettings.mPackages.get(packageName);
23497        if (ps == null) {
23498            return;
23499        }
23500        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23501            // TODO Implement atomic delete if package is unused
23502            // It is currently possible that the package will be deleted even if it is installed
23503            // after this method returns.
23504            mHandler.post(new Runnable() {
23505                public void run() {
23506                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23507                            0, PackageManager.DELETE_ALL_USERS);
23508                }
23509            });
23510        }
23511    }
23512
23513    /**
23514     * Check and throw if the given before/after packages would be considered a
23515     * downgrade.
23516     */
23517    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23518            throws PackageManagerException {
23519        if (after.versionCode < before.mVersionCode) {
23520            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23521                    "Update version code " + after.versionCode + " is older than current "
23522                    + before.mVersionCode);
23523        } else if (after.versionCode == before.mVersionCode) {
23524            if (after.baseRevisionCode < before.baseRevisionCode) {
23525                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23526                        "Update base revision code " + after.baseRevisionCode
23527                        + " is older than current " + before.baseRevisionCode);
23528            }
23529
23530            if (!ArrayUtils.isEmpty(after.splitNames)) {
23531                for (int i = 0; i < after.splitNames.length; i++) {
23532                    final String splitName = after.splitNames[i];
23533                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23534                    if (j != -1) {
23535                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23536                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23537                                    "Update split " + splitName + " revision code "
23538                                    + after.splitRevisionCodes[i] + " is older than current "
23539                                    + before.splitRevisionCodes[j]);
23540                        }
23541                    }
23542                }
23543            }
23544        }
23545    }
23546
23547    private static class MoveCallbacks extends Handler {
23548        private static final int MSG_CREATED = 1;
23549        private static final int MSG_STATUS_CHANGED = 2;
23550
23551        private final RemoteCallbackList<IPackageMoveObserver>
23552                mCallbacks = new RemoteCallbackList<>();
23553
23554        private final SparseIntArray mLastStatus = new SparseIntArray();
23555
23556        public MoveCallbacks(Looper looper) {
23557            super(looper);
23558        }
23559
23560        public void register(IPackageMoveObserver callback) {
23561            mCallbacks.register(callback);
23562        }
23563
23564        public void unregister(IPackageMoveObserver callback) {
23565            mCallbacks.unregister(callback);
23566        }
23567
23568        @Override
23569        public void handleMessage(Message msg) {
23570            final SomeArgs args = (SomeArgs) msg.obj;
23571            final int n = mCallbacks.beginBroadcast();
23572            for (int i = 0; i < n; i++) {
23573                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23574                try {
23575                    invokeCallback(callback, msg.what, args);
23576                } catch (RemoteException ignored) {
23577                }
23578            }
23579            mCallbacks.finishBroadcast();
23580            args.recycle();
23581        }
23582
23583        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23584                throws RemoteException {
23585            switch (what) {
23586                case MSG_CREATED: {
23587                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23588                    break;
23589                }
23590                case MSG_STATUS_CHANGED: {
23591                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23592                    break;
23593                }
23594            }
23595        }
23596
23597        private void notifyCreated(int moveId, Bundle extras) {
23598            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23599
23600            final SomeArgs args = SomeArgs.obtain();
23601            args.argi1 = moveId;
23602            args.arg2 = extras;
23603            obtainMessage(MSG_CREATED, args).sendToTarget();
23604        }
23605
23606        private void notifyStatusChanged(int moveId, int status) {
23607            notifyStatusChanged(moveId, status, -1);
23608        }
23609
23610        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23611            Slog.v(TAG, "Move " + moveId + " status " + status);
23612
23613            final SomeArgs args = SomeArgs.obtain();
23614            args.argi1 = moveId;
23615            args.argi2 = status;
23616            args.arg3 = estMillis;
23617            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23618
23619            synchronized (mLastStatus) {
23620                mLastStatus.put(moveId, status);
23621            }
23622        }
23623    }
23624
23625    private final static class OnPermissionChangeListeners extends Handler {
23626        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23627
23628        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23629                new RemoteCallbackList<>();
23630
23631        public OnPermissionChangeListeners(Looper looper) {
23632            super(looper);
23633        }
23634
23635        @Override
23636        public void handleMessage(Message msg) {
23637            switch (msg.what) {
23638                case MSG_ON_PERMISSIONS_CHANGED: {
23639                    final int uid = msg.arg1;
23640                    handleOnPermissionsChanged(uid);
23641                } break;
23642            }
23643        }
23644
23645        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23646            mPermissionListeners.register(listener);
23647
23648        }
23649
23650        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23651            mPermissionListeners.unregister(listener);
23652        }
23653
23654        public void onPermissionsChanged(int uid) {
23655            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23656                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23657            }
23658        }
23659
23660        private void handleOnPermissionsChanged(int uid) {
23661            final int count = mPermissionListeners.beginBroadcast();
23662            try {
23663                for (int i = 0; i < count; i++) {
23664                    IOnPermissionsChangeListener callback = mPermissionListeners
23665                            .getBroadcastItem(i);
23666                    try {
23667                        callback.onPermissionsChanged(uid);
23668                    } catch (RemoteException e) {
23669                        Log.e(TAG, "Permission listener is dead", e);
23670                    }
23671                }
23672            } finally {
23673                mPermissionListeners.finishBroadcast();
23674            }
23675        }
23676    }
23677
23678    private class PackageManagerInternalImpl extends PackageManagerInternal {
23679        @Override
23680        public void setLocationPackagesProvider(PackagesProvider provider) {
23681            synchronized (mPackages) {
23682                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23683            }
23684        }
23685
23686        @Override
23687        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23688            synchronized (mPackages) {
23689                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23690            }
23691        }
23692
23693        @Override
23694        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23695            synchronized (mPackages) {
23696                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23697            }
23698        }
23699
23700        @Override
23701        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23702            synchronized (mPackages) {
23703                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23704            }
23705        }
23706
23707        @Override
23708        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23709            synchronized (mPackages) {
23710                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23711            }
23712        }
23713
23714        @Override
23715        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23716            synchronized (mPackages) {
23717                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23718            }
23719        }
23720
23721        @Override
23722        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23723            synchronized (mPackages) {
23724                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23725                        packageName, userId);
23726            }
23727        }
23728
23729        @Override
23730        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23731            synchronized (mPackages) {
23732                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23733                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23734                        packageName, userId);
23735            }
23736        }
23737
23738        @Override
23739        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23740            synchronized (mPackages) {
23741                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23742                        packageName, userId);
23743            }
23744        }
23745
23746        @Override
23747        public void setKeepUninstalledPackages(final List<String> packageList) {
23748            Preconditions.checkNotNull(packageList);
23749            List<String> removedFromList = null;
23750            synchronized (mPackages) {
23751                if (mKeepUninstalledPackages != null) {
23752                    final int packagesCount = mKeepUninstalledPackages.size();
23753                    for (int i = 0; i < packagesCount; i++) {
23754                        String oldPackage = mKeepUninstalledPackages.get(i);
23755                        if (packageList != null && packageList.contains(oldPackage)) {
23756                            continue;
23757                        }
23758                        if (removedFromList == null) {
23759                            removedFromList = new ArrayList<>();
23760                        }
23761                        removedFromList.add(oldPackage);
23762                    }
23763                }
23764                mKeepUninstalledPackages = new ArrayList<>(packageList);
23765                if (removedFromList != null) {
23766                    final int removedCount = removedFromList.size();
23767                    for (int i = 0; i < removedCount; i++) {
23768                        deletePackageIfUnusedLPr(removedFromList.get(i));
23769                    }
23770                }
23771            }
23772        }
23773
23774        @Override
23775        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23776            synchronized (mPackages) {
23777                // If we do not support permission review, done.
23778                if (!mPermissionReviewRequired) {
23779                    return false;
23780                }
23781
23782                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23783                if (packageSetting == null) {
23784                    return false;
23785                }
23786
23787                // Permission review applies only to apps not supporting the new permission model.
23788                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23789                    return false;
23790                }
23791
23792                // Legacy apps have the permission and get user consent on launch.
23793                PermissionsState permissionsState = packageSetting.getPermissionsState();
23794                return permissionsState.isPermissionReviewRequired(userId);
23795            }
23796        }
23797
23798        @Override
23799        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23800            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23801        }
23802
23803        @Override
23804        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23805                int userId) {
23806            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23807        }
23808
23809        @Override
23810        public void setDeviceAndProfileOwnerPackages(
23811                int deviceOwnerUserId, String deviceOwnerPackage,
23812                SparseArray<String> profileOwnerPackages) {
23813            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23814                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23815        }
23816
23817        @Override
23818        public boolean isPackageDataProtected(int userId, String packageName) {
23819            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23820        }
23821
23822        @Override
23823        public boolean isPackageEphemeral(int userId, String packageName) {
23824            synchronized (mPackages) {
23825                final PackageSetting ps = mSettings.mPackages.get(packageName);
23826                return ps != null ? ps.getInstantApp(userId) : false;
23827            }
23828        }
23829
23830        @Override
23831        public boolean wasPackageEverLaunched(String packageName, int userId) {
23832            synchronized (mPackages) {
23833                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23834            }
23835        }
23836
23837        @Override
23838        public void grantRuntimePermission(String packageName, String name, int userId,
23839                boolean overridePolicy) {
23840            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23841                    overridePolicy);
23842        }
23843
23844        @Override
23845        public void revokeRuntimePermission(String packageName, String name, int userId,
23846                boolean overridePolicy) {
23847            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23848                    overridePolicy);
23849        }
23850
23851        @Override
23852        public String getNameForUid(int uid) {
23853            return PackageManagerService.this.getNameForUid(uid);
23854        }
23855
23856        @Override
23857        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23858                Intent origIntent, String resolvedType, String callingPackage,
23859                Bundle verificationBundle, int userId) {
23860            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23861                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23862                    userId);
23863        }
23864
23865        @Override
23866        public void grantEphemeralAccess(int userId, Intent intent,
23867                int targetAppId, int ephemeralAppId) {
23868            synchronized (mPackages) {
23869                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23870                        targetAppId, ephemeralAppId);
23871            }
23872        }
23873
23874        @Override
23875        public boolean isInstantAppInstallerComponent(ComponentName component) {
23876            synchronized (mPackages) {
23877                return mInstantAppInstallerActivity != null
23878                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23879            }
23880        }
23881
23882        @Override
23883        public void pruneInstantApps() {
23884            synchronized (mPackages) {
23885                mInstantAppRegistry.pruneInstantAppsLPw();
23886            }
23887        }
23888
23889        @Override
23890        public String getSetupWizardPackageName() {
23891            return mSetupWizardPackage;
23892        }
23893
23894        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23895            if (policy != null) {
23896                mExternalSourcesPolicy = policy;
23897            }
23898        }
23899
23900        @Override
23901        public boolean isPackagePersistent(String packageName) {
23902            synchronized (mPackages) {
23903                PackageParser.Package pkg = mPackages.get(packageName);
23904                return pkg != null
23905                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23906                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23907                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23908                        : false;
23909            }
23910        }
23911
23912        @Override
23913        public List<PackageInfo> getOverlayPackages(int userId) {
23914            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23915            synchronized (mPackages) {
23916                for (PackageParser.Package p : mPackages.values()) {
23917                    if (p.mOverlayTarget != null) {
23918                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23919                        if (pkg != null) {
23920                            overlayPackages.add(pkg);
23921                        }
23922                    }
23923                }
23924            }
23925            return overlayPackages;
23926        }
23927
23928        @Override
23929        public List<String> getTargetPackageNames(int userId) {
23930            List<String> targetPackages = new ArrayList<>();
23931            synchronized (mPackages) {
23932                for (PackageParser.Package p : mPackages.values()) {
23933                    if (p.mOverlayTarget == null) {
23934                        targetPackages.add(p.packageName);
23935                    }
23936                }
23937            }
23938            return targetPackages;
23939        }
23940
23941        @Override
23942        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23943                @Nullable List<String> overlayPackageNames) {
23944            synchronized (mPackages) {
23945                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23946                    Slog.e(TAG, "failed to find package " + targetPackageName);
23947                    return false;
23948                }
23949
23950                ArrayList<String> paths = null;
23951                if (overlayPackageNames != null) {
23952                    final int N = overlayPackageNames.size();
23953                    paths = new ArrayList<>(N);
23954                    for (int i = 0; i < N; i++) {
23955                        final String packageName = overlayPackageNames.get(i);
23956                        final PackageParser.Package pkg = mPackages.get(packageName);
23957                        if (pkg == null) {
23958                            Slog.e(TAG, "failed to find package " + packageName);
23959                            return false;
23960                        }
23961                        paths.add(pkg.baseCodePath);
23962                    }
23963                }
23964
23965                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23966                    mEnabledOverlayPaths.get(userId);
23967                if (userSpecificOverlays == null) {
23968                    userSpecificOverlays = new ArrayMap<>();
23969                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23970                }
23971
23972                if (paths != null && paths.size() > 0) {
23973                    userSpecificOverlays.put(targetPackageName, paths);
23974                } else {
23975                    userSpecificOverlays.remove(targetPackageName);
23976                }
23977                return true;
23978            }
23979        }
23980
23981        @Override
23982        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23983                int flags, int userId) {
23984            return resolveIntentInternal(
23985                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
23986        }
23987
23988        @Override
23989        public ResolveInfo resolveService(Intent intent, String resolvedType,
23990                int flags, int userId, int callingUid) {
23991            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23992        }
23993
23994        @Override
23995        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23996            synchronized (mPackages) {
23997                mIsolatedOwners.put(isolatedUid, ownerUid);
23998            }
23999        }
24000
24001        @Override
24002        public void removeIsolatedUid(int isolatedUid) {
24003            synchronized (mPackages) {
24004                mIsolatedOwners.delete(isolatedUid);
24005            }
24006        }
24007
24008        @Override
24009        public int getUidTargetSdkVersion(int uid) {
24010            synchronized (mPackages) {
24011                return getUidTargetSdkVersionLockedLPr(uid);
24012            }
24013        }
24014
24015        @Override
24016        public boolean canAccessInstantApps(int callingUid) {
24017            return PackageManagerService.this.canAccessInstantApps(callingUid);
24018        }
24019    }
24020
24021    @Override
24022    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24023        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24024        synchronized (mPackages) {
24025            final long identity = Binder.clearCallingIdentity();
24026            try {
24027                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
24028                        packageNames, userId);
24029            } finally {
24030                Binder.restoreCallingIdentity(identity);
24031            }
24032        }
24033    }
24034
24035    @Override
24036    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24037        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24038        synchronized (mPackages) {
24039            final long identity = Binder.clearCallingIdentity();
24040            try {
24041                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
24042                        packageNames, userId);
24043            } finally {
24044                Binder.restoreCallingIdentity(identity);
24045            }
24046        }
24047    }
24048
24049    private static void enforceSystemOrPhoneCaller(String tag) {
24050        int callingUid = Binder.getCallingUid();
24051        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24052            throw new SecurityException(
24053                    "Cannot call " + tag + " from UID " + callingUid);
24054        }
24055    }
24056
24057    boolean isHistoricalPackageUsageAvailable() {
24058        return mPackageUsage.isHistoricalPackageUsageAvailable();
24059    }
24060
24061    /**
24062     * Return a <b>copy</b> of the collection of packages known to the package manager.
24063     * @return A copy of the values of mPackages.
24064     */
24065    Collection<PackageParser.Package> getPackages() {
24066        synchronized (mPackages) {
24067            return new ArrayList<>(mPackages.values());
24068        }
24069    }
24070
24071    /**
24072     * Logs process start information (including base APK hash) to the security log.
24073     * @hide
24074     */
24075    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24076            String apkFile, int pid) {
24077        if (!SecurityLog.isLoggingEnabled()) {
24078            return;
24079        }
24080        Bundle data = new Bundle();
24081        data.putLong("startTimestamp", System.currentTimeMillis());
24082        data.putString("processName", processName);
24083        data.putInt("uid", uid);
24084        data.putString("seinfo", seinfo);
24085        data.putString("apkFile", apkFile);
24086        data.putInt("pid", pid);
24087        Message msg = mProcessLoggingHandler.obtainMessage(
24088                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24089        msg.setData(data);
24090        mProcessLoggingHandler.sendMessage(msg);
24091    }
24092
24093    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24094        return mCompilerStats.getPackageStats(pkgName);
24095    }
24096
24097    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24098        return getOrCreateCompilerPackageStats(pkg.packageName);
24099    }
24100
24101    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24102        return mCompilerStats.getOrCreatePackageStats(pkgName);
24103    }
24104
24105    public void deleteCompilerPackageStats(String pkgName) {
24106        mCompilerStats.deletePackageStats(pkgName);
24107    }
24108
24109    @Override
24110    public int getInstallReason(String packageName, int userId) {
24111        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24112                true /* requireFullPermission */, false /* checkShell */,
24113                "get install reason");
24114        synchronized (mPackages) {
24115            final PackageSetting ps = mSettings.mPackages.get(packageName);
24116            if (ps != null) {
24117                return ps.getInstallReason(userId);
24118            }
24119        }
24120        return PackageManager.INSTALL_REASON_UNKNOWN;
24121    }
24122
24123    @Override
24124    public boolean canRequestPackageInstalls(String packageName, int userId) {
24125        return canRequestPackageInstallsInternal(packageName, 0, userId,
24126                true /* throwIfPermNotDeclared*/);
24127    }
24128
24129    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24130            boolean throwIfPermNotDeclared) {
24131        int callingUid = Binder.getCallingUid();
24132        int uid = getPackageUid(packageName, 0, userId);
24133        if (callingUid != uid && callingUid != Process.ROOT_UID
24134                && callingUid != Process.SYSTEM_UID) {
24135            throw new SecurityException(
24136                    "Caller uid " + callingUid + " does not own package " + packageName);
24137        }
24138        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24139        if (info == null) {
24140            return false;
24141        }
24142        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24143            return false;
24144        }
24145        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24146        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24147        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24148            if (throwIfPermNotDeclared) {
24149                throw new SecurityException("Need to declare " + appOpPermission
24150                        + " to call this api");
24151            } else {
24152                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24153                return false;
24154            }
24155        }
24156        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24157            return false;
24158        }
24159        if (mExternalSourcesPolicy != null) {
24160            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24161            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24162                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24163            }
24164        }
24165        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24166    }
24167
24168    @Override
24169    public ComponentName getInstantAppResolverSettingsComponent() {
24170        return mInstantAppResolverSettingsComponent;
24171    }
24172
24173    @Override
24174    public ComponentName getInstantAppInstallerComponent() {
24175        return mInstantAppInstallerActivity == null
24176                ? null : mInstantAppInstallerActivity.getComponentName();
24177    }
24178
24179    @Override
24180    public String getInstantAppAndroidId(String packageName, int userId) {
24181        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24182                "getInstantAppAndroidId");
24183        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24184                true /* requireFullPermission */, false /* checkShell */,
24185                "getInstantAppAndroidId");
24186        // Make sure the target is an Instant App.
24187        if (!isInstantApp(packageName, userId)) {
24188            return null;
24189        }
24190        synchronized (mPackages) {
24191            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24192        }
24193    }
24194}
24195
24196interface PackageSender {
24197    void sendPackageBroadcast(final String action, final String pkg,
24198        final Bundle extras, final int flags, final String targetPkg,
24199        final IIntentReceiver finishedReceiver, final int[] userIds);
24200    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
24201        int appId, int... userIds);
24202}
24203