PackageManagerService.java revision 947802e0b9842c48102153ef26373a21b6742145
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.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_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_NEWER_SDK;
51import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
52import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
56import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
57import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
58import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.isApkFile;
86import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
87import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
88import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
89import static android.system.OsConstants.O_CREAT;
90import static android.system.OsConstants.O_RDWR;
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
93import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
94import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
95import static com.android.internal.util.ArrayUtils.appendInt;
96import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
99import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
100import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
104import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
105import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
106import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
107import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
108import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
109import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
110import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
111import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
112import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
114import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
115
116import android.Manifest;
117import android.annotation.IntDef;
118import android.annotation.NonNull;
119import android.annotation.Nullable;
120import android.app.ActivityManager;
121import android.app.AppOpsManager;
122import android.app.IActivityManager;
123import android.app.ResourcesManager;
124import android.app.admin.IDevicePolicyManager;
125import android.app.admin.SecurityLog;
126import android.app.backup.IBackupManager;
127import android.content.BroadcastReceiver;
128import android.content.ComponentName;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.IIntentReceiver;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.IntentSender.SendIntentException;
136import android.content.ServiceConnection;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.AppsQueryHelper;
140import android.content.pm.AuxiliaryResolveInfo;
141import android.content.pm.ChangedPackages;
142import android.content.pm.ComponentInfo;
143import android.content.pm.FallbackCategoryProvider;
144import android.content.pm.FeatureInfo;
145import android.content.pm.IDexModuleRegisterCallback;
146import android.content.pm.IOnPermissionsChangeListener;
147import android.content.pm.IPackageDataObserver;
148import android.content.pm.IPackageDeleteObserver;
149import android.content.pm.IPackageDeleteObserver2;
150import android.content.pm.IPackageInstallObserver2;
151import android.content.pm.IPackageInstaller;
152import android.content.pm.IPackageManager;
153import android.content.pm.IPackageManagerNative;
154import android.content.pm.IPackageMoveObserver;
155import android.content.pm.IPackageStatsObserver;
156import android.content.pm.InstantAppInfo;
157import android.content.pm.InstantAppRequest;
158import android.content.pm.InstantAppResolveInfo;
159import android.content.pm.InstrumentationInfo;
160import android.content.pm.IntentFilterVerificationInfo;
161import android.content.pm.KeySet;
162import android.content.pm.PackageCleanItem;
163import android.content.pm.PackageInfo;
164import android.content.pm.PackageInfoLite;
165import android.content.pm.PackageInstaller;
166import android.content.pm.PackageManager;
167import android.content.pm.PackageManagerInternal;
168import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
169import android.content.pm.PackageManager.PackageInfoFlags;
170import android.content.pm.PackageParser;
171import android.content.pm.PackageParser.ActivityIntentInfo;
172import android.content.pm.PackageParser.Package;
173import android.content.pm.PackageParser.PackageLite;
174import android.content.pm.PackageParser.PackageParserException;
175import android.content.pm.PackageParser.ParseFlags;
176import android.content.pm.PackageStats;
177import android.content.pm.PackageUserState;
178import android.content.pm.ParceledListSlice;
179import android.content.pm.PermissionGroupInfo;
180import android.content.pm.PermissionInfo;
181import android.content.pm.ProviderInfo;
182import android.content.pm.ResolveInfo;
183import android.content.pm.ServiceInfo;
184import android.content.pm.SharedLibraryInfo;
185import android.content.pm.Signature;
186import android.content.pm.UserInfo;
187import android.content.pm.VerifierDeviceIdentity;
188import android.content.pm.VerifierInfo;
189import android.content.pm.VersionedPackage;
190import android.content.pm.dex.IArtManager;
191import android.content.res.Resources;
192import android.database.ContentObserver;
193import android.graphics.Bitmap;
194import android.hardware.display.DisplayManager;
195import android.net.Uri;
196import android.os.Binder;
197import android.os.Build;
198import android.os.Bundle;
199import android.os.Debug;
200import android.os.Environment;
201import android.os.Environment.UserEnvironment;
202import android.os.FileUtils;
203import android.os.Handler;
204import android.os.IBinder;
205import android.os.Looper;
206import android.os.Message;
207import android.os.Parcel;
208import android.os.ParcelFileDescriptor;
209import android.os.PatternMatcher;
210import android.os.Process;
211import android.os.RemoteCallbackList;
212import android.os.RemoteException;
213import android.os.ResultReceiver;
214import android.os.SELinux;
215import android.os.ServiceManager;
216import android.os.ShellCallback;
217import android.os.SystemClock;
218import android.os.SystemProperties;
219import android.os.Trace;
220import android.os.UserHandle;
221import android.os.UserManager;
222import android.os.UserManagerInternal;
223import android.os.storage.IStorageManager;
224import android.os.storage.StorageEventListener;
225import android.os.storage.StorageManager;
226import android.os.storage.StorageManagerInternal;
227import android.os.storage.VolumeInfo;
228import android.os.storage.VolumeRecord;
229import android.provider.Settings.Global;
230import android.provider.Settings.Secure;
231import android.security.KeyStore;
232import android.security.SystemKeyStore;
233import android.service.pm.PackageServiceDumpProto;
234import android.system.ErrnoException;
235import android.system.Os;
236import android.text.TextUtils;
237import android.text.format.DateUtils;
238import android.util.ArrayMap;
239import android.util.ArraySet;
240import android.util.Base64;
241import android.util.DisplayMetrics;
242import android.util.EventLog;
243import android.util.ExceptionUtils;
244import android.util.Log;
245import android.util.LogPrinter;
246import android.util.LongSparseArray;
247import android.util.LongSparseLongArray;
248import android.util.MathUtils;
249import android.util.PackageUtils;
250import android.util.Pair;
251import android.util.PrintStreamPrinter;
252import android.util.Slog;
253import android.util.SparseArray;
254import android.util.SparseBooleanArray;
255import android.util.SparseIntArray;
256import android.util.TimingsTraceLog;
257import android.util.Xml;
258import android.util.jar.StrictJarFile;
259import android.util.proto.ProtoOutputStream;
260import android.view.Display;
261
262import com.android.internal.R;
263import com.android.internal.annotations.GuardedBy;
264import com.android.internal.app.IMediaContainerService;
265import com.android.internal.app.ResolverActivity;
266import com.android.internal.content.NativeLibraryHelper;
267import com.android.internal.content.PackageHelper;
268import com.android.internal.logging.MetricsLogger;
269import com.android.internal.os.IParcelFileDescriptorFactory;
270import com.android.internal.os.SomeArgs;
271import com.android.internal.os.Zygote;
272import com.android.internal.telephony.CarrierAppUtils;
273import com.android.internal.util.ArrayUtils;
274import com.android.internal.util.ConcurrentUtils;
275import com.android.internal.util.DumpUtils;
276import com.android.internal.util.FastXmlSerializer;
277import com.android.internal.util.IndentingPrintWriter;
278import com.android.internal.util.Preconditions;
279import com.android.internal.util.XmlUtils;
280import com.android.server.AttributeCache;
281import com.android.server.DeviceIdleController;
282import com.android.server.EventLogTags;
283import com.android.server.FgThread;
284import com.android.server.IntentResolver;
285import com.android.server.LocalServices;
286import com.android.server.LockGuard;
287import com.android.server.ServiceThread;
288import com.android.server.SystemConfig;
289import com.android.server.SystemServerInitThreadPool;
290import com.android.server.Watchdog;
291import com.android.server.net.NetworkPolicyManagerInternal;
292import com.android.server.pm.Installer.InstallerException;
293import com.android.server.pm.Settings.DatabaseVersion;
294import com.android.server.pm.Settings.VersionInfo;
295import com.android.server.pm.dex.ArtManagerService;
296import com.android.server.pm.dex.DexLogger;
297import com.android.server.pm.dex.DexManager;
298import com.android.server.pm.dex.DexoptOptions;
299import com.android.server.pm.dex.PackageDexUsage;
300import com.android.server.pm.permission.BasePermission;
301import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
302import com.android.server.pm.permission.PermissionManagerService;
303import com.android.server.pm.permission.PermissionManagerInternal;
304import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
305import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
306import com.android.server.pm.permission.PermissionsState;
307import com.android.server.pm.permission.PermissionsState.PermissionState;
308import com.android.server.storage.DeviceStorageMonitorInternal;
309
310import dalvik.system.CloseGuard;
311import dalvik.system.VMRuntime;
312
313import libcore.io.IoUtils;
314
315import org.xmlpull.v1.XmlPullParser;
316import org.xmlpull.v1.XmlPullParserException;
317import org.xmlpull.v1.XmlSerializer;
318
319import java.io.BufferedOutputStream;
320import java.io.ByteArrayInputStream;
321import java.io.ByteArrayOutputStream;
322import java.io.File;
323import java.io.FileDescriptor;
324import java.io.FileInputStream;
325import java.io.FileOutputStream;
326import java.io.FilenameFilter;
327import java.io.IOException;
328import java.io.PrintWriter;
329import java.lang.annotation.Retention;
330import java.lang.annotation.RetentionPolicy;
331import java.nio.charset.StandardCharsets;
332import java.security.DigestInputStream;
333import java.security.MessageDigest;
334import java.security.NoSuchAlgorithmException;
335import java.security.PublicKey;
336import java.security.SecureRandom;
337import java.security.cert.Certificate;
338import java.security.cert.CertificateException;
339import java.util.ArrayList;
340import java.util.Arrays;
341import java.util.Collection;
342import java.util.Collections;
343import java.util.Comparator;
344import java.util.HashMap;
345import java.util.HashSet;
346import java.util.Iterator;
347import java.util.LinkedHashSet;
348import java.util.List;
349import java.util.Map;
350import java.util.Objects;
351import java.util.Set;
352import java.util.concurrent.CountDownLatch;
353import java.util.concurrent.Future;
354import java.util.concurrent.TimeUnit;
355import java.util.concurrent.atomic.AtomicBoolean;
356import java.util.concurrent.atomic.AtomicInteger;
357
358/**
359 * Keep track of all those APKs everywhere.
360 * <p>
361 * Internally there are two important locks:
362 * <ul>
363 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
364 * and other related state. It is a fine-grained lock that should only be held
365 * momentarily, as it's one of the most contended locks in the system.
366 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
367 * operations typically involve heavy lifting of application data on disk. Since
368 * {@code installd} is single-threaded, and it's operations can often be slow,
369 * this lock should never be acquired while already holding {@link #mPackages}.
370 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
371 * holding {@link #mInstallLock}.
372 * </ul>
373 * Many internal methods rely on the caller to hold the appropriate locks, and
374 * this contract is expressed through method name suffixes:
375 * <ul>
376 * <li>fooLI(): the caller must hold {@link #mInstallLock}
377 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
378 * being modified must be frozen
379 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
380 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
381 * </ul>
382 * <p>
383 * Because this class is very central to the platform's security; please run all
384 * CTS and unit tests whenever making modifications:
385 *
386 * <pre>
387 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
388 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
389 * </pre>
390 */
391public class PackageManagerService extends IPackageManager.Stub
392        implements PackageSender {
393    static final String TAG = "PackageManager";
394    public static final boolean DEBUG_SETTINGS = false;
395    static final boolean DEBUG_PREFERRED = false;
396    static final boolean DEBUG_UPGRADE = false;
397    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
398    private static final boolean DEBUG_BACKUP = false;
399    public static final boolean DEBUG_INSTALL = false;
400    public static final boolean DEBUG_REMOVE = false;
401    private static final boolean DEBUG_BROADCASTS = false;
402    private static final boolean DEBUG_SHOW_INFO = false;
403    private static final boolean DEBUG_PACKAGE_INFO = false;
404    private static final boolean DEBUG_INTENT_MATCHING = false;
405    public static final boolean DEBUG_PACKAGE_SCANNING = false;
406    private static final boolean DEBUG_VERIFY = false;
407    private static final boolean DEBUG_FILTERS = false;
408    public static final boolean DEBUG_PERMISSIONS = false;
409    private static final boolean DEBUG_SHARED_LIBRARIES = false;
410    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
411
412    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
413    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
414    // user, but by default initialize to this.
415    public static final boolean DEBUG_DEXOPT = false;
416
417    private static final boolean DEBUG_ABI_SELECTION = false;
418    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
419    private static final boolean DEBUG_TRIAGED_MISSING = false;
420    private static final boolean DEBUG_APP_DATA = false;
421
422    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
423    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
424
425    private static final boolean HIDE_EPHEMERAL_APIS = false;
426
427    private static final boolean ENABLE_FREE_CACHE_V2 =
428            SystemProperties.getBoolean("fw.free_cache_v2", true);
429
430    private static final int RADIO_UID = Process.PHONE_UID;
431    private static final int LOG_UID = Process.LOG_UID;
432    private static final int NFC_UID = Process.NFC_UID;
433    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
434    private static final int SHELL_UID = Process.SHELL_UID;
435
436    // Suffix used during package installation when copying/moving
437    // package apks to install directory.
438    private static final String INSTALL_PACKAGE_SUFFIX = "-";
439
440    static final int SCAN_NO_DEX = 1<<0;
441    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
442    static final int SCAN_NEW_INSTALL = 1<<2;
443    static final int SCAN_UPDATE_TIME = 1<<3;
444    static final int SCAN_BOOTING = 1<<4;
445    static final int SCAN_TRUSTED_OVERLAY = 1<<5;
446    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
447    static final int SCAN_REQUIRE_KNOWN = 1<<7;
448    static final int SCAN_MOVE = 1<<8;
449    static final int SCAN_INITIAL = 1<<9;
450    static final int SCAN_CHECK_ONLY = 1<<10;
451    static final int SCAN_DONT_KILL_APP = 1<<11;
452    static final int SCAN_IGNORE_FROZEN = 1<<12;
453    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
454    static final int SCAN_AS_INSTANT_APP = 1<<14;
455    static final int SCAN_AS_FULL_APP = 1<<15;
456    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
457    static final int SCAN_AS_SYSTEM = 1<<17;
458    static final int SCAN_AS_PRIVILEGED = 1<<18;
459    static final int SCAN_AS_OEM = 1<<19;
460    static final int SCAN_AS_VENDOR = 1<<20;
461
462    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
463            SCAN_NO_DEX,
464            SCAN_UPDATE_SIGNATURE,
465            SCAN_NEW_INSTALL,
466            SCAN_UPDATE_TIME,
467            SCAN_BOOTING,
468            SCAN_TRUSTED_OVERLAY,
469            SCAN_DELETE_DATA_ON_FAILURES,
470            SCAN_REQUIRE_KNOWN,
471            SCAN_MOVE,
472            SCAN_INITIAL,
473            SCAN_CHECK_ONLY,
474            SCAN_DONT_KILL_APP,
475            SCAN_IGNORE_FROZEN,
476            SCAN_FIRST_BOOT_OR_UPGRADE,
477            SCAN_AS_INSTANT_APP,
478            SCAN_AS_FULL_APP,
479            SCAN_AS_VIRTUAL_PRELOAD,
480    })
481    @Retention(RetentionPolicy.SOURCE)
482    public @interface ScanFlags {}
483
484    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
485    /** Extension of the compressed packages */
486    public final static String COMPRESSED_EXTENSION = ".gz";
487    /** Suffix of stub packages on the system partition */
488    public final static String STUB_SUFFIX = "-Stub";
489
490    private static final int[] EMPTY_INT_ARRAY = new int[0];
491
492    private static final int TYPE_UNKNOWN = 0;
493    private static final int TYPE_ACTIVITY = 1;
494    private static final int TYPE_RECEIVER = 2;
495    private static final int TYPE_SERVICE = 3;
496    private static final int TYPE_PROVIDER = 4;
497    @IntDef(prefix = { "TYPE_" }, value = {
498            TYPE_UNKNOWN,
499            TYPE_ACTIVITY,
500            TYPE_RECEIVER,
501            TYPE_SERVICE,
502            TYPE_PROVIDER,
503    })
504    @Retention(RetentionPolicy.SOURCE)
505    public @interface ComponentType {}
506
507    /**
508     * Timeout (in milliseconds) after which the watchdog should declare that
509     * our handler thread is wedged.  The usual default for such things is one
510     * minute but we sometimes do very lengthy I/O operations on this thread,
511     * such as installing multi-gigabyte applications, so ours needs to be longer.
512     */
513    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
514
515    /**
516     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
517     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
518     * settings entry if available, otherwise we use the hardcoded default.  If it's been
519     * more than this long since the last fstrim, we force one during the boot sequence.
520     *
521     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
522     * one gets run at the next available charging+idle time.  This final mandatory
523     * no-fstrim check kicks in only of the other scheduling criteria is never met.
524     */
525    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
526
527    /**
528     * Whether verification is enabled by default.
529     */
530    private static final boolean DEFAULT_VERIFY_ENABLE = true;
531
532    /**
533     * The default maximum time to wait for the verification agent to return in
534     * milliseconds.
535     */
536    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
537
538    /**
539     * The default response for package verification timeout.
540     *
541     * This can be either PackageManager.VERIFICATION_ALLOW or
542     * PackageManager.VERIFICATION_REJECT.
543     */
544    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
545
546    public static final String PLATFORM_PACKAGE_NAME = "android";
547
548    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
549
550    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
551            DEFAULT_CONTAINER_PACKAGE,
552            "com.android.defcontainer.DefaultContainerService");
553
554    private static final String KILL_APP_REASON_GIDS_CHANGED =
555            "permission grant or revoke changed gids";
556
557    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
558            "permissions revoked";
559
560    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
561
562    private static final String PACKAGE_SCHEME = "package";
563
564    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
565
566    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
567
568    /** Canonical intent used to identify what counts as a "web browser" app */
569    private static final Intent sBrowserIntent;
570    static {
571        sBrowserIntent = new Intent();
572        sBrowserIntent.setAction(Intent.ACTION_VIEW);
573        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
574        sBrowserIntent.setData(Uri.parse("http:"));
575    }
576
577    /**
578     * The set of all protected actions [i.e. those actions for which a high priority
579     * intent filter is disallowed].
580     */
581    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
582    static {
583        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
584        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
585        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
586        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
587    }
588
589    // Compilation reasons.
590    public static final int REASON_FIRST_BOOT = 0;
591    public static final int REASON_BOOT = 1;
592    public static final int REASON_INSTALL = 2;
593    public static final int REASON_BACKGROUND_DEXOPT = 3;
594    public static final int REASON_AB_OTA = 4;
595    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
596    public static final int REASON_SHARED = 6;
597
598    public static final int REASON_LAST = REASON_SHARED;
599
600    /**
601     * Version number for the package parser cache. Increment this whenever the format or
602     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
603     */
604    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
605
606    /**
607     * Whether the package parser cache is enabled.
608     */
609    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
610
611    /**
612     * Permissions required in order to receive instant application lifecycle broadcasts.
613     */
614    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
615            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
616
617    final ServiceThread mHandlerThread;
618
619    final PackageHandler mHandler;
620
621    private final ProcessLoggingHandler mProcessLoggingHandler;
622
623    /**
624     * Messages for {@link #mHandler} that need to wait for system ready before
625     * being dispatched.
626     */
627    private ArrayList<Message> mPostSystemReadyMessages;
628
629    final int mSdkVersion = Build.VERSION.SDK_INT;
630
631    final Context mContext;
632    final boolean mFactoryTest;
633    final boolean mOnlyCore;
634    final DisplayMetrics mMetrics;
635    final int mDefParseFlags;
636    final String[] mSeparateProcesses;
637    final boolean mIsUpgrade;
638    final boolean mIsPreNUpgrade;
639    final boolean mIsPreNMR1Upgrade;
640
641    // Have we told the Activity Manager to whitelist the default container service by uid yet?
642    @GuardedBy("mPackages")
643    boolean mDefaultContainerWhitelisted = false;
644
645    @GuardedBy("mPackages")
646    private boolean mDexOptDialogShown;
647
648    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
649    // LOCK HELD.  Can be called with mInstallLock held.
650    @GuardedBy("mInstallLock")
651    final Installer mInstaller;
652
653    /** Directory where installed applications are stored */
654    private static final File sAppInstallDir =
655            new File(Environment.getDataDirectory(), "app");
656    /** Directory where installed application's 32-bit native libraries are copied. */
657    private static final File sAppLib32InstallDir =
658            new File(Environment.getDataDirectory(), "app-lib");
659    /** Directory where code and non-resource assets of forward-locked applications are stored */
660    private static final File sDrmAppPrivateInstallDir =
661            new File(Environment.getDataDirectory(), "app-private");
662
663    // ----------------------------------------------------------------
664
665    // Lock for state used when installing and doing other long running
666    // operations.  Methods that must be called with this lock held have
667    // the suffix "LI".
668    final Object mInstallLock = new Object();
669
670    // ----------------------------------------------------------------
671
672    // Keys are String (package name), values are Package.  This also serves
673    // as the lock for the global state.  Methods that must be called with
674    // this lock held have the prefix "LP".
675    @GuardedBy("mPackages")
676    final ArrayMap<String, PackageParser.Package> mPackages =
677            new ArrayMap<String, PackageParser.Package>();
678
679    final ArrayMap<String, Set<String>> mKnownCodebase =
680            new ArrayMap<String, Set<String>>();
681
682    // Keys are isolated uids and values are the uid of the application
683    // that created the isolated proccess.
684    @GuardedBy("mPackages")
685    final SparseIntArray mIsolatedOwners = new SparseIntArray();
686
687    /**
688     * Tracks new system packages [received in an OTA] that we expect to
689     * find updated user-installed versions. Keys are package name, values
690     * are package location.
691     */
692    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
693    /**
694     * Tracks high priority intent filters for protected actions. During boot, certain
695     * filter actions are protected and should never be allowed to have a high priority
696     * intent filter for them. However, there is one, and only one exception -- the
697     * setup wizard. It must be able to define a high priority intent filter for these
698     * actions to ensure there are no escapes from the wizard. We need to delay processing
699     * of these during boot as we need to look at all of the system packages in order
700     * to know which component is the setup wizard.
701     */
702    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
703    /**
704     * Whether or not processing protected filters should be deferred.
705     */
706    private boolean mDeferProtectedFilters = true;
707
708    /**
709     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
710     */
711    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
712    /**
713     * Whether or not system app permissions should be promoted from install to runtime.
714     */
715    boolean mPromoteSystemApps;
716
717    @GuardedBy("mPackages")
718    final Settings mSettings;
719
720    /**
721     * Set of package names that are currently "frozen", which means active
722     * surgery is being done on the code/data for that package. The platform
723     * will refuse to launch frozen packages to avoid race conditions.
724     *
725     * @see PackageFreezer
726     */
727    @GuardedBy("mPackages")
728    final ArraySet<String> mFrozenPackages = new ArraySet<>();
729
730    final ProtectedPackages mProtectedPackages;
731
732    @GuardedBy("mLoadedVolumes")
733    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
734
735    boolean mFirstBoot;
736
737    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
738
739    @GuardedBy("mAvailableFeatures")
740    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
741
742    private final InstantAppRegistry mInstantAppRegistry;
743
744    @GuardedBy("mPackages")
745    int mChangedPackagesSequenceNumber;
746    /**
747     * List of changed [installed, removed or updated] packages.
748     * mapping from user id -> sequence number -> package name
749     */
750    @GuardedBy("mPackages")
751    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
752    /**
753     * The sequence number of the last change to a package.
754     * mapping from user id -> package name -> sequence number
755     */
756    @GuardedBy("mPackages")
757    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
758
759    class PackageParserCallback implements PackageParser.Callback {
760        @Override public final boolean hasFeature(String feature) {
761            return PackageManagerService.this.hasSystemFeature(feature, 0);
762        }
763
764        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
765                Collection<PackageParser.Package> allPackages, String targetPackageName) {
766            List<PackageParser.Package> overlayPackages = null;
767            for (PackageParser.Package p : allPackages) {
768                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
769                    if (overlayPackages == null) {
770                        overlayPackages = new ArrayList<PackageParser.Package>();
771                    }
772                    overlayPackages.add(p);
773                }
774            }
775            if (overlayPackages != null) {
776                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
777                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
778                        return p1.mOverlayPriority - p2.mOverlayPriority;
779                    }
780                };
781                Collections.sort(overlayPackages, cmp);
782            }
783            return overlayPackages;
784        }
785
786        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
787                String targetPackageName, String targetPath) {
788            if ("android".equals(targetPackageName)) {
789                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
790                // native AssetManager.
791                return null;
792            }
793            List<PackageParser.Package> overlayPackages =
794                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
795            if (overlayPackages == null || overlayPackages.isEmpty()) {
796                return null;
797            }
798            List<String> overlayPathList = null;
799            for (PackageParser.Package overlayPackage : overlayPackages) {
800                if (targetPath == null) {
801                    if (overlayPathList == null) {
802                        overlayPathList = new ArrayList<String>();
803                    }
804                    overlayPathList.add(overlayPackage.baseCodePath);
805                    continue;
806                }
807
808                try {
809                    // Creates idmaps for system to parse correctly the Android manifest of the
810                    // target package.
811                    //
812                    // OverlayManagerService will update each of them with a correct gid from its
813                    // target package app id.
814                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
815                            UserHandle.getSharedAppGid(
816                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
817                    if (overlayPathList == null) {
818                        overlayPathList = new ArrayList<String>();
819                    }
820                    overlayPathList.add(overlayPackage.baseCodePath);
821                } catch (InstallerException e) {
822                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
823                            overlayPackage.baseCodePath);
824                }
825            }
826            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
827        }
828
829        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
830            synchronized (mPackages) {
831                return getStaticOverlayPathsLocked(
832                        mPackages.values(), targetPackageName, targetPath);
833            }
834        }
835
836        @Override public final String[] getOverlayApks(String targetPackageName) {
837            return getStaticOverlayPaths(targetPackageName, null);
838        }
839
840        @Override public final String[] getOverlayPaths(String targetPackageName,
841                String targetPath) {
842            return getStaticOverlayPaths(targetPackageName, targetPath);
843        }
844    }
845
846    class ParallelPackageParserCallback extends PackageParserCallback {
847        List<PackageParser.Package> mOverlayPackages = null;
848
849        void findStaticOverlayPackages() {
850            synchronized (mPackages) {
851                for (PackageParser.Package p : mPackages.values()) {
852                    if (p.mIsStaticOverlay) {
853                        if (mOverlayPackages == null) {
854                            mOverlayPackages = new ArrayList<PackageParser.Package>();
855                        }
856                        mOverlayPackages.add(p);
857                    }
858                }
859            }
860        }
861
862        @Override
863        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
864            // We can trust mOverlayPackages without holding mPackages because package uninstall
865            // can't happen while running parallel parsing.
866            // Moreover holding mPackages on each parsing thread causes dead-lock.
867            return mOverlayPackages == null ? null :
868                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
869        }
870    }
871
872    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
873    final ParallelPackageParserCallback mParallelPackageParserCallback =
874            new ParallelPackageParserCallback();
875
876    public static final class SharedLibraryEntry {
877        public final @Nullable String path;
878        public final @Nullable String apk;
879        public final @NonNull SharedLibraryInfo info;
880
881        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
882                String declaringPackageName, long declaringPackageVersionCode) {
883            path = _path;
884            apk = _apk;
885            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
886                    declaringPackageName, declaringPackageVersionCode), null);
887        }
888    }
889
890    // Currently known shared libraries.
891    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
892    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
893            new ArrayMap<>();
894
895    // All available activities, for your resolving pleasure.
896    final ActivityIntentResolver mActivities =
897            new ActivityIntentResolver();
898
899    // All available receivers, for your resolving pleasure.
900    final ActivityIntentResolver mReceivers =
901            new ActivityIntentResolver();
902
903    // All available services, for your resolving pleasure.
904    final ServiceIntentResolver mServices = new ServiceIntentResolver();
905
906    // All available providers, for your resolving pleasure.
907    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
908
909    // Mapping from provider base names (first directory in content URI codePath)
910    // to the provider information.
911    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
912            new ArrayMap<String, PackageParser.Provider>();
913
914    // Mapping from instrumentation class names to info about them.
915    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
916            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
917
918    // Packages whose data we have transfered into another package, thus
919    // should no longer exist.
920    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
921
922    // Broadcast actions that are only available to the system.
923    @GuardedBy("mProtectedBroadcasts")
924    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
925
926    /** List of packages waiting for verification. */
927    final SparseArray<PackageVerificationState> mPendingVerification
928            = new SparseArray<PackageVerificationState>();
929
930    final PackageInstallerService mInstallerService;
931
932    final ArtManagerService mArtManagerService;
933
934    private final PackageDexOptimizer mPackageDexOptimizer;
935    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
936    // is used by other apps).
937    private final DexManager mDexManager;
938
939    private AtomicInteger mNextMoveId = new AtomicInteger();
940    private final MoveCallbacks mMoveCallbacks;
941
942    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
943
944    // Cache of users who need badging.
945    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
946
947    /** Token for keys in mPendingVerification. */
948    private int mPendingVerificationToken = 0;
949
950    volatile boolean mSystemReady;
951    volatile boolean mSafeMode;
952    volatile boolean mHasSystemUidErrors;
953    private volatile boolean mEphemeralAppsDisabled;
954
955    ApplicationInfo mAndroidApplication;
956    final ActivityInfo mResolveActivity = new ActivityInfo();
957    final ResolveInfo mResolveInfo = new ResolveInfo();
958    ComponentName mResolveComponentName;
959    PackageParser.Package mPlatformPackage;
960    ComponentName mCustomResolverComponentName;
961
962    boolean mResolverReplaced = false;
963
964    private final @Nullable ComponentName mIntentFilterVerifierComponent;
965    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
966
967    private int mIntentFilterVerificationToken = 0;
968
969    /** The service connection to the ephemeral resolver */
970    final EphemeralResolverConnection mInstantAppResolverConnection;
971    /** Component used to show resolver settings for Instant Apps */
972    final ComponentName mInstantAppResolverSettingsComponent;
973
974    /** Activity used to install instant applications */
975    ActivityInfo mInstantAppInstallerActivity;
976    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
977
978    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
979            = new SparseArray<IntentFilterVerificationState>();
980
981    // TODO remove this and go through mPermissonManager directly
982    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
983    private final PermissionManagerInternal mPermissionManager;
984
985    // List of packages names to keep cached, even if they are uninstalled for all users
986    private List<String> mKeepUninstalledPackages;
987
988    private UserManagerInternal mUserManagerInternal;
989
990    private DeviceIdleController.LocalService mDeviceIdleController;
991
992    private File mCacheDir;
993
994    private Future<?> mPrepareAppDataFuture;
995
996    private static class IFVerificationParams {
997        PackageParser.Package pkg;
998        boolean replacing;
999        int userId;
1000        int verifierUid;
1001
1002        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1003                int _userId, int _verifierUid) {
1004            pkg = _pkg;
1005            replacing = _replacing;
1006            userId = _userId;
1007            replacing = _replacing;
1008            verifierUid = _verifierUid;
1009        }
1010    }
1011
1012    private interface IntentFilterVerifier<T extends IntentFilter> {
1013        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1014                                               T filter, String packageName);
1015        void startVerifications(int userId);
1016        void receiveVerificationResponse(int verificationId);
1017    }
1018
1019    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1020        private Context mContext;
1021        private ComponentName mIntentFilterVerifierComponent;
1022        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1023
1024        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1025            mContext = context;
1026            mIntentFilterVerifierComponent = verifierComponent;
1027        }
1028
1029        private String getDefaultScheme() {
1030            return IntentFilter.SCHEME_HTTPS;
1031        }
1032
1033        @Override
1034        public void startVerifications(int userId) {
1035            // Launch verifications requests
1036            int count = mCurrentIntentFilterVerifications.size();
1037            for (int n=0; n<count; n++) {
1038                int verificationId = mCurrentIntentFilterVerifications.get(n);
1039                final IntentFilterVerificationState ivs =
1040                        mIntentFilterVerificationStates.get(verificationId);
1041
1042                String packageName = ivs.getPackageName();
1043
1044                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1045                final int filterCount = filters.size();
1046                ArraySet<String> domainsSet = new ArraySet<>();
1047                for (int m=0; m<filterCount; m++) {
1048                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1049                    domainsSet.addAll(filter.getHostsList());
1050                }
1051                synchronized (mPackages) {
1052                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1053                            packageName, domainsSet) != null) {
1054                        scheduleWriteSettingsLocked();
1055                    }
1056                }
1057                sendVerificationRequest(verificationId, ivs);
1058            }
1059            mCurrentIntentFilterVerifications.clear();
1060        }
1061
1062        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1063            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1064            verificationIntent.putExtra(
1065                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1066                    verificationId);
1067            verificationIntent.putExtra(
1068                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1069                    getDefaultScheme());
1070            verificationIntent.putExtra(
1071                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1072                    ivs.getHostsString());
1073            verificationIntent.putExtra(
1074                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1075                    ivs.getPackageName());
1076            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1077            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1078
1079            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1080            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1081                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1082                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1083
1084            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1085            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1086                    "Sending IntentFilter verification broadcast");
1087        }
1088
1089        public void receiveVerificationResponse(int verificationId) {
1090            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1091
1092            final boolean verified = ivs.isVerified();
1093
1094            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1095            final int count = filters.size();
1096            if (DEBUG_DOMAIN_VERIFICATION) {
1097                Slog.i(TAG, "Received verification response " + verificationId
1098                        + " for " + count + " filters, verified=" + verified);
1099            }
1100            for (int n=0; n<count; n++) {
1101                PackageParser.ActivityIntentInfo filter = filters.get(n);
1102                filter.setVerified(verified);
1103
1104                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1105                        + " verified with result:" + verified + " and hosts:"
1106                        + ivs.getHostsString());
1107            }
1108
1109            mIntentFilterVerificationStates.remove(verificationId);
1110
1111            final String packageName = ivs.getPackageName();
1112            IntentFilterVerificationInfo ivi = null;
1113
1114            synchronized (mPackages) {
1115                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1116            }
1117            if (ivi == null) {
1118                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1119                        + verificationId + " packageName:" + packageName);
1120                return;
1121            }
1122            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1123                    "Updating IntentFilterVerificationInfo for package " + packageName
1124                            +" verificationId:" + verificationId);
1125
1126            synchronized (mPackages) {
1127                if (verified) {
1128                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1129                } else {
1130                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1131                }
1132                scheduleWriteSettingsLocked();
1133
1134                final int userId = ivs.getUserId();
1135                if (userId != UserHandle.USER_ALL) {
1136                    final int userStatus =
1137                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1138
1139                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1140                    boolean needUpdate = false;
1141
1142                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1143                    // already been set by the User thru the Disambiguation dialog
1144                    switch (userStatus) {
1145                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1146                            if (verified) {
1147                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1148                            } else {
1149                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1150                            }
1151                            needUpdate = true;
1152                            break;
1153
1154                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1155                            if (verified) {
1156                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1157                                needUpdate = true;
1158                            }
1159                            break;
1160
1161                        default:
1162                            // Nothing to do
1163                    }
1164
1165                    if (needUpdate) {
1166                        mSettings.updateIntentFilterVerificationStatusLPw(
1167                                packageName, updatedStatus, userId);
1168                        scheduleWritePackageRestrictionsLocked(userId);
1169                    }
1170                }
1171            }
1172        }
1173
1174        @Override
1175        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1176                    ActivityIntentInfo filter, String packageName) {
1177            if (!hasValidDomains(filter)) {
1178                return false;
1179            }
1180            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1181            if (ivs == null) {
1182                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1183                        packageName);
1184            }
1185            if (DEBUG_DOMAIN_VERIFICATION) {
1186                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1187            }
1188            ivs.addFilter(filter);
1189            return true;
1190        }
1191
1192        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1193                int userId, int verificationId, String packageName) {
1194            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1195                    verifierUid, userId, packageName);
1196            ivs.setPendingState();
1197            synchronized (mPackages) {
1198                mIntentFilterVerificationStates.append(verificationId, ivs);
1199                mCurrentIntentFilterVerifications.add(verificationId);
1200            }
1201            return ivs;
1202        }
1203    }
1204
1205    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1206        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1207                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1208                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1209    }
1210
1211    // Set of pending broadcasts for aggregating enable/disable of components.
1212    static class PendingPackageBroadcasts {
1213        // for each user id, a map of <package name -> components within that package>
1214        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1215
1216        public PendingPackageBroadcasts() {
1217            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1218        }
1219
1220        public ArrayList<String> get(int userId, String packageName) {
1221            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1222            return packages.get(packageName);
1223        }
1224
1225        public void put(int userId, String packageName, ArrayList<String> components) {
1226            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1227            packages.put(packageName, components);
1228        }
1229
1230        public void remove(int userId, String packageName) {
1231            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1232            if (packages != null) {
1233                packages.remove(packageName);
1234            }
1235        }
1236
1237        public void remove(int userId) {
1238            mUidMap.remove(userId);
1239        }
1240
1241        public int userIdCount() {
1242            return mUidMap.size();
1243        }
1244
1245        public int userIdAt(int n) {
1246            return mUidMap.keyAt(n);
1247        }
1248
1249        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1250            return mUidMap.get(userId);
1251        }
1252
1253        public int size() {
1254            // total number of pending broadcast entries across all userIds
1255            int num = 0;
1256            for (int i = 0; i< mUidMap.size(); i++) {
1257                num += mUidMap.valueAt(i).size();
1258            }
1259            return num;
1260        }
1261
1262        public void clear() {
1263            mUidMap.clear();
1264        }
1265
1266        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1267            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1268            if (map == null) {
1269                map = new ArrayMap<String, ArrayList<String>>();
1270                mUidMap.put(userId, map);
1271            }
1272            return map;
1273        }
1274    }
1275    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1276
1277    // Service Connection to remote media container service to copy
1278    // package uri's from external media onto secure containers
1279    // or internal storage.
1280    private IMediaContainerService mContainerService = null;
1281
1282    static final int SEND_PENDING_BROADCAST = 1;
1283    static final int MCS_BOUND = 3;
1284    static final int END_COPY = 4;
1285    static final int INIT_COPY = 5;
1286    static final int MCS_UNBIND = 6;
1287    static final int START_CLEANING_PACKAGE = 7;
1288    static final int FIND_INSTALL_LOC = 8;
1289    static final int POST_INSTALL = 9;
1290    static final int MCS_RECONNECT = 10;
1291    static final int MCS_GIVE_UP = 11;
1292    static final int WRITE_SETTINGS = 13;
1293    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1294    static final int PACKAGE_VERIFIED = 15;
1295    static final int CHECK_PENDING_VERIFICATION = 16;
1296    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1297    static final int INTENT_FILTER_VERIFIED = 18;
1298    static final int WRITE_PACKAGE_LIST = 19;
1299    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1300
1301    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1302
1303    // Delay time in millisecs
1304    static final int BROADCAST_DELAY = 10 * 1000;
1305
1306    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1307            2 * 60 * 60 * 1000L; /* two hours */
1308
1309    static UserManagerService sUserManager;
1310
1311    // Stores a list of users whose package restrictions file needs to be updated
1312    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1313
1314    final private DefaultContainerConnection mDefContainerConn =
1315            new DefaultContainerConnection();
1316    class DefaultContainerConnection implements ServiceConnection {
1317        public void onServiceConnected(ComponentName name, IBinder service) {
1318            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1319            final IMediaContainerService imcs = IMediaContainerService.Stub
1320                    .asInterface(Binder.allowBlocking(service));
1321            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1322        }
1323
1324        public void onServiceDisconnected(ComponentName name) {
1325            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1326        }
1327    }
1328
1329    // Recordkeeping of restore-after-install operations that are currently in flight
1330    // between the Package Manager and the Backup Manager
1331    static class PostInstallData {
1332        public InstallArgs args;
1333        public PackageInstalledInfo res;
1334
1335        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1336            args = _a;
1337            res = _r;
1338        }
1339    }
1340
1341    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1342    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1343
1344    // XML tags for backup/restore of various bits of state
1345    private static final String TAG_PREFERRED_BACKUP = "pa";
1346    private static final String TAG_DEFAULT_APPS = "da";
1347    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1348
1349    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1350    private static final String TAG_ALL_GRANTS = "rt-grants";
1351    private static final String TAG_GRANT = "grant";
1352    private static final String ATTR_PACKAGE_NAME = "pkg";
1353
1354    private static final String TAG_PERMISSION = "perm";
1355    private static final String ATTR_PERMISSION_NAME = "name";
1356    private static final String ATTR_IS_GRANTED = "g";
1357    private static final String ATTR_USER_SET = "set";
1358    private static final String ATTR_USER_FIXED = "fixed";
1359    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1360
1361    // System/policy permission grants are not backed up
1362    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1363            FLAG_PERMISSION_POLICY_FIXED
1364            | FLAG_PERMISSION_SYSTEM_FIXED
1365            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1366
1367    // And we back up these user-adjusted states
1368    private static final int USER_RUNTIME_GRANT_MASK =
1369            FLAG_PERMISSION_USER_SET
1370            | FLAG_PERMISSION_USER_FIXED
1371            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1372
1373    final @Nullable String mRequiredVerifierPackage;
1374    final @NonNull String mRequiredInstallerPackage;
1375    final @NonNull String mRequiredUninstallerPackage;
1376    final @Nullable String mSetupWizardPackage;
1377    final @Nullable String mStorageManagerPackage;
1378    final @NonNull String mServicesSystemSharedLibraryPackageName;
1379    final @NonNull String mSharedSystemSharedLibraryPackageName;
1380
1381    private final PackageUsage mPackageUsage = new PackageUsage();
1382    private final CompilerStats mCompilerStats = new CompilerStats();
1383
1384    class PackageHandler extends Handler {
1385        private boolean mBound = false;
1386        final ArrayList<HandlerParams> mPendingInstalls =
1387            new ArrayList<HandlerParams>();
1388
1389        private boolean connectToService() {
1390            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1391                    " DefaultContainerService");
1392            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1393            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1394            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1395                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1396                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1397                mBound = true;
1398                return true;
1399            }
1400            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1401            return false;
1402        }
1403
1404        private void disconnectService() {
1405            mContainerService = null;
1406            mBound = false;
1407            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1408            mContext.unbindService(mDefContainerConn);
1409            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1410        }
1411
1412        PackageHandler(Looper looper) {
1413            super(looper);
1414        }
1415
1416        public void handleMessage(Message msg) {
1417            try {
1418                doHandleMessage(msg);
1419            } finally {
1420                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1421            }
1422        }
1423
1424        void doHandleMessage(Message msg) {
1425            switch (msg.what) {
1426                case INIT_COPY: {
1427                    HandlerParams params = (HandlerParams) msg.obj;
1428                    int idx = mPendingInstalls.size();
1429                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1430                    // If a bind was already initiated we dont really
1431                    // need to do anything. The pending install
1432                    // will be processed later on.
1433                    if (!mBound) {
1434                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1435                                System.identityHashCode(mHandler));
1436                        // If this is the only one pending we might
1437                        // have to bind to the service again.
1438                        if (!connectToService()) {
1439                            Slog.e(TAG, "Failed to bind to media container service");
1440                            params.serviceError();
1441                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1442                                    System.identityHashCode(mHandler));
1443                            if (params.traceMethod != null) {
1444                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1445                                        params.traceCookie);
1446                            }
1447                            return;
1448                        } else {
1449                            // Once we bind to the service, the first
1450                            // pending request will be processed.
1451                            mPendingInstalls.add(idx, params);
1452                        }
1453                    } else {
1454                        mPendingInstalls.add(idx, params);
1455                        // Already bound to the service. Just make
1456                        // sure we trigger off processing the first request.
1457                        if (idx == 0) {
1458                            mHandler.sendEmptyMessage(MCS_BOUND);
1459                        }
1460                    }
1461                    break;
1462                }
1463                case MCS_BOUND: {
1464                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1465                    if (msg.obj != null) {
1466                        mContainerService = (IMediaContainerService) msg.obj;
1467                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1468                                System.identityHashCode(mHandler));
1469                    }
1470                    if (mContainerService == null) {
1471                        if (!mBound) {
1472                            // Something seriously wrong since we are not bound and we are not
1473                            // waiting for connection. Bail out.
1474                            Slog.e(TAG, "Cannot bind to media container service");
1475                            for (HandlerParams params : mPendingInstalls) {
1476                                // Indicate service bind error
1477                                params.serviceError();
1478                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1479                                        System.identityHashCode(params));
1480                                if (params.traceMethod != null) {
1481                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1482                                            params.traceMethod, params.traceCookie);
1483                                }
1484                                return;
1485                            }
1486                            mPendingInstalls.clear();
1487                        } else {
1488                            Slog.w(TAG, "Waiting to connect to media container service");
1489                        }
1490                    } else if (mPendingInstalls.size() > 0) {
1491                        HandlerParams params = mPendingInstalls.get(0);
1492                        if (params != null) {
1493                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1494                                    System.identityHashCode(params));
1495                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1496                            if (params.startCopy()) {
1497                                // We are done...  look for more work or to
1498                                // go idle.
1499                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1500                                        "Checking for more work or unbind...");
1501                                // Delete pending install
1502                                if (mPendingInstalls.size() > 0) {
1503                                    mPendingInstalls.remove(0);
1504                                }
1505                                if (mPendingInstalls.size() == 0) {
1506                                    if (mBound) {
1507                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1508                                                "Posting delayed MCS_UNBIND");
1509                                        removeMessages(MCS_UNBIND);
1510                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1511                                        // Unbind after a little delay, to avoid
1512                                        // continual thrashing.
1513                                        sendMessageDelayed(ubmsg, 10000);
1514                                    }
1515                                } else {
1516                                    // There are more pending requests in queue.
1517                                    // Just post MCS_BOUND message to trigger processing
1518                                    // of next pending install.
1519                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1520                                            "Posting MCS_BOUND for next work");
1521                                    mHandler.sendEmptyMessage(MCS_BOUND);
1522                                }
1523                            }
1524                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1525                        }
1526                    } else {
1527                        // Should never happen ideally.
1528                        Slog.w(TAG, "Empty queue");
1529                    }
1530                    break;
1531                }
1532                case MCS_RECONNECT: {
1533                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1534                    if (mPendingInstalls.size() > 0) {
1535                        if (mBound) {
1536                            disconnectService();
1537                        }
1538                        if (!connectToService()) {
1539                            Slog.e(TAG, "Failed to bind to media container service");
1540                            for (HandlerParams params : mPendingInstalls) {
1541                                // Indicate service bind error
1542                                params.serviceError();
1543                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1544                                        System.identityHashCode(params));
1545                            }
1546                            mPendingInstalls.clear();
1547                        }
1548                    }
1549                    break;
1550                }
1551                case MCS_UNBIND: {
1552                    // If there is no actual work left, then time to unbind.
1553                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1554
1555                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1556                        if (mBound) {
1557                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1558
1559                            disconnectService();
1560                        }
1561                    } else if (mPendingInstalls.size() > 0) {
1562                        // There are more pending requests in queue.
1563                        // Just post MCS_BOUND message to trigger processing
1564                        // of next pending install.
1565                        mHandler.sendEmptyMessage(MCS_BOUND);
1566                    }
1567
1568                    break;
1569                }
1570                case MCS_GIVE_UP: {
1571                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1572                    HandlerParams params = mPendingInstalls.remove(0);
1573                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1574                            System.identityHashCode(params));
1575                    break;
1576                }
1577                case SEND_PENDING_BROADCAST: {
1578                    String packages[];
1579                    ArrayList<String> components[];
1580                    int size = 0;
1581                    int uids[];
1582                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1583                    synchronized (mPackages) {
1584                        if (mPendingBroadcasts == null) {
1585                            return;
1586                        }
1587                        size = mPendingBroadcasts.size();
1588                        if (size <= 0) {
1589                            // Nothing to be done. Just return
1590                            return;
1591                        }
1592                        packages = new String[size];
1593                        components = new ArrayList[size];
1594                        uids = new int[size];
1595                        int i = 0;  // filling out the above arrays
1596
1597                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1598                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1599                            Iterator<Map.Entry<String, ArrayList<String>>> it
1600                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1601                                            .entrySet().iterator();
1602                            while (it.hasNext() && i < size) {
1603                                Map.Entry<String, ArrayList<String>> ent = it.next();
1604                                packages[i] = ent.getKey();
1605                                components[i] = ent.getValue();
1606                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1607                                uids[i] = (ps != null)
1608                                        ? UserHandle.getUid(packageUserId, ps.appId)
1609                                        : -1;
1610                                i++;
1611                            }
1612                        }
1613                        size = i;
1614                        mPendingBroadcasts.clear();
1615                    }
1616                    // Send broadcasts
1617                    for (int i = 0; i < size; i++) {
1618                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1619                    }
1620                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1621                    break;
1622                }
1623                case START_CLEANING_PACKAGE: {
1624                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1625                    final String packageName = (String)msg.obj;
1626                    final int userId = msg.arg1;
1627                    final boolean andCode = msg.arg2 != 0;
1628                    synchronized (mPackages) {
1629                        if (userId == UserHandle.USER_ALL) {
1630                            int[] users = sUserManager.getUserIds();
1631                            for (int user : users) {
1632                                mSettings.addPackageToCleanLPw(
1633                                        new PackageCleanItem(user, packageName, andCode));
1634                            }
1635                        } else {
1636                            mSettings.addPackageToCleanLPw(
1637                                    new PackageCleanItem(userId, packageName, andCode));
1638                        }
1639                    }
1640                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1641                    startCleaningPackages();
1642                } break;
1643                case POST_INSTALL: {
1644                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1645
1646                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1647                    final boolean didRestore = (msg.arg2 != 0);
1648                    mRunningInstalls.delete(msg.arg1);
1649
1650                    if (data != null) {
1651                        InstallArgs args = data.args;
1652                        PackageInstalledInfo parentRes = data.res;
1653
1654                        final boolean grantPermissions = (args.installFlags
1655                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1656                        final boolean killApp = (args.installFlags
1657                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1658                        final boolean virtualPreload = ((args.installFlags
1659                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1660                        final String[] grantedPermissions = args.installGrantPermissions;
1661
1662                        // Handle the parent package
1663                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1664                                virtualPreload, grantedPermissions, didRestore,
1665                                args.installerPackageName, args.observer);
1666
1667                        // Handle the child packages
1668                        final int childCount = (parentRes.addedChildPackages != null)
1669                                ? parentRes.addedChildPackages.size() : 0;
1670                        for (int i = 0; i < childCount; i++) {
1671                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1672                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1673                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1674                                    args.installerPackageName, args.observer);
1675                        }
1676
1677                        // Log tracing if needed
1678                        if (args.traceMethod != null) {
1679                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1680                                    args.traceCookie);
1681                        }
1682                    } else {
1683                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1684                    }
1685
1686                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1687                } break;
1688                case WRITE_SETTINGS: {
1689                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1690                    synchronized (mPackages) {
1691                        removeMessages(WRITE_SETTINGS);
1692                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1693                        mSettings.writeLPr();
1694                        mDirtyUsers.clear();
1695                    }
1696                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1697                } break;
1698                case WRITE_PACKAGE_RESTRICTIONS: {
1699                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1700                    synchronized (mPackages) {
1701                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1702                        for (int userId : mDirtyUsers) {
1703                            mSettings.writePackageRestrictionsLPr(userId);
1704                        }
1705                        mDirtyUsers.clear();
1706                    }
1707                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1708                } break;
1709                case WRITE_PACKAGE_LIST: {
1710                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1711                    synchronized (mPackages) {
1712                        removeMessages(WRITE_PACKAGE_LIST);
1713                        mSettings.writePackageListLPr(msg.arg1);
1714                    }
1715                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1716                } break;
1717                case CHECK_PENDING_VERIFICATION: {
1718                    final int verificationId = msg.arg1;
1719                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1720
1721                    if ((state != null) && !state.timeoutExtended()) {
1722                        final InstallArgs args = state.getInstallArgs();
1723                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1724
1725                        Slog.i(TAG, "Verification timed out for " + originUri);
1726                        mPendingVerification.remove(verificationId);
1727
1728                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1729
1730                        final UserHandle user = args.getUser();
1731                        if (getDefaultVerificationResponse(user)
1732                                == PackageManager.VERIFICATION_ALLOW) {
1733                            Slog.i(TAG, "Continuing with installation of " + originUri);
1734                            state.setVerifierResponse(Binder.getCallingUid(),
1735                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1736                            broadcastPackageVerified(verificationId, originUri,
1737                                    PackageManager.VERIFICATION_ALLOW, user);
1738                            try {
1739                                ret = args.copyApk(mContainerService, true);
1740                            } catch (RemoteException e) {
1741                                Slog.e(TAG, "Could not contact the ContainerService");
1742                            }
1743                        } else {
1744                            broadcastPackageVerified(verificationId, originUri,
1745                                    PackageManager.VERIFICATION_REJECT, user);
1746                        }
1747
1748                        Trace.asyncTraceEnd(
1749                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1750
1751                        processPendingInstall(args, ret);
1752                        mHandler.sendEmptyMessage(MCS_UNBIND);
1753                    }
1754                    break;
1755                }
1756                case PACKAGE_VERIFIED: {
1757                    final int verificationId = msg.arg1;
1758
1759                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1760                    if (state == null) {
1761                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1762                        break;
1763                    }
1764
1765                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1766
1767                    state.setVerifierResponse(response.callerUid, response.code);
1768
1769                    if (state.isVerificationComplete()) {
1770                        mPendingVerification.remove(verificationId);
1771
1772                        final InstallArgs args = state.getInstallArgs();
1773                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1774
1775                        int ret;
1776                        if (state.isInstallAllowed()) {
1777                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1778                            broadcastPackageVerified(verificationId, originUri,
1779                                    response.code, state.getInstallArgs().getUser());
1780                            try {
1781                                ret = args.copyApk(mContainerService, true);
1782                            } catch (RemoteException e) {
1783                                Slog.e(TAG, "Could not contact the ContainerService");
1784                            }
1785                        } else {
1786                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1787                        }
1788
1789                        Trace.asyncTraceEnd(
1790                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1791
1792                        processPendingInstall(args, ret);
1793                        mHandler.sendEmptyMessage(MCS_UNBIND);
1794                    }
1795
1796                    break;
1797                }
1798                case START_INTENT_FILTER_VERIFICATIONS: {
1799                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1800                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1801                            params.replacing, params.pkg);
1802                    break;
1803                }
1804                case INTENT_FILTER_VERIFIED: {
1805                    final int verificationId = msg.arg1;
1806
1807                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1808                            verificationId);
1809                    if (state == null) {
1810                        Slog.w(TAG, "Invalid IntentFilter verification token "
1811                                + verificationId + " received");
1812                        break;
1813                    }
1814
1815                    final int userId = state.getUserId();
1816
1817                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1818                            "Processing IntentFilter verification with token:"
1819                            + verificationId + " and userId:" + userId);
1820
1821                    final IntentFilterVerificationResponse response =
1822                            (IntentFilterVerificationResponse) msg.obj;
1823
1824                    state.setVerifierResponse(response.callerUid, response.code);
1825
1826                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1827                            "IntentFilter verification with token:" + verificationId
1828                            + " and userId:" + userId
1829                            + " is settings verifier response with response code:"
1830                            + response.code);
1831
1832                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1833                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1834                                + response.getFailedDomainsString());
1835                    }
1836
1837                    if (state.isVerificationComplete()) {
1838                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1839                    } else {
1840                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1841                                "IntentFilter verification with token:" + verificationId
1842                                + " was not said to be complete");
1843                    }
1844
1845                    break;
1846                }
1847                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1848                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1849                            mInstantAppResolverConnection,
1850                            (InstantAppRequest) msg.obj,
1851                            mInstantAppInstallerActivity,
1852                            mHandler);
1853                }
1854            }
1855        }
1856    }
1857
1858    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1859        @Override
1860        public void onGidsChanged(int appId, int userId) {
1861            mHandler.post(new Runnable() {
1862                @Override
1863                public void run() {
1864                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1865                }
1866            });
1867        }
1868        @Override
1869        public void onPermissionGranted(int uid, int userId) {
1870            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1871
1872            // Not critical; if this is lost, the application has to request again.
1873            synchronized (mPackages) {
1874                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1875            }
1876        }
1877        @Override
1878        public void onInstallPermissionGranted() {
1879            synchronized (mPackages) {
1880                scheduleWriteSettingsLocked();
1881            }
1882        }
1883        @Override
1884        public void onPermissionRevoked(int uid, int userId) {
1885            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1886
1887            synchronized (mPackages) {
1888                // Critical; after this call the application should never have the permission
1889                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1890            }
1891
1892            final int appId = UserHandle.getAppId(uid);
1893            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1894        }
1895        @Override
1896        public void onInstallPermissionRevoked() {
1897            synchronized (mPackages) {
1898                scheduleWriteSettingsLocked();
1899            }
1900        }
1901        @Override
1902        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1903            synchronized (mPackages) {
1904                for (int userId : updatedUserIds) {
1905                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1906                }
1907            }
1908        }
1909        @Override
1910        public void onInstallPermissionUpdated() {
1911            synchronized (mPackages) {
1912                scheduleWriteSettingsLocked();
1913            }
1914        }
1915        @Override
1916        public void onPermissionRemoved() {
1917            synchronized (mPackages) {
1918                mSettings.writeLPr();
1919            }
1920        }
1921    };
1922
1923    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1924            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1925            boolean launchedForRestore, String installerPackage,
1926            IPackageInstallObserver2 installObserver) {
1927        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1928            // Send the removed broadcasts
1929            if (res.removedInfo != null) {
1930                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1931            }
1932
1933            // Now that we successfully installed the package, grant runtime
1934            // permissions if requested before broadcasting the install. Also
1935            // for legacy apps in permission review mode we clear the permission
1936            // review flag which is used to emulate runtime permissions for
1937            // legacy apps.
1938            if (grantPermissions) {
1939                final int callingUid = Binder.getCallingUid();
1940                mPermissionManager.grantRequestedRuntimePermissions(
1941                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1942                        mPermissionCallback);
1943            }
1944
1945            final boolean update = res.removedInfo != null
1946                    && res.removedInfo.removedPackage != null;
1947            final String installerPackageName =
1948                    res.installerPackageName != null
1949                            ? res.installerPackageName
1950                            : res.removedInfo != null
1951                                    ? res.removedInfo.installerPackageName
1952                                    : null;
1953
1954            // If this is the first time we have child packages for a disabled privileged
1955            // app that had no children, we grant requested runtime permissions to the new
1956            // children if the parent on the system image had them already granted.
1957            if (res.pkg.parentPackage != null) {
1958                final int callingUid = Binder.getCallingUid();
1959                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1960                        res.pkg, callingUid, mPermissionCallback);
1961            }
1962
1963            synchronized (mPackages) {
1964                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1965            }
1966
1967            final String packageName = res.pkg.applicationInfo.packageName;
1968
1969            // Determine the set of users who are adding this package for
1970            // the first time vs. those who are seeing an update.
1971            int[] firstUserIds = EMPTY_INT_ARRAY;
1972            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1973            int[] updateUserIds = EMPTY_INT_ARRAY;
1974            int[] instantUserIds = EMPTY_INT_ARRAY;
1975            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1976            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1977            for (int newUser : res.newUsers) {
1978                final boolean isInstantApp = ps.getInstantApp(newUser);
1979                if (allNewUsers) {
1980                    if (isInstantApp) {
1981                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1982                    } else {
1983                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1984                    }
1985                    continue;
1986                }
1987                boolean isNew = true;
1988                for (int origUser : res.origUsers) {
1989                    if (origUser == newUser) {
1990                        isNew = false;
1991                        break;
1992                    }
1993                }
1994                if (isNew) {
1995                    if (isInstantApp) {
1996                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1997                    } else {
1998                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1999                    }
2000                } else {
2001                    if (isInstantApp) {
2002                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2003                    } else {
2004                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2005                    }
2006                }
2007            }
2008
2009            // Send installed broadcasts if the package is not a static shared lib.
2010            if (res.pkg.staticSharedLibName == null) {
2011                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2012
2013                // Send added for users that see the package for the first time
2014                // sendPackageAddedForNewUsers also deals with system apps
2015                int appId = UserHandle.getAppId(res.uid);
2016                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2017                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2018                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2019
2020                // Send added for users that don't see the package for the first time
2021                Bundle extras = new Bundle(1);
2022                extras.putInt(Intent.EXTRA_UID, res.uid);
2023                if (update) {
2024                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2025                }
2026                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2027                        extras, 0 /*flags*/,
2028                        null /*targetPackage*/, null /*finishedReceiver*/,
2029                        updateUserIds, instantUserIds);
2030                if (installerPackageName != null) {
2031                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2032                            extras, 0 /*flags*/,
2033                            installerPackageName, null /*finishedReceiver*/,
2034                            updateUserIds, instantUserIds);
2035                }
2036
2037                // Send replaced for users that don't see the package for the first time
2038                if (update) {
2039                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2040                            packageName, extras, 0 /*flags*/,
2041                            null /*targetPackage*/, null /*finishedReceiver*/,
2042                            updateUserIds, instantUserIds);
2043                    if (installerPackageName != null) {
2044                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2045                                extras, 0 /*flags*/,
2046                                installerPackageName, null /*finishedReceiver*/,
2047                                updateUserIds, instantUserIds);
2048                    }
2049                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2050                            null /*package*/, null /*extras*/, 0 /*flags*/,
2051                            packageName /*targetPackage*/,
2052                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2053                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2054                    // First-install and we did a restore, so we're responsible for the
2055                    // first-launch broadcast.
2056                    if (DEBUG_BACKUP) {
2057                        Slog.i(TAG, "Post-restore of " + packageName
2058                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2059                    }
2060                    sendFirstLaunchBroadcast(packageName, installerPackage,
2061                            firstUserIds, firstInstantUserIds);
2062                }
2063
2064                // Send broadcast package appeared if forward locked/external for all users
2065                // treat asec-hosted packages like removable media on upgrade
2066                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2067                    if (DEBUG_INSTALL) {
2068                        Slog.i(TAG, "upgrading pkg " + res.pkg
2069                                + " is ASEC-hosted -> AVAILABLE");
2070                    }
2071                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2072                    ArrayList<String> pkgList = new ArrayList<>(1);
2073                    pkgList.add(packageName);
2074                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2075                }
2076            }
2077
2078            // Work that needs to happen on first install within each user
2079            if (firstUserIds != null && firstUserIds.length > 0) {
2080                synchronized (mPackages) {
2081                    for (int userId : firstUserIds) {
2082                        // If this app is a browser and it's newly-installed for some
2083                        // users, clear any default-browser state in those users. The
2084                        // app's nature doesn't depend on the user, so we can just check
2085                        // its browser nature in any user and generalize.
2086                        if (packageIsBrowser(packageName, userId)) {
2087                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2088                        }
2089
2090                        // We may also need to apply pending (restored) runtime
2091                        // permission grants within these users.
2092                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2093                    }
2094                }
2095            }
2096
2097            // Log current value of "unknown sources" setting
2098            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2099                    getUnknownSourcesSettings());
2100
2101            // Remove the replaced package's older resources safely now
2102            // We delete after a gc for applications  on sdcard.
2103            if (res.removedInfo != null && res.removedInfo.args != null) {
2104                Runtime.getRuntime().gc();
2105                synchronized (mInstallLock) {
2106                    res.removedInfo.args.doPostDeleteLI(true);
2107                }
2108            } else {
2109                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2110                // and not block here.
2111                VMRuntime.getRuntime().requestConcurrentGC();
2112            }
2113
2114            // Notify DexManager that the package was installed for new users.
2115            // The updated users should already be indexed and the package code paths
2116            // should not change.
2117            // Don't notify the manager for ephemeral apps as they are not expected to
2118            // survive long enough to benefit of background optimizations.
2119            for (int userId : firstUserIds) {
2120                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2121                // There's a race currently where some install events may interleave with an uninstall.
2122                // This can lead to package info being null (b/36642664).
2123                if (info != null) {
2124                    mDexManager.notifyPackageInstalled(info, userId);
2125                }
2126            }
2127        }
2128
2129        // If someone is watching installs - notify them
2130        if (installObserver != null) {
2131            try {
2132                Bundle extras = extrasForInstallResult(res);
2133                installObserver.onPackageInstalled(res.name, res.returnCode,
2134                        res.returnMsg, extras);
2135            } catch (RemoteException e) {
2136                Slog.i(TAG, "Observer no longer exists.");
2137            }
2138        }
2139    }
2140
2141    private StorageEventListener mStorageListener = new StorageEventListener() {
2142        @Override
2143        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2144            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2145                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2146                    final String volumeUuid = vol.getFsUuid();
2147
2148                    // Clean up any users or apps that were removed or recreated
2149                    // while this volume was missing
2150                    sUserManager.reconcileUsers(volumeUuid);
2151                    reconcileApps(volumeUuid);
2152
2153                    // Clean up any install sessions that expired or were
2154                    // cancelled while this volume was missing
2155                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2156
2157                    loadPrivatePackages(vol);
2158
2159                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2160                    unloadPrivatePackages(vol);
2161                }
2162            }
2163        }
2164
2165        @Override
2166        public void onVolumeForgotten(String fsUuid) {
2167            if (TextUtils.isEmpty(fsUuid)) {
2168                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2169                return;
2170            }
2171
2172            // Remove any apps installed on the forgotten volume
2173            synchronized (mPackages) {
2174                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2175                for (PackageSetting ps : packages) {
2176                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2177                    deletePackageVersioned(new VersionedPackage(ps.name,
2178                            PackageManager.VERSION_CODE_HIGHEST),
2179                            new LegacyPackageDeleteObserver(null).getBinder(),
2180                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2181                    // Try very hard to release any references to this package
2182                    // so we don't risk the system server being killed due to
2183                    // open FDs
2184                    AttributeCache.instance().removePackage(ps.name);
2185                }
2186
2187                mSettings.onVolumeForgotten(fsUuid);
2188                mSettings.writeLPr();
2189            }
2190        }
2191    };
2192
2193    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2194        Bundle extras = null;
2195        switch (res.returnCode) {
2196            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2197                extras = new Bundle();
2198                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2199                        res.origPermission);
2200                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2201                        res.origPackage);
2202                break;
2203            }
2204            case PackageManager.INSTALL_SUCCEEDED: {
2205                extras = new Bundle();
2206                extras.putBoolean(Intent.EXTRA_REPLACING,
2207                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2208                break;
2209            }
2210        }
2211        return extras;
2212    }
2213
2214    void scheduleWriteSettingsLocked() {
2215        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2216            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2217        }
2218    }
2219
2220    void scheduleWritePackageListLocked(int userId) {
2221        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2222            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2223            msg.arg1 = userId;
2224            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2225        }
2226    }
2227
2228    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2229        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2230        scheduleWritePackageRestrictionsLocked(userId);
2231    }
2232
2233    void scheduleWritePackageRestrictionsLocked(int userId) {
2234        final int[] userIds = (userId == UserHandle.USER_ALL)
2235                ? sUserManager.getUserIds() : new int[]{userId};
2236        for (int nextUserId : userIds) {
2237            if (!sUserManager.exists(nextUserId)) return;
2238            mDirtyUsers.add(nextUserId);
2239            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2240                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2241            }
2242        }
2243    }
2244
2245    public static PackageManagerService main(Context context, Installer installer,
2246            boolean factoryTest, boolean onlyCore) {
2247        // Self-check for initial settings.
2248        PackageManagerServiceCompilerMapping.checkProperties();
2249
2250        PackageManagerService m = new PackageManagerService(context, installer,
2251                factoryTest, onlyCore);
2252        m.enableSystemUserPackages();
2253        ServiceManager.addService("package", m);
2254        final PackageManagerNative pmn = m.new PackageManagerNative();
2255        ServiceManager.addService("package_native", pmn);
2256        return m;
2257    }
2258
2259    private void enableSystemUserPackages() {
2260        if (!UserManager.isSplitSystemUser()) {
2261            return;
2262        }
2263        // For system user, enable apps based on the following conditions:
2264        // - app is whitelisted or belong to one of these groups:
2265        //   -- system app which has no launcher icons
2266        //   -- system app which has INTERACT_ACROSS_USERS permission
2267        //   -- system IME app
2268        // - app is not in the blacklist
2269        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2270        Set<String> enableApps = new ArraySet<>();
2271        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2272                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2273                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2274        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2275        enableApps.addAll(wlApps);
2276        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2277                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2278        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2279        enableApps.removeAll(blApps);
2280        Log.i(TAG, "Applications installed for system user: " + enableApps);
2281        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2282                UserHandle.SYSTEM);
2283        final int allAppsSize = allAps.size();
2284        synchronized (mPackages) {
2285            for (int i = 0; i < allAppsSize; i++) {
2286                String pName = allAps.get(i);
2287                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2288                // Should not happen, but we shouldn't be failing if it does
2289                if (pkgSetting == null) {
2290                    continue;
2291                }
2292                boolean install = enableApps.contains(pName);
2293                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2294                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2295                            + " for system user");
2296                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2297                }
2298            }
2299            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2300        }
2301    }
2302
2303    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2304        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2305                Context.DISPLAY_SERVICE);
2306        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2307    }
2308
2309    /**
2310     * Requests that files preopted on a secondary system partition be copied to the data partition
2311     * if possible.  Note that the actual copying of the files is accomplished by init for security
2312     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2313     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2314     */
2315    private static void requestCopyPreoptedFiles() {
2316        final int WAIT_TIME_MS = 100;
2317        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2318        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2319            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2320            // We will wait for up to 100 seconds.
2321            final long timeStart = SystemClock.uptimeMillis();
2322            final long timeEnd = timeStart + 100 * 1000;
2323            long timeNow = timeStart;
2324            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2325                try {
2326                    Thread.sleep(WAIT_TIME_MS);
2327                } catch (InterruptedException e) {
2328                    // Do nothing
2329                }
2330                timeNow = SystemClock.uptimeMillis();
2331                if (timeNow > timeEnd) {
2332                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2333                    Slog.wtf(TAG, "cppreopt did not finish!");
2334                    break;
2335                }
2336            }
2337
2338            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2339        }
2340    }
2341
2342    public PackageManagerService(Context context, Installer installer,
2343            boolean factoryTest, boolean onlyCore) {
2344        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2345        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2346        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2347                SystemClock.uptimeMillis());
2348
2349        if (mSdkVersion <= 0) {
2350            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2351        }
2352
2353        mContext = context;
2354
2355        mFactoryTest = factoryTest;
2356        mOnlyCore = onlyCore;
2357        mMetrics = new DisplayMetrics();
2358        mInstaller = installer;
2359
2360        // Create sub-components that provide services / data. Order here is important.
2361        synchronized (mInstallLock) {
2362        synchronized (mPackages) {
2363            // Expose private service for system components to use.
2364            LocalServices.addService(
2365                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2366            sUserManager = new UserManagerService(context, this,
2367                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2368            mPermissionManager = PermissionManagerService.create(context,
2369                    new DefaultPermissionGrantedCallback() {
2370                        @Override
2371                        public void onDefaultRuntimePermissionsGranted(int userId) {
2372                            synchronized(mPackages) {
2373                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2374                            }
2375                        }
2376                    }, mPackages /*externalLock*/);
2377            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2378            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2379        }
2380        }
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        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2412                "*dexopt*");
2413        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2414                installer, mInstallLock);
2415        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2416                dexManagerListener);
2417        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2418
2419        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2420                FgThread.get().getLooper());
2421
2422        getDefaultDisplayMetrics(context, mMetrics);
2423
2424        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2425        SystemConfig systemConfig = SystemConfig.getInstance();
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            mInstantAppRegistry = new InstantAppRegistry(this);
2441
2442            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2443            final int builtInLibCount = libConfig.size();
2444            for (int i = 0; i < builtInLibCount; i++) {
2445                String name = libConfig.keyAt(i);
2446                String path = libConfig.valueAt(i);
2447                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2448                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2449            }
2450
2451            SELinuxMMAC.readInstallPolicy();
2452
2453            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2454            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2455            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2456
2457            // Clean up orphaned packages for which the code path doesn't exist
2458            // and they are an update to a system app - caused by bug/32321269
2459            final int packageSettingCount = mSettings.mPackages.size();
2460            for (int i = packageSettingCount - 1; i >= 0; i--) {
2461                PackageSetting ps = mSettings.mPackages.valueAt(i);
2462                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2463                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2464                    mSettings.mPackages.removeAt(i);
2465                    mSettings.enableSystemPackageLPw(ps.name);
2466                }
2467            }
2468
2469            if (mFirstBoot) {
2470                requestCopyPreoptedFiles();
2471            }
2472
2473            String customResolverActivity = Resources.getSystem().getString(
2474                    R.string.config_customResolverActivity);
2475            if (TextUtils.isEmpty(customResolverActivity)) {
2476                customResolverActivity = null;
2477            } else {
2478                mCustomResolverComponentName = ComponentName.unflattenFromString(
2479                        customResolverActivity);
2480            }
2481
2482            long startTime = SystemClock.uptimeMillis();
2483
2484            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2485                    startTime);
2486
2487            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2488            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2489
2490            if (bootClassPath == null) {
2491                Slog.w(TAG, "No BOOTCLASSPATH found!");
2492            }
2493
2494            if (systemServerClassPath == null) {
2495                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2496            }
2497
2498            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2499
2500            final VersionInfo ver = mSettings.getInternalVersion();
2501            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2502            if (mIsUpgrade) {
2503                logCriticalInfo(Log.INFO,
2504                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2505            }
2506
2507            // when upgrading from pre-M, promote system app permissions from install to runtime
2508            mPromoteSystemApps =
2509                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2510
2511            // When upgrading from pre-N, we need to handle package extraction like first boot,
2512            // as there is no profiling data available.
2513            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2514
2515            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2516
2517            // save off the names of pre-existing system packages prior to scanning; we don't
2518            // want to automatically grant runtime permissions for new system apps
2519            if (mPromoteSystemApps) {
2520                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2521                while (pkgSettingIter.hasNext()) {
2522                    PackageSetting ps = pkgSettingIter.next();
2523                    if (isSystemApp(ps)) {
2524                        mExistingSystemPackages.add(ps.name);
2525                    }
2526                }
2527            }
2528
2529            mCacheDir = preparePackageParserCache(mIsUpgrade);
2530
2531            // Set flag to monitor and not change apk file paths when
2532            // scanning install directories.
2533            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2534
2535            if (mIsUpgrade || mFirstBoot) {
2536                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2537            }
2538
2539            // Collect vendor overlay packages. (Do this before scanning any apps.)
2540            // For security and version matching reason, only consider
2541            // overlay packages if they reside in the right directory.
2542            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2543                    mDefParseFlags
2544                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2545                    scanFlags
2546                    | SCAN_AS_SYSTEM
2547                    | SCAN_TRUSTED_OVERLAY,
2548                    0);
2549
2550            mParallelPackageParserCallback.findStaticOverlayPackages();
2551
2552            // Find base frameworks (resource packages without code).
2553            scanDirTracedLI(frameworkDir,
2554                    mDefParseFlags
2555                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2556                    scanFlags
2557                    | SCAN_NO_DEX
2558                    | SCAN_AS_SYSTEM
2559                    | SCAN_AS_PRIVILEGED,
2560                    0);
2561
2562            // Collected privileged system packages.
2563            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2564            scanDirTracedLI(privilegedAppDir,
2565                    mDefParseFlags
2566                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2567                    scanFlags
2568                    | SCAN_AS_SYSTEM
2569                    | SCAN_AS_PRIVILEGED,
2570                    0);
2571
2572            // Collect ordinary system packages.
2573            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2574            scanDirTracedLI(systemAppDir,
2575                    mDefParseFlags
2576                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2577                    scanFlags
2578                    | SCAN_AS_SYSTEM,
2579                    0);
2580
2581            // Collected privileged vendor packages.
2582                File privilegedVendorAppDir = new File(Environment.getVendorDirectory(),
2583                        "priv-app");
2584            try {
2585                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2586            } catch (IOException e) {
2587                // failed to look up canonical path, continue with original one
2588            }
2589            scanDirTracedLI(privilegedVendorAppDir,
2590                    mDefParseFlags
2591                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2592                    scanFlags
2593                    | SCAN_AS_SYSTEM
2594                    | SCAN_AS_VENDOR
2595                    | SCAN_AS_PRIVILEGED,
2596                    0);
2597
2598            // Collect ordinary vendor packages.
2599            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2600            try {
2601                vendorAppDir = vendorAppDir.getCanonicalFile();
2602            } catch (IOException e) {
2603                // failed to look up canonical path, continue with original one
2604            }
2605            scanDirTracedLI(vendorAppDir,
2606                    mDefParseFlags
2607                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2608                    scanFlags
2609                    | SCAN_AS_SYSTEM
2610                    | SCAN_AS_VENDOR,
2611                    0);
2612
2613            // Collect all OEM packages.
2614            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2615            scanDirTracedLI(oemAppDir,
2616                    mDefParseFlags
2617                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2618                    scanFlags
2619                    | SCAN_AS_SYSTEM
2620                    | SCAN_AS_OEM,
2621                    0);
2622
2623            // Prune any system packages that no longer exist.
2624            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2625            // Stub packages must either be replaced with full versions in the /data
2626            // partition or be disabled.
2627            final List<String> stubSystemApps = new ArrayList<>();
2628            if (!mOnlyCore) {
2629                // do this first before mucking with mPackages for the "expecting better" case
2630                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2631                while (pkgIterator.hasNext()) {
2632                    final PackageParser.Package pkg = pkgIterator.next();
2633                    if (pkg.isStub) {
2634                        stubSystemApps.add(pkg.packageName);
2635                    }
2636                }
2637
2638                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2639                while (psit.hasNext()) {
2640                    PackageSetting ps = psit.next();
2641
2642                    /*
2643                     * If this is not a system app, it can't be a
2644                     * disable system app.
2645                     */
2646                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2647                        continue;
2648                    }
2649
2650                    /*
2651                     * If the package is scanned, it's not erased.
2652                     */
2653                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2654                    if (scannedPkg != null) {
2655                        /*
2656                         * If the system app is both scanned and in the
2657                         * disabled packages list, then it must have been
2658                         * added via OTA. Remove it from the currently
2659                         * scanned package so the previously user-installed
2660                         * application can be scanned.
2661                         */
2662                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2663                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2664                                    + ps.name + "; removing system app.  Last known codePath="
2665                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2666                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2667                                    + scannedPkg.getLongVersionCode());
2668                            removePackageLI(scannedPkg, true);
2669                            mExpectingBetter.put(ps.name, ps.codePath);
2670                        }
2671
2672                        continue;
2673                    }
2674
2675                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2676                        psit.remove();
2677                        logCriticalInfo(Log.WARN, "System package " + ps.name
2678                                + " no longer exists; it's data will be wiped");
2679                        // Actual deletion of code and data will be handled by later
2680                        // reconciliation step
2681                    } else {
2682                        // we still have a disabled system package, but, it still might have
2683                        // been removed. check the code path still exists and check there's
2684                        // still a package. the latter can happen if an OTA keeps the same
2685                        // code path, but, changes the package name.
2686                        final PackageSetting disabledPs =
2687                                mSettings.getDisabledSystemPkgLPr(ps.name);
2688                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2689                                || disabledPs.pkg == null) {
2690                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2691                        }
2692                    }
2693                }
2694            }
2695
2696            //look for any incomplete package installations
2697            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2698            for (int i = 0; i < deletePkgsList.size(); i++) {
2699                // Actual deletion of code and data will be handled by later
2700                // reconciliation step
2701                final String packageName = deletePkgsList.get(i).name;
2702                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2703                synchronized (mPackages) {
2704                    mSettings.removePackageLPw(packageName);
2705                }
2706            }
2707
2708            //delete tmp files
2709            deleteTempPackageFiles();
2710
2711            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2712
2713            // Remove any shared userIDs that have no associated packages
2714            mSettings.pruneSharedUsersLPw();
2715            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2716            final int systemPackagesCount = mPackages.size();
2717            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2718                    + " ms, packageCount: " + systemPackagesCount
2719                    + " , timePerPackage: "
2720                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2721                    + " , cached: " + cachedSystemApps);
2722            if (mIsUpgrade && systemPackagesCount > 0) {
2723                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2724                        ((int) systemScanTime) / systemPackagesCount);
2725            }
2726            if (!mOnlyCore) {
2727                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2728                        SystemClock.uptimeMillis());
2729                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2730
2731                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2732                        | PackageParser.PARSE_FORWARD_LOCK,
2733                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2734
2735                // Remove disable package settings for updated system apps that were
2736                // removed via an OTA. If the update is no longer present, remove the
2737                // app completely. Otherwise, revoke their system privileges.
2738                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2739                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2740                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2741
2742                    final String msg;
2743                    if (deletedPkg == null) {
2744                        // should have found an update, but, we didn't; remove everything
2745                        msg = "Updated system package " + deletedAppName
2746                                + " no longer exists; removing its data";
2747                        // Actual deletion of code and data will be handled by later
2748                        // reconciliation step
2749                    } else {
2750                        // found an update; revoke system privileges
2751                        msg = "Updated system package + " + deletedAppName
2752                                + " no longer exists; revoking system privileges";
2753
2754                        // Don't do anything if a stub is removed from the system image. If
2755                        // we were to remove the uncompressed version from the /data partition,
2756                        // this is where it'd be done.
2757
2758                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2759                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2760                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2761                    }
2762                    logCriticalInfo(Log.WARN, msg);
2763                }
2764
2765                /*
2766                 * Make sure all system apps that we expected to appear on
2767                 * the userdata partition actually showed up. If they never
2768                 * appeared, crawl back and revive the system version.
2769                 */
2770                for (int i = 0; i < mExpectingBetter.size(); i++) {
2771                    final String packageName = mExpectingBetter.keyAt(i);
2772                    if (!mPackages.containsKey(packageName)) {
2773                        final File scanFile = mExpectingBetter.valueAt(i);
2774
2775                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2776                                + " but never showed up; reverting to system");
2777
2778                        final @ParseFlags int reparseFlags;
2779                        final @ScanFlags int rescanFlags;
2780                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2781                            reparseFlags =
2782                                    mDefParseFlags |
2783                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2784                            rescanFlags =
2785                                    scanFlags
2786                                    | SCAN_AS_SYSTEM
2787                                    | SCAN_AS_PRIVILEGED;
2788                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2789                            reparseFlags =
2790                                    mDefParseFlags |
2791                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2792                            rescanFlags =
2793                                    scanFlags
2794                                    | SCAN_AS_SYSTEM;
2795                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2796                            reparseFlags =
2797                                    mDefParseFlags |
2798                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2799                            rescanFlags =
2800                                    scanFlags
2801                                    | SCAN_AS_SYSTEM
2802                                    | SCAN_AS_VENDOR
2803                                    | SCAN_AS_PRIVILEGED;
2804                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2805                            reparseFlags =
2806                                    mDefParseFlags |
2807                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2808                            rescanFlags =
2809                                    scanFlags
2810                                    | SCAN_AS_SYSTEM
2811                                    | SCAN_AS_VENDOR;
2812                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2813                            reparseFlags =
2814                                    mDefParseFlags |
2815                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2816                            rescanFlags =
2817                                    scanFlags
2818                                    | SCAN_AS_SYSTEM
2819                                    | SCAN_AS_OEM;
2820                        } else {
2821                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2822                            continue;
2823                        }
2824
2825                        mSettings.enableSystemPackageLPw(packageName);
2826
2827                        try {
2828                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2829                        } catch (PackageManagerException e) {
2830                            Slog.e(TAG, "Failed to parse original system package: "
2831                                    + e.getMessage());
2832                        }
2833                    }
2834                }
2835
2836                // Uncompress and install any stubbed system applications.
2837                // This must be done last to ensure all stubs are replaced or disabled.
2838                decompressSystemApplications(stubSystemApps, scanFlags);
2839
2840                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2841                                - cachedSystemApps;
2842
2843                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2844                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2845                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2846                        + " ms, packageCount: " + dataPackagesCount
2847                        + " , timePerPackage: "
2848                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2849                        + " , cached: " + cachedNonSystemApps);
2850                if (mIsUpgrade && dataPackagesCount > 0) {
2851                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2852                            ((int) dataScanTime) / dataPackagesCount);
2853                }
2854            }
2855            mExpectingBetter.clear();
2856
2857            // Resolve the storage manager.
2858            mStorageManagerPackage = getStorageManagerPackageName();
2859
2860            // Resolve protected action filters. Only the setup wizard is allowed to
2861            // have a high priority filter for these actions.
2862            mSetupWizardPackage = getSetupWizardPackageName();
2863            if (mProtectedFilters.size() > 0) {
2864                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2865                    Slog.i(TAG, "No setup wizard;"
2866                        + " All protected intents capped to priority 0");
2867                }
2868                for (ActivityIntentInfo filter : mProtectedFilters) {
2869                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2870                        if (DEBUG_FILTERS) {
2871                            Slog.i(TAG, "Found setup wizard;"
2872                                + " allow priority " + filter.getPriority() + ";"
2873                                + " package: " + filter.activity.info.packageName
2874                                + " activity: " + filter.activity.className
2875                                + " priority: " + filter.getPriority());
2876                        }
2877                        // skip setup wizard; allow it to keep the high priority filter
2878                        continue;
2879                    }
2880                    if (DEBUG_FILTERS) {
2881                        Slog.i(TAG, "Protected action; cap priority to 0;"
2882                                + " package: " + filter.activity.info.packageName
2883                                + " activity: " + filter.activity.className
2884                                + " origPrio: " + filter.getPriority());
2885                    }
2886                    filter.setPriority(0);
2887                }
2888            }
2889            mDeferProtectedFilters = false;
2890            mProtectedFilters.clear();
2891
2892            // Now that we know all of the shared libraries, update all clients to have
2893            // the correct library paths.
2894            updateAllSharedLibrariesLPw(null);
2895
2896            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2897                // NOTE: We ignore potential failures here during a system scan (like
2898                // the rest of the commands above) because there's precious little we
2899                // can do about it. A settings error is reported, though.
2900                final List<String> changedAbiCodePath =
2901                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2902                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
2903                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
2904                        final String codePathString = changedAbiCodePath.get(i);
2905                        try {
2906                            mInstaller.rmdex(codePathString,
2907                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
2908                        } catch (InstallerException ignored) {
2909                        }
2910                    }
2911                }
2912            }
2913
2914            // Now that we know all the packages we are keeping,
2915            // read and update their last usage times.
2916            mPackageUsage.read(mPackages);
2917            mCompilerStats.read();
2918
2919            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2920                    SystemClock.uptimeMillis());
2921            Slog.i(TAG, "Time to scan packages: "
2922                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2923                    + " seconds");
2924
2925            // If the platform SDK has changed since the last time we booted,
2926            // we need to re-grant app permission to catch any new ones that
2927            // appear.  This is really a hack, and means that apps can in some
2928            // cases get permissions that the user didn't initially explicitly
2929            // allow...  it would be nice to have some better way to handle
2930            // this situation.
2931            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
2932            if (sdkUpdated) {
2933                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2934                        + mSdkVersion + "; regranting permissions for internal storage");
2935            }
2936            mPermissionManager.updateAllPermissions(
2937                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
2938                    mPermissionCallback);
2939            ver.sdkVersion = mSdkVersion;
2940
2941            // If this is the first boot or an update from pre-M, and it is a normal
2942            // boot, then we need to initialize the default preferred apps across
2943            // all defined users.
2944            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2945                for (UserInfo user : sUserManager.getUsers(true)) {
2946                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2947                    applyFactoryDefaultBrowserLPw(user.id);
2948                    primeDomainVerificationsLPw(user.id);
2949                }
2950            }
2951
2952            // Prepare storage for system user really early during boot,
2953            // since core system apps like SettingsProvider and SystemUI
2954            // can't wait for user to start
2955            final int storageFlags;
2956            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2957                storageFlags = StorageManager.FLAG_STORAGE_DE;
2958            } else {
2959                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2960            }
2961            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2962                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2963                    true /* onlyCoreApps */);
2964            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2965                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2966                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2967                traceLog.traceBegin("AppDataFixup");
2968                try {
2969                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2970                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2971                } catch (InstallerException e) {
2972                    Slog.w(TAG, "Trouble fixing GIDs", e);
2973                }
2974                traceLog.traceEnd();
2975
2976                traceLog.traceBegin("AppDataPrepare");
2977                if (deferPackages == null || deferPackages.isEmpty()) {
2978                    return;
2979                }
2980                int count = 0;
2981                for (String pkgName : deferPackages) {
2982                    PackageParser.Package pkg = null;
2983                    synchronized (mPackages) {
2984                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2985                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2986                            pkg = ps.pkg;
2987                        }
2988                    }
2989                    if (pkg != null) {
2990                        synchronized (mInstallLock) {
2991                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2992                                    true /* maybeMigrateAppData */);
2993                        }
2994                        count++;
2995                    }
2996                }
2997                traceLog.traceEnd();
2998                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2999            }, "prepareAppData");
3000
3001            // If this is first boot after an OTA, and a normal boot, then
3002            // we need to clear code cache directories.
3003            // Note that we do *not* clear the application profiles. These remain valid
3004            // across OTAs and are used to drive profile verification (post OTA) and
3005            // profile compilation (without waiting to collect a fresh set of profiles).
3006            if (mIsUpgrade && !onlyCore) {
3007                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3008                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3009                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3010                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3011                        // No apps are running this early, so no need to freeze
3012                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3013                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3014                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3015                    }
3016                }
3017                ver.fingerprint = Build.FINGERPRINT;
3018            }
3019
3020            checkDefaultBrowser();
3021
3022            // clear only after permissions and other defaults have been updated
3023            mExistingSystemPackages.clear();
3024            mPromoteSystemApps = false;
3025
3026            // All the changes are done during package scanning.
3027            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3028
3029            // can downgrade to reader
3030            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3031            mSettings.writeLPr();
3032            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3033            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3034                    SystemClock.uptimeMillis());
3035
3036            if (!mOnlyCore) {
3037                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3038                mRequiredInstallerPackage = getRequiredInstallerLPr();
3039                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3040                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3041                if (mIntentFilterVerifierComponent != null) {
3042                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3043                            mIntentFilterVerifierComponent);
3044                } else {
3045                    mIntentFilterVerifier = null;
3046                }
3047                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3048                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3049                        SharedLibraryInfo.VERSION_UNDEFINED);
3050                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3051                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3052                        SharedLibraryInfo.VERSION_UNDEFINED);
3053            } else {
3054                mRequiredVerifierPackage = null;
3055                mRequiredInstallerPackage = null;
3056                mRequiredUninstallerPackage = null;
3057                mIntentFilterVerifierComponent = null;
3058                mIntentFilterVerifier = null;
3059                mServicesSystemSharedLibraryPackageName = null;
3060                mSharedSystemSharedLibraryPackageName = null;
3061            }
3062
3063            mInstallerService = new PackageInstallerService(context, this);
3064            mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock);
3065            final Pair<ComponentName, String> instantAppResolverComponent =
3066                    getInstantAppResolverLPr();
3067            if (instantAppResolverComponent != null) {
3068                if (DEBUG_EPHEMERAL) {
3069                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3070                }
3071                mInstantAppResolverConnection = new EphemeralResolverConnection(
3072                        mContext, instantAppResolverComponent.first,
3073                        instantAppResolverComponent.second);
3074                mInstantAppResolverSettingsComponent =
3075                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3076            } else {
3077                mInstantAppResolverConnection = null;
3078                mInstantAppResolverSettingsComponent = null;
3079            }
3080            updateInstantAppInstallerLocked(null);
3081
3082            // Read and update the usage of dex files.
3083            // Do this at the end of PM init so that all the packages have their
3084            // data directory reconciled.
3085            // At this point we know the code paths of the packages, so we can validate
3086            // the disk file and build the internal cache.
3087            // The usage file is expected to be small so loading and verifying it
3088            // should take a fairly small time compare to the other activities (e.g. package
3089            // scanning).
3090            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3091            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3092            for (int userId : currentUserIds) {
3093                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3094            }
3095            mDexManager.load(userPackages);
3096            if (mIsUpgrade) {
3097                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3098                        (int) (SystemClock.uptimeMillis() - startTime));
3099            }
3100        } // synchronized (mPackages)
3101        } // synchronized (mInstallLock)
3102
3103        // Now after opening every single application zip, make sure they
3104        // are all flushed.  Not really needed, but keeps things nice and
3105        // tidy.
3106        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3107        Runtime.getRuntime().gc();
3108        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3109
3110        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3111        FallbackCategoryProvider.loadFallbacks();
3112        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3113
3114        // The initial scanning above does many calls into installd while
3115        // holding the mPackages lock, but we're mostly interested in yelling
3116        // once we have a booted system.
3117        mInstaller.setWarnIfHeld(mPackages);
3118
3119        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3120    }
3121
3122    /**
3123     * Uncompress and install stub applications.
3124     * <p>In order to save space on the system partition, some applications are shipped in a
3125     * compressed form. In addition the compressed bits for the full application, the
3126     * system image contains a tiny stub comprised of only the Android manifest.
3127     * <p>During the first boot, attempt to uncompress and install the full application. If
3128     * the application can't be installed for any reason, disable the stub and prevent
3129     * uncompressing the full application during future boots.
3130     * <p>In order to forcefully attempt an installation of a full application, go to app
3131     * settings and enable the application.
3132     */
3133    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3134        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3135            final String pkgName = stubSystemApps.get(i);
3136            // skip if the system package is already disabled
3137            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3138                stubSystemApps.remove(i);
3139                continue;
3140            }
3141            // skip if the package isn't installed (?!); this should never happen
3142            final PackageParser.Package pkg = mPackages.get(pkgName);
3143            if (pkg == null) {
3144                stubSystemApps.remove(i);
3145                continue;
3146            }
3147            // skip if the package has been disabled by the user
3148            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3149            if (ps != null) {
3150                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3151                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3152                    stubSystemApps.remove(i);
3153                    continue;
3154                }
3155            }
3156
3157            if (DEBUG_COMPRESSION) {
3158                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3159            }
3160
3161            // uncompress the binary to its eventual destination on /data
3162            final File scanFile = decompressPackage(pkg);
3163            if (scanFile == null) {
3164                continue;
3165            }
3166
3167            // install the package to replace the stub on /system
3168            try {
3169                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3170                removePackageLI(pkg, true /*chatty*/);
3171                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3172                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3173                        UserHandle.USER_SYSTEM, "android");
3174                stubSystemApps.remove(i);
3175                continue;
3176            } catch (PackageManagerException e) {
3177                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3178            }
3179
3180            // any failed attempt to install the package will be cleaned up later
3181        }
3182
3183        // disable any stub still left; these failed to install the full application
3184        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3185            final String pkgName = stubSystemApps.get(i);
3186            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3187            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3188                    UserHandle.USER_SYSTEM, "android");
3189            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3190        }
3191    }
3192
3193    /**
3194     * Decompresses the given package on the system image onto
3195     * the /data partition.
3196     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3197     */
3198    private File decompressPackage(PackageParser.Package pkg) {
3199        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3200        if (compressedFiles == null || compressedFiles.length == 0) {
3201            if (DEBUG_COMPRESSION) {
3202                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3203            }
3204            return null;
3205        }
3206        final File dstCodePath =
3207                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3208        int ret = PackageManager.INSTALL_SUCCEEDED;
3209        try {
3210            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3211            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3212            for (File srcFile : compressedFiles) {
3213                final String srcFileName = srcFile.getName();
3214                final String dstFileName = srcFileName.substring(
3215                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3216                final File dstFile = new File(dstCodePath, dstFileName);
3217                ret = decompressFile(srcFile, dstFile);
3218                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3219                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3220                            + "; pkg: " + pkg.packageName
3221                            + ", file: " + dstFileName);
3222                    break;
3223                }
3224            }
3225        } catch (ErrnoException e) {
3226            logCriticalInfo(Log.ERROR, "Failed to decompress"
3227                    + "; pkg: " + pkg.packageName
3228                    + ", err: " + e.errno);
3229        }
3230        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3231            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3232            NativeLibraryHelper.Handle handle = null;
3233            try {
3234                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3235                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3236                        null /*abiOverride*/);
3237            } catch (IOException e) {
3238                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3239                        + "; pkg: " + pkg.packageName);
3240                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3241            } finally {
3242                IoUtils.closeQuietly(handle);
3243            }
3244        }
3245        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3246            if (dstCodePath == null || !dstCodePath.exists()) {
3247                return null;
3248            }
3249            removeCodePathLI(dstCodePath);
3250            return null;
3251        }
3252
3253        return dstCodePath;
3254    }
3255
3256    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3257        // we're only interested in updating the installer appliction when 1) it's not
3258        // already set or 2) the modified package is the installer
3259        if (mInstantAppInstallerActivity != null
3260                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3261                        .equals(modifiedPackage)) {
3262            return;
3263        }
3264        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3265    }
3266
3267    private static File preparePackageParserCache(boolean isUpgrade) {
3268        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3269            return null;
3270        }
3271
3272        // Disable package parsing on eng builds to allow for faster incremental development.
3273        if (Build.IS_ENG) {
3274            return null;
3275        }
3276
3277        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3278            Slog.i(TAG, "Disabling package parser cache due to system property.");
3279            return null;
3280        }
3281
3282        // The base directory for the package parser cache lives under /data/system/.
3283        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3284                "package_cache");
3285        if (cacheBaseDir == null) {
3286            return null;
3287        }
3288
3289        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3290        // This also serves to "GC" unused entries when the package cache version changes (which
3291        // can only happen during upgrades).
3292        if (isUpgrade) {
3293            FileUtils.deleteContents(cacheBaseDir);
3294        }
3295
3296
3297        // Return the versioned package cache directory. This is something like
3298        // "/data/system/package_cache/1"
3299        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3300
3301        // The following is a workaround to aid development on non-numbered userdebug
3302        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3303        // the system partition is newer.
3304        //
3305        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3306        // that starts with "eng." to signify that this is an engineering build and not
3307        // destined for release.
3308        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3309            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3310
3311            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3312            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3313            // in general and should not be used for production changes. In this specific case,
3314            // we know that they will work.
3315            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3316            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3317                FileUtils.deleteContents(cacheBaseDir);
3318                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3319            }
3320        }
3321
3322        return cacheDir;
3323    }
3324
3325    @Override
3326    public boolean isFirstBoot() {
3327        // allow instant applications
3328        return mFirstBoot;
3329    }
3330
3331    @Override
3332    public boolean isOnlyCoreApps() {
3333        // allow instant applications
3334        return mOnlyCore;
3335    }
3336
3337    @Override
3338    public boolean isUpgrade() {
3339        // allow instant applications
3340        // The system property allows testing ota flow when upgraded to the same image.
3341        return mIsUpgrade || SystemProperties.getBoolean(
3342                "persist.pm.mock-upgrade", false /* default */);
3343    }
3344
3345    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3346        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3347
3348        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3349                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3350                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3351        if (matches.size() == 1) {
3352            return matches.get(0).getComponentInfo().packageName;
3353        } else if (matches.size() == 0) {
3354            Log.e(TAG, "There should probably be a verifier, but, none were found");
3355            return null;
3356        }
3357        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3358    }
3359
3360    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3361        synchronized (mPackages) {
3362            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3363            if (libraryEntry == null) {
3364                throw new IllegalStateException("Missing required shared library:" + name);
3365            }
3366            return libraryEntry.apk;
3367        }
3368    }
3369
3370    private @NonNull String getRequiredInstallerLPr() {
3371        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3372        intent.addCategory(Intent.CATEGORY_DEFAULT);
3373        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3374
3375        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3376                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3377                UserHandle.USER_SYSTEM);
3378        if (matches.size() == 1) {
3379            ResolveInfo resolveInfo = matches.get(0);
3380            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3381                throw new RuntimeException("The installer must be a privileged app");
3382            }
3383            return matches.get(0).getComponentInfo().packageName;
3384        } else {
3385            throw new RuntimeException("There must be exactly one installer; found " + matches);
3386        }
3387    }
3388
3389    private @NonNull String getRequiredUninstallerLPr() {
3390        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3391        intent.addCategory(Intent.CATEGORY_DEFAULT);
3392        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3393
3394        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3395                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3396                UserHandle.USER_SYSTEM);
3397        if (resolveInfo == null ||
3398                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3399            throw new RuntimeException("There must be exactly one uninstaller; found "
3400                    + resolveInfo);
3401        }
3402        return resolveInfo.getComponentInfo().packageName;
3403    }
3404
3405    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3406        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3407
3408        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3409                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3410                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3411        ResolveInfo best = null;
3412        final int N = matches.size();
3413        for (int i = 0; i < N; i++) {
3414            final ResolveInfo cur = matches.get(i);
3415            final String packageName = cur.getComponentInfo().packageName;
3416            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3417                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3418                continue;
3419            }
3420
3421            if (best == null || cur.priority > best.priority) {
3422                best = cur;
3423            }
3424        }
3425
3426        if (best != null) {
3427            return best.getComponentInfo().getComponentName();
3428        }
3429        Slog.w(TAG, "Intent filter verifier not found");
3430        return null;
3431    }
3432
3433    @Override
3434    public @Nullable ComponentName getInstantAppResolverComponent() {
3435        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3436            return null;
3437        }
3438        synchronized (mPackages) {
3439            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3440            if (instantAppResolver == null) {
3441                return null;
3442            }
3443            return instantAppResolver.first;
3444        }
3445    }
3446
3447    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3448        final String[] packageArray =
3449                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3450        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3451            if (DEBUG_EPHEMERAL) {
3452                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3453            }
3454            return null;
3455        }
3456
3457        final int callingUid = Binder.getCallingUid();
3458        final int resolveFlags =
3459                MATCH_DIRECT_BOOT_AWARE
3460                | MATCH_DIRECT_BOOT_UNAWARE
3461                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3462        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3463        final Intent resolverIntent = new Intent(actionName);
3464        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3465                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3466        // temporarily look for the old action
3467        if (resolvers.size() == 0) {
3468            if (DEBUG_EPHEMERAL) {
3469                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3470            }
3471            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3472            resolverIntent.setAction(actionName);
3473            resolvers = queryIntentServicesInternal(resolverIntent, null,
3474                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3475        }
3476        final int N = resolvers.size();
3477        if (N == 0) {
3478            if (DEBUG_EPHEMERAL) {
3479                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3480            }
3481            return null;
3482        }
3483
3484        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3485        for (int i = 0; i < N; i++) {
3486            final ResolveInfo info = resolvers.get(i);
3487
3488            if (info.serviceInfo == null) {
3489                continue;
3490            }
3491
3492            final String packageName = info.serviceInfo.packageName;
3493            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3494                if (DEBUG_EPHEMERAL) {
3495                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3496                            + " pkg: " + packageName + ", info:" + info);
3497                }
3498                continue;
3499            }
3500
3501            if (DEBUG_EPHEMERAL) {
3502                Slog.v(TAG, "Ephemeral resolver found;"
3503                        + " pkg: " + packageName + ", info:" + info);
3504            }
3505            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3506        }
3507        if (DEBUG_EPHEMERAL) {
3508            Slog.v(TAG, "Ephemeral resolver NOT found");
3509        }
3510        return null;
3511    }
3512
3513    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3514        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3515        intent.addCategory(Intent.CATEGORY_DEFAULT);
3516        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3517
3518        final int resolveFlags =
3519                MATCH_DIRECT_BOOT_AWARE
3520                | MATCH_DIRECT_BOOT_UNAWARE
3521                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3522        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3523                resolveFlags, UserHandle.USER_SYSTEM);
3524        // temporarily look for the old action
3525        if (matches.isEmpty()) {
3526            if (DEBUG_EPHEMERAL) {
3527                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3528            }
3529            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3530            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3531                    resolveFlags, UserHandle.USER_SYSTEM);
3532        }
3533        Iterator<ResolveInfo> iter = matches.iterator();
3534        while (iter.hasNext()) {
3535            final ResolveInfo rInfo = iter.next();
3536            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3537            if (ps != null) {
3538                final PermissionsState permissionsState = ps.getPermissionsState();
3539                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3540                    continue;
3541                }
3542            }
3543            iter.remove();
3544        }
3545        if (matches.size() == 0) {
3546            return null;
3547        } else if (matches.size() == 1) {
3548            return (ActivityInfo) matches.get(0).getComponentInfo();
3549        } else {
3550            throw new RuntimeException(
3551                    "There must be at most one ephemeral installer; found " + matches);
3552        }
3553    }
3554
3555    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3556            @NonNull ComponentName resolver) {
3557        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3558                .addCategory(Intent.CATEGORY_DEFAULT)
3559                .setPackage(resolver.getPackageName());
3560        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3561        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3562                UserHandle.USER_SYSTEM);
3563        // temporarily look for the old action
3564        if (matches.isEmpty()) {
3565            if (DEBUG_EPHEMERAL) {
3566                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3567            }
3568            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3569            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3570                    UserHandle.USER_SYSTEM);
3571        }
3572        if (matches.isEmpty()) {
3573            return null;
3574        }
3575        return matches.get(0).getComponentInfo().getComponentName();
3576    }
3577
3578    private void primeDomainVerificationsLPw(int userId) {
3579        if (DEBUG_DOMAIN_VERIFICATION) {
3580            Slog.d(TAG, "Priming domain verifications in user " + userId);
3581        }
3582
3583        SystemConfig systemConfig = SystemConfig.getInstance();
3584        ArraySet<String> packages = systemConfig.getLinkedApps();
3585
3586        for (String packageName : packages) {
3587            PackageParser.Package pkg = mPackages.get(packageName);
3588            if (pkg != null) {
3589                if (!pkg.isSystem()) {
3590                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3591                    continue;
3592                }
3593
3594                ArraySet<String> domains = null;
3595                for (PackageParser.Activity a : pkg.activities) {
3596                    for (ActivityIntentInfo filter : a.intents) {
3597                        if (hasValidDomains(filter)) {
3598                            if (domains == null) {
3599                                domains = new ArraySet<String>();
3600                            }
3601                            domains.addAll(filter.getHostsList());
3602                        }
3603                    }
3604                }
3605
3606                if (domains != null && domains.size() > 0) {
3607                    if (DEBUG_DOMAIN_VERIFICATION) {
3608                        Slog.v(TAG, "      + " + packageName);
3609                    }
3610                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3611                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3612                    // and then 'always' in the per-user state actually used for intent resolution.
3613                    final IntentFilterVerificationInfo ivi;
3614                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3615                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3616                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3617                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3618                } else {
3619                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3620                            + "' does not handle web links");
3621                }
3622            } else {
3623                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3624            }
3625        }
3626
3627        scheduleWritePackageRestrictionsLocked(userId);
3628        scheduleWriteSettingsLocked();
3629    }
3630
3631    private void applyFactoryDefaultBrowserLPw(int userId) {
3632        // The default browser app's package name is stored in a string resource,
3633        // with a product-specific overlay used for vendor customization.
3634        String browserPkg = mContext.getResources().getString(
3635                com.android.internal.R.string.default_browser);
3636        if (!TextUtils.isEmpty(browserPkg)) {
3637            // non-empty string => required to be a known package
3638            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3639            if (ps == null) {
3640                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3641                browserPkg = null;
3642            } else {
3643                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3644            }
3645        }
3646
3647        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3648        // default.  If there's more than one, just leave everything alone.
3649        if (browserPkg == null) {
3650            calculateDefaultBrowserLPw(userId);
3651        }
3652    }
3653
3654    private void calculateDefaultBrowserLPw(int userId) {
3655        List<String> allBrowsers = resolveAllBrowserApps(userId);
3656        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3657        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3658    }
3659
3660    private List<String> resolveAllBrowserApps(int userId) {
3661        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3662        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3663                PackageManager.MATCH_ALL, userId);
3664
3665        final int count = list.size();
3666        List<String> result = new ArrayList<String>(count);
3667        for (int i=0; i<count; i++) {
3668            ResolveInfo info = list.get(i);
3669            if (info.activityInfo == null
3670                    || !info.handleAllWebDataURI
3671                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3672                    || result.contains(info.activityInfo.packageName)) {
3673                continue;
3674            }
3675            result.add(info.activityInfo.packageName);
3676        }
3677
3678        return result;
3679    }
3680
3681    private boolean packageIsBrowser(String packageName, int userId) {
3682        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3683                PackageManager.MATCH_ALL, userId);
3684        final int N = list.size();
3685        for (int i = 0; i < N; i++) {
3686            ResolveInfo info = list.get(i);
3687            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3688                return true;
3689            }
3690        }
3691        return false;
3692    }
3693
3694    private void checkDefaultBrowser() {
3695        final int myUserId = UserHandle.myUserId();
3696        final String packageName = getDefaultBrowserPackageName(myUserId);
3697        if (packageName != null) {
3698            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3699            if (info == null) {
3700                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3701                synchronized (mPackages) {
3702                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3703                }
3704            }
3705        }
3706    }
3707
3708    @Override
3709    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3710            throws RemoteException {
3711        try {
3712            return super.onTransact(code, data, reply, flags);
3713        } catch (RuntimeException e) {
3714            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3715                Slog.wtf(TAG, "Package Manager Crash", e);
3716            }
3717            throw e;
3718        }
3719    }
3720
3721    static int[] appendInts(int[] cur, int[] add) {
3722        if (add == null) return cur;
3723        if (cur == null) return add;
3724        final int N = add.length;
3725        for (int i=0; i<N; i++) {
3726            cur = appendInt(cur, add[i]);
3727        }
3728        return cur;
3729    }
3730
3731    /**
3732     * Returns whether or not a full application can see an instant application.
3733     * <p>
3734     * Currently, there are three cases in which this can occur:
3735     * <ol>
3736     * <li>The calling application is a "special" process. Special processes
3737     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3738     * <li>The calling application has the permission
3739     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3740     * <li>The calling application is the default launcher on the
3741     *     system partition.</li>
3742     * </ol>
3743     */
3744    private boolean canViewInstantApps(int callingUid, int userId) {
3745        if (callingUid < Process.FIRST_APPLICATION_UID) {
3746            return true;
3747        }
3748        if (mContext.checkCallingOrSelfPermission(
3749                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3750            return true;
3751        }
3752        if (mContext.checkCallingOrSelfPermission(
3753                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3754            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3755            if (homeComponent != null
3756                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3757                return true;
3758            }
3759        }
3760        return false;
3761    }
3762
3763    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3764        if (!sUserManager.exists(userId)) return null;
3765        if (ps == null) {
3766            return null;
3767        }
3768        PackageParser.Package p = ps.pkg;
3769        if (p == null) {
3770            return null;
3771        }
3772        final int callingUid = Binder.getCallingUid();
3773        // Filter out ephemeral app metadata:
3774        //   * The system/shell/root can see metadata for any app
3775        //   * An installed app can see metadata for 1) other installed apps
3776        //     and 2) ephemeral apps that have explicitly interacted with it
3777        //   * Ephemeral apps can only see their own data and exposed installed apps
3778        //   * Holding a signature permission allows seeing instant apps
3779        if (filterAppAccessLPr(ps, callingUid, userId)) {
3780            return null;
3781        }
3782
3783        final PermissionsState permissionsState = ps.getPermissionsState();
3784
3785        // Compute GIDs only if requested
3786        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3787                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3788        // Compute granted permissions only if package has requested permissions
3789        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3790                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3791        final PackageUserState state = ps.readUserState(userId);
3792
3793        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3794                && ps.isSystem()) {
3795            flags |= MATCH_ANY_USER;
3796        }
3797
3798        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3799                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3800
3801        if (packageInfo == null) {
3802            return null;
3803        }
3804
3805        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3806                resolveExternalPackageNameLPr(p);
3807
3808        return packageInfo;
3809    }
3810
3811    @Override
3812    public void checkPackageStartable(String packageName, int userId) {
3813        final int callingUid = Binder.getCallingUid();
3814        if (getInstantAppPackageName(callingUid) != null) {
3815            throw new SecurityException("Instant applications don't have access to this method");
3816        }
3817        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3818        synchronized (mPackages) {
3819            final PackageSetting ps = mSettings.mPackages.get(packageName);
3820            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3821                throw new SecurityException("Package " + packageName + " was not found!");
3822            }
3823
3824            if (!ps.getInstalled(userId)) {
3825                throw new SecurityException(
3826                        "Package " + packageName + " was not installed for user " + userId + "!");
3827            }
3828
3829            if (mSafeMode && !ps.isSystem()) {
3830                throw new SecurityException("Package " + packageName + " not a system app!");
3831            }
3832
3833            if (mFrozenPackages.contains(packageName)) {
3834                throw new SecurityException("Package " + packageName + " is currently frozen!");
3835            }
3836
3837            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3838                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3839            }
3840        }
3841    }
3842
3843    @Override
3844    public boolean isPackageAvailable(String packageName, int userId) {
3845        if (!sUserManager.exists(userId)) return false;
3846        final int callingUid = Binder.getCallingUid();
3847        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3848                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3849        synchronized (mPackages) {
3850            PackageParser.Package p = mPackages.get(packageName);
3851            if (p != null) {
3852                final PackageSetting ps = (PackageSetting) p.mExtras;
3853                if (filterAppAccessLPr(ps, callingUid, userId)) {
3854                    return false;
3855                }
3856                if (ps != null) {
3857                    final PackageUserState state = ps.readUserState(userId);
3858                    if (state != null) {
3859                        return PackageParser.isAvailable(state);
3860                    }
3861                }
3862            }
3863        }
3864        return false;
3865    }
3866
3867    @Override
3868    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3869        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3870                flags, Binder.getCallingUid(), userId);
3871    }
3872
3873    @Override
3874    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3875            int flags, int userId) {
3876        return getPackageInfoInternal(versionedPackage.getPackageName(),
3877                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3878    }
3879
3880    /**
3881     * Important: The provided filterCallingUid is used exclusively to filter out packages
3882     * that can be seen based on user state. It's typically the original caller uid prior
3883     * to clearing. Because it can only be provided by trusted code, it's value can be
3884     * trusted and will be used as-is; unlike userId which will be validated by this method.
3885     */
3886    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3887            int flags, int filterCallingUid, int userId) {
3888        if (!sUserManager.exists(userId)) return null;
3889        flags = updateFlagsForPackage(flags, userId, packageName);
3890        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
3891                false /* requireFullPermission */, false /* checkShell */, "get package info");
3892
3893        // reader
3894        synchronized (mPackages) {
3895            // Normalize package name to handle renamed packages and static libs
3896            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3897
3898            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3899            if (matchFactoryOnly) {
3900                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3901                if (ps != null) {
3902                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3903                        return null;
3904                    }
3905                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3906                        return null;
3907                    }
3908                    return generatePackageInfo(ps, flags, userId);
3909                }
3910            }
3911
3912            PackageParser.Package p = mPackages.get(packageName);
3913            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3914                return null;
3915            }
3916            if (DEBUG_PACKAGE_INFO)
3917                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3918            if (p != null) {
3919                final PackageSetting ps = (PackageSetting) p.mExtras;
3920                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3921                    return null;
3922                }
3923                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3924                    return null;
3925                }
3926                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3927            }
3928            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3929                final PackageSetting ps = mSettings.mPackages.get(packageName);
3930                if (ps == null) return null;
3931                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3932                    return null;
3933                }
3934                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3935                    return null;
3936                }
3937                return generatePackageInfo(ps, flags, userId);
3938            }
3939        }
3940        return null;
3941    }
3942
3943    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3944        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3945            return true;
3946        }
3947        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3948            return true;
3949        }
3950        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3951            return true;
3952        }
3953        return false;
3954    }
3955
3956    private boolean isComponentVisibleToInstantApp(
3957            @Nullable ComponentName component, @ComponentType int type) {
3958        if (type == TYPE_ACTIVITY) {
3959            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3960            return activity != null
3961                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3962                    : false;
3963        } else if (type == TYPE_RECEIVER) {
3964            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3965            return activity != null
3966                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3967                    : false;
3968        } else if (type == TYPE_SERVICE) {
3969            final PackageParser.Service service = mServices.mServices.get(component);
3970            return service != null
3971                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3972                    : false;
3973        } else if (type == TYPE_PROVIDER) {
3974            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3975            return provider != null
3976                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3977                    : false;
3978        } else if (type == TYPE_UNKNOWN) {
3979            return isComponentVisibleToInstantApp(component);
3980        }
3981        return false;
3982    }
3983
3984    /**
3985     * Returns whether or not access to the application should be filtered.
3986     * <p>
3987     * Access may be limited based upon whether the calling or target applications
3988     * are instant applications.
3989     *
3990     * @see #canAccessInstantApps(int)
3991     */
3992    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3993            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3994        // if we're in an isolated process, get the real calling UID
3995        if (Process.isIsolated(callingUid)) {
3996            callingUid = mIsolatedOwners.get(callingUid);
3997        }
3998        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3999        final boolean callerIsInstantApp = instantAppPkgName != null;
4000        if (ps == null) {
4001            if (callerIsInstantApp) {
4002                // pretend the application exists, but, needs to be filtered
4003                return true;
4004            }
4005            return false;
4006        }
4007        // if the target and caller are the same application, don't filter
4008        if (isCallerSameApp(ps.name, callingUid)) {
4009            return false;
4010        }
4011        if (callerIsInstantApp) {
4012            // request for a specific component; if it hasn't been explicitly exposed, filter
4013            if (component != null) {
4014                return !isComponentVisibleToInstantApp(component, componentType);
4015            }
4016            // request for application; if no components have been explicitly exposed, filter
4017            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4018        }
4019        if (ps.getInstantApp(userId)) {
4020            // caller can see all components of all instant applications, don't filter
4021            if (canViewInstantApps(callingUid, userId)) {
4022                return false;
4023            }
4024            // request for a specific instant application component, filter
4025            if (component != null) {
4026                return true;
4027            }
4028            // request for an instant application; if the caller hasn't been granted access, filter
4029            return !mInstantAppRegistry.isInstantAccessGranted(
4030                    userId, UserHandle.getAppId(callingUid), ps.appId);
4031        }
4032        return false;
4033    }
4034
4035    /**
4036     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4037     */
4038    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4039        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4040    }
4041
4042    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4043            int flags) {
4044        // Callers can access only the libs they depend on, otherwise they need to explicitly
4045        // ask for the shared libraries given the caller is allowed to access all static libs.
4046        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4047            // System/shell/root get to see all static libs
4048            final int appId = UserHandle.getAppId(uid);
4049            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4050                    || appId == Process.ROOT_UID) {
4051                return false;
4052            }
4053        }
4054
4055        // No package means no static lib as it is always on internal storage
4056        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4057            return false;
4058        }
4059
4060        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4061                ps.pkg.staticSharedLibVersion);
4062        if (libEntry == null) {
4063            return false;
4064        }
4065
4066        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4067        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4068        if (uidPackageNames == null) {
4069            return true;
4070        }
4071
4072        for (String uidPackageName : uidPackageNames) {
4073            if (ps.name.equals(uidPackageName)) {
4074                return false;
4075            }
4076            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4077            if (uidPs != null) {
4078                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4079                        libEntry.info.getName());
4080                if (index < 0) {
4081                    continue;
4082                }
4083                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4084                    return false;
4085                }
4086            }
4087        }
4088        return true;
4089    }
4090
4091    @Override
4092    public String[] currentToCanonicalPackageNames(String[] names) {
4093        final int callingUid = Binder.getCallingUid();
4094        if (getInstantAppPackageName(callingUid) != null) {
4095            return names;
4096        }
4097        final String[] out = new String[names.length];
4098        // reader
4099        synchronized (mPackages) {
4100            final int callingUserId = UserHandle.getUserId(callingUid);
4101            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4102            for (int i=names.length-1; i>=0; i--) {
4103                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4104                boolean translateName = false;
4105                if (ps != null && ps.realName != null) {
4106                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4107                    translateName = !targetIsInstantApp
4108                            || canViewInstantApps
4109                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4110                                    UserHandle.getAppId(callingUid), ps.appId);
4111                }
4112                out[i] = translateName ? ps.realName : names[i];
4113            }
4114        }
4115        return out;
4116    }
4117
4118    @Override
4119    public String[] canonicalToCurrentPackageNames(String[] names) {
4120        final int callingUid = Binder.getCallingUid();
4121        if (getInstantAppPackageName(callingUid) != null) {
4122            return names;
4123        }
4124        final String[] out = new String[names.length];
4125        // reader
4126        synchronized (mPackages) {
4127            final int callingUserId = UserHandle.getUserId(callingUid);
4128            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4129            for (int i=names.length-1; i>=0; i--) {
4130                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4131                boolean translateName = false;
4132                if (cur != null) {
4133                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4134                    final boolean targetIsInstantApp =
4135                            ps != null && ps.getInstantApp(callingUserId);
4136                    translateName = !targetIsInstantApp
4137                            || canViewInstantApps
4138                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4139                                    UserHandle.getAppId(callingUid), ps.appId);
4140                }
4141                out[i] = translateName ? cur : names[i];
4142            }
4143        }
4144        return out;
4145    }
4146
4147    @Override
4148    public int getPackageUid(String packageName, int flags, int userId) {
4149        if (!sUserManager.exists(userId)) return -1;
4150        final int callingUid = Binder.getCallingUid();
4151        flags = updateFlagsForPackage(flags, userId, packageName);
4152        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4153                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4154
4155        // reader
4156        synchronized (mPackages) {
4157            final PackageParser.Package p = mPackages.get(packageName);
4158            if (p != null && p.isMatch(flags)) {
4159                PackageSetting ps = (PackageSetting) p.mExtras;
4160                if (filterAppAccessLPr(ps, callingUid, userId)) {
4161                    return -1;
4162                }
4163                return UserHandle.getUid(userId, p.applicationInfo.uid);
4164            }
4165            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4166                final PackageSetting ps = mSettings.mPackages.get(packageName);
4167                if (ps != null && ps.isMatch(flags)
4168                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4169                    return UserHandle.getUid(userId, ps.appId);
4170                }
4171            }
4172        }
4173
4174        return -1;
4175    }
4176
4177    @Override
4178    public int[] getPackageGids(String packageName, int flags, int userId) {
4179        if (!sUserManager.exists(userId)) return null;
4180        final int callingUid = Binder.getCallingUid();
4181        flags = updateFlagsForPackage(flags, userId, packageName);
4182        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4183                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4184
4185        // reader
4186        synchronized (mPackages) {
4187            final PackageParser.Package p = mPackages.get(packageName);
4188            if (p != null && p.isMatch(flags)) {
4189                PackageSetting ps = (PackageSetting) p.mExtras;
4190                if (filterAppAccessLPr(ps, callingUid, userId)) {
4191                    return null;
4192                }
4193                // TODO: Shouldn't this be checking for package installed state for userId and
4194                // return null?
4195                return ps.getPermissionsState().computeGids(userId);
4196            }
4197            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4198                final PackageSetting ps = mSettings.mPackages.get(packageName);
4199                if (ps != null && ps.isMatch(flags)
4200                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4201                    return ps.getPermissionsState().computeGids(userId);
4202                }
4203            }
4204        }
4205
4206        return null;
4207    }
4208
4209    @Override
4210    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4211        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4212    }
4213
4214    @Override
4215    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4216            int flags) {
4217        final List<PermissionInfo> permissionList =
4218                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4219        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4220    }
4221
4222    @Override
4223    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4224        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4225    }
4226
4227    @Override
4228    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4229        final List<PermissionGroupInfo> permissionList =
4230                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4231        return (permissionList == null)
4232                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4233    }
4234
4235    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4236            int filterCallingUid, int userId) {
4237        if (!sUserManager.exists(userId)) return null;
4238        PackageSetting ps = mSettings.mPackages.get(packageName);
4239        if (ps != null) {
4240            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4241                return null;
4242            }
4243            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4244                return null;
4245            }
4246            if (ps.pkg == null) {
4247                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4248                if (pInfo != null) {
4249                    return pInfo.applicationInfo;
4250                }
4251                return null;
4252            }
4253            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4254                    ps.readUserState(userId), userId);
4255            if (ai != null) {
4256                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4257            }
4258            return ai;
4259        }
4260        return null;
4261    }
4262
4263    @Override
4264    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4265        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4266    }
4267
4268    /**
4269     * Important: The provided filterCallingUid is used exclusively to filter out applications
4270     * that can be seen based on user state. It's typically the original caller uid prior
4271     * to clearing. Because it can only be provided by trusted code, it's value can be
4272     * trusted and will be used as-is; unlike userId which will be validated by this method.
4273     */
4274    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4275            int filterCallingUid, int userId) {
4276        if (!sUserManager.exists(userId)) return null;
4277        flags = updateFlagsForApplication(flags, userId, packageName);
4278        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4279                false /* requireFullPermission */, false /* checkShell */, "get application info");
4280
4281        // writer
4282        synchronized (mPackages) {
4283            // Normalize package name to handle renamed packages and static libs
4284            packageName = resolveInternalPackageNameLPr(packageName,
4285                    PackageManager.VERSION_CODE_HIGHEST);
4286
4287            PackageParser.Package p = mPackages.get(packageName);
4288            if (DEBUG_PACKAGE_INFO) Log.v(
4289                    TAG, "getApplicationInfo " + packageName
4290                    + ": " + p);
4291            if (p != null) {
4292                PackageSetting ps = mSettings.mPackages.get(packageName);
4293                if (ps == null) return null;
4294                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4295                    return null;
4296                }
4297                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4298                    return null;
4299                }
4300                // Note: isEnabledLP() does not apply here - always return info
4301                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4302                        p, flags, ps.readUserState(userId), userId);
4303                if (ai != null) {
4304                    ai.packageName = resolveExternalPackageNameLPr(p);
4305                }
4306                return ai;
4307            }
4308            if ("android".equals(packageName)||"system".equals(packageName)) {
4309                return mAndroidApplication;
4310            }
4311            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4312                // Already generates the external package name
4313                return generateApplicationInfoFromSettingsLPw(packageName,
4314                        flags, filterCallingUid, userId);
4315            }
4316        }
4317        return null;
4318    }
4319
4320    private String normalizePackageNameLPr(String packageName) {
4321        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4322        return normalizedPackageName != null ? normalizedPackageName : packageName;
4323    }
4324
4325    @Override
4326    public void deletePreloadsFileCache() {
4327        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4328            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4329        }
4330        File dir = Environment.getDataPreloadsFileCacheDirectory();
4331        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4332        FileUtils.deleteContents(dir);
4333    }
4334
4335    @Override
4336    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4337            final int storageFlags, final IPackageDataObserver observer) {
4338        mContext.enforceCallingOrSelfPermission(
4339                android.Manifest.permission.CLEAR_APP_CACHE, null);
4340        mHandler.post(() -> {
4341            boolean success = false;
4342            try {
4343                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4344                success = true;
4345            } catch (IOException e) {
4346                Slog.w(TAG, e);
4347            }
4348            if (observer != null) {
4349                try {
4350                    observer.onRemoveCompleted(null, success);
4351                } catch (RemoteException e) {
4352                    Slog.w(TAG, e);
4353                }
4354            }
4355        });
4356    }
4357
4358    @Override
4359    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4360            final int storageFlags, final IntentSender pi) {
4361        mContext.enforceCallingOrSelfPermission(
4362                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4363        mHandler.post(() -> {
4364            boolean success = false;
4365            try {
4366                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4367                success = true;
4368            } catch (IOException e) {
4369                Slog.w(TAG, e);
4370            }
4371            if (pi != null) {
4372                try {
4373                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4374                } catch (SendIntentException e) {
4375                    Slog.w(TAG, e);
4376                }
4377            }
4378        });
4379    }
4380
4381    /**
4382     * Blocking call to clear various types of cached data across the system
4383     * until the requested bytes are available.
4384     */
4385    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4386        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4387        final File file = storage.findPathForUuid(volumeUuid);
4388        if (file.getUsableSpace() >= bytes) return;
4389
4390        if (ENABLE_FREE_CACHE_V2) {
4391            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4392                    volumeUuid);
4393            final boolean aggressive = (storageFlags
4394                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4395            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4396
4397            // 1. Pre-flight to determine if we have any chance to succeed
4398            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4399            if (internalVolume && (aggressive || SystemProperties
4400                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4401                deletePreloadsFileCache();
4402                if (file.getUsableSpace() >= bytes) return;
4403            }
4404
4405            // 3. Consider parsed APK data (aggressive only)
4406            if (internalVolume && aggressive) {
4407                FileUtils.deleteContents(mCacheDir);
4408                if (file.getUsableSpace() >= bytes) return;
4409            }
4410
4411            // 4. Consider cached app data (above quotas)
4412            try {
4413                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4414                        Installer.FLAG_FREE_CACHE_V2);
4415            } catch (InstallerException ignored) {
4416            }
4417            if (file.getUsableSpace() >= bytes) return;
4418
4419            // 5. Consider shared libraries with refcount=0 and age>min cache period
4420            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4421                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4422                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4423                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4424                return;
4425            }
4426
4427            // 6. Consider dexopt output (aggressive only)
4428            // TODO: Implement
4429
4430            // 7. Consider installed instant apps unused longer than min cache period
4431            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4432                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4433                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4434                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4435                return;
4436            }
4437
4438            // 8. Consider cached app data (below quotas)
4439            try {
4440                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4441                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4442            } catch (InstallerException ignored) {
4443            }
4444            if (file.getUsableSpace() >= bytes) return;
4445
4446            // 9. Consider DropBox entries
4447            // TODO: Implement
4448
4449            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4450            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4451                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4452                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4453                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4454                return;
4455            }
4456        } else {
4457            try {
4458                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4459            } catch (InstallerException ignored) {
4460            }
4461            if (file.getUsableSpace() >= bytes) return;
4462        }
4463
4464        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4465    }
4466
4467    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4468            throws IOException {
4469        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4470        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4471
4472        List<VersionedPackage> packagesToDelete = null;
4473        final long now = System.currentTimeMillis();
4474
4475        synchronized (mPackages) {
4476            final int[] allUsers = sUserManager.getUserIds();
4477            final int libCount = mSharedLibraries.size();
4478            for (int i = 0; i < libCount; i++) {
4479                final LongSparseArray<SharedLibraryEntry> versionedLib
4480                        = mSharedLibraries.valueAt(i);
4481                if (versionedLib == null) {
4482                    continue;
4483                }
4484                final int versionCount = versionedLib.size();
4485                for (int j = 0; j < versionCount; j++) {
4486                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4487                    // Skip packages that are not static shared libs.
4488                    if (!libInfo.isStatic()) {
4489                        break;
4490                    }
4491                    // Important: We skip static shared libs used for some user since
4492                    // in such a case we need to keep the APK on the device. The check for
4493                    // a lib being used for any user is performed by the uninstall call.
4494                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4495                    // Resolve the package name - we use synthetic package names internally
4496                    final String internalPackageName = resolveInternalPackageNameLPr(
4497                            declaringPackage.getPackageName(),
4498                            declaringPackage.getLongVersionCode());
4499                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4500                    // Skip unused static shared libs cached less than the min period
4501                    // to prevent pruning a lib needed by a subsequently installed package.
4502                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4503                        continue;
4504                    }
4505                    if (packagesToDelete == null) {
4506                        packagesToDelete = new ArrayList<>();
4507                    }
4508                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4509                            declaringPackage.getLongVersionCode()));
4510                }
4511            }
4512        }
4513
4514        if (packagesToDelete != null) {
4515            final int packageCount = packagesToDelete.size();
4516            for (int i = 0; i < packageCount; i++) {
4517                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4518                // Delete the package synchronously (will fail of the lib used for any user).
4519                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4520                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4521                                == PackageManager.DELETE_SUCCEEDED) {
4522                    if (volume.getUsableSpace() >= neededSpace) {
4523                        return true;
4524                    }
4525                }
4526            }
4527        }
4528
4529        return false;
4530    }
4531
4532    /**
4533     * Update given flags based on encryption status of current user.
4534     */
4535    private int updateFlags(int flags, int userId) {
4536        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4537                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4538            // Caller expressed an explicit opinion about what encryption
4539            // aware/unaware components they want to see, so fall through and
4540            // give them what they want
4541        } else {
4542            // Caller expressed no opinion, so match based on user state
4543            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4544                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4545            } else {
4546                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4547            }
4548        }
4549        return flags;
4550    }
4551
4552    private UserManagerInternal getUserManagerInternal() {
4553        if (mUserManagerInternal == null) {
4554            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4555        }
4556        return mUserManagerInternal;
4557    }
4558
4559    private DeviceIdleController.LocalService getDeviceIdleController() {
4560        if (mDeviceIdleController == null) {
4561            mDeviceIdleController =
4562                    LocalServices.getService(DeviceIdleController.LocalService.class);
4563        }
4564        return mDeviceIdleController;
4565    }
4566
4567    /**
4568     * Update given flags when being used to request {@link PackageInfo}.
4569     */
4570    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4571        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4572        boolean triaged = true;
4573        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4574                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4575            // Caller is asking for component details, so they'd better be
4576            // asking for specific encryption matching behavior, or be triaged
4577            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4578                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4579                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4580                triaged = false;
4581            }
4582        }
4583        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4584                | PackageManager.MATCH_SYSTEM_ONLY
4585                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4586            triaged = false;
4587        }
4588        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4589            mPermissionManager.enforceCrossUserPermission(
4590                    Binder.getCallingUid(), userId, false, false,
4591                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4592                    + Debug.getCallers(5));
4593        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4594                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4595            // If the caller wants all packages and has a restricted profile associated with it,
4596            // then match all users. This is to make sure that launchers that need to access work
4597            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4598            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4599            flags |= PackageManager.MATCH_ANY_USER;
4600        }
4601        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4602            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4603                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4604        }
4605        return updateFlags(flags, userId);
4606    }
4607
4608    /**
4609     * Update given flags when being used to request {@link ApplicationInfo}.
4610     */
4611    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4612        return updateFlagsForPackage(flags, userId, cookie);
4613    }
4614
4615    /**
4616     * Update given flags when being used to request {@link ComponentInfo}.
4617     */
4618    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4619        if (cookie instanceof Intent) {
4620            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4621                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4622            }
4623        }
4624
4625        boolean triaged = true;
4626        // Caller is asking for component details, so they'd better be
4627        // asking for specific encryption matching behavior, or be triaged
4628        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4629                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4630                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4631            triaged = false;
4632        }
4633        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4634            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4635                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4636        }
4637
4638        return updateFlags(flags, userId);
4639    }
4640
4641    /**
4642     * Update given intent when being used to request {@link ResolveInfo}.
4643     */
4644    private Intent updateIntentForResolve(Intent intent) {
4645        if (intent.getSelector() != null) {
4646            intent = intent.getSelector();
4647        }
4648        if (DEBUG_PREFERRED) {
4649            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4650        }
4651        return intent;
4652    }
4653
4654    /**
4655     * Update given flags when being used to request {@link ResolveInfo}.
4656     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4657     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4658     * flag set. However, this flag is only honoured in three circumstances:
4659     * <ul>
4660     * <li>when called from a system process</li>
4661     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4662     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4663     * action and a {@code android.intent.category.BROWSABLE} category</li>
4664     * </ul>
4665     */
4666    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4667        return updateFlagsForResolve(flags, userId, intent, callingUid,
4668                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4669    }
4670    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4671            boolean wantInstantApps) {
4672        return updateFlagsForResolve(flags, userId, intent, callingUid,
4673                wantInstantApps, false /*onlyExposedExplicitly*/);
4674    }
4675    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4676            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4677        // Safe mode means we shouldn't match any third-party components
4678        if (mSafeMode) {
4679            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4680        }
4681        if (getInstantAppPackageName(callingUid) != null) {
4682            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4683            if (onlyExposedExplicitly) {
4684                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4685            }
4686            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4687            flags |= PackageManager.MATCH_INSTANT;
4688        } else {
4689            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4690            final boolean allowMatchInstant =
4691                    (wantInstantApps
4692                            && Intent.ACTION_VIEW.equals(intent.getAction())
4693                            && hasWebURI(intent))
4694                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4695            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4696                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4697            if (!allowMatchInstant) {
4698                flags &= ~PackageManager.MATCH_INSTANT;
4699            }
4700        }
4701        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4702    }
4703
4704    @Override
4705    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4706        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4707    }
4708
4709    /**
4710     * Important: The provided filterCallingUid is used exclusively to filter out activities
4711     * that can be seen based on user state. It's typically the original caller uid prior
4712     * to clearing. Because it can only be provided by trusted code, it's value can be
4713     * trusted and will be used as-is; unlike userId which will be validated by this method.
4714     */
4715    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4716            int filterCallingUid, int userId) {
4717        if (!sUserManager.exists(userId)) return null;
4718        flags = updateFlagsForComponent(flags, userId, component);
4719        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4720                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4721        synchronized (mPackages) {
4722            PackageParser.Activity a = mActivities.mActivities.get(component);
4723
4724            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4725            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4726                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4727                if (ps == null) return null;
4728                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4729                    return null;
4730                }
4731                return PackageParser.generateActivityInfo(
4732                        a, flags, ps.readUserState(userId), userId);
4733            }
4734            if (mResolveComponentName.equals(component)) {
4735                return PackageParser.generateActivityInfo(
4736                        mResolveActivity, flags, new PackageUserState(), userId);
4737            }
4738        }
4739        return null;
4740    }
4741
4742    @Override
4743    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4744            String resolvedType) {
4745        synchronized (mPackages) {
4746            if (component.equals(mResolveComponentName)) {
4747                // The resolver supports EVERYTHING!
4748                return true;
4749            }
4750            final int callingUid = Binder.getCallingUid();
4751            final int callingUserId = UserHandle.getUserId(callingUid);
4752            PackageParser.Activity a = mActivities.mActivities.get(component);
4753            if (a == null) {
4754                return false;
4755            }
4756            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4757            if (ps == null) {
4758                return false;
4759            }
4760            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4761                return false;
4762            }
4763            for (int i=0; i<a.intents.size(); i++) {
4764                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4765                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4766                    return true;
4767                }
4768            }
4769            return false;
4770        }
4771    }
4772
4773    @Override
4774    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4775        if (!sUserManager.exists(userId)) return null;
4776        final int callingUid = Binder.getCallingUid();
4777        flags = updateFlagsForComponent(flags, userId, component);
4778        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4779                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4780        synchronized (mPackages) {
4781            PackageParser.Activity a = mReceivers.mActivities.get(component);
4782            if (DEBUG_PACKAGE_INFO) Log.v(
4783                TAG, "getReceiverInfo " + component + ": " + a);
4784            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4785                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4786                if (ps == null) return null;
4787                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4788                    return null;
4789                }
4790                return PackageParser.generateActivityInfo(
4791                        a, flags, ps.readUserState(userId), userId);
4792            }
4793        }
4794        return null;
4795    }
4796
4797    @Override
4798    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4799            int flags, int userId) {
4800        if (!sUserManager.exists(userId)) return null;
4801        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4802        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4803            return null;
4804        }
4805
4806        flags = updateFlagsForPackage(flags, userId, null);
4807
4808        final boolean canSeeStaticLibraries =
4809                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4810                        == PERMISSION_GRANTED
4811                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4812                        == PERMISSION_GRANTED
4813                || canRequestPackageInstallsInternal(packageName,
4814                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4815                        false  /* throwIfPermNotDeclared*/)
4816                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4817                        == PERMISSION_GRANTED;
4818
4819        synchronized (mPackages) {
4820            List<SharedLibraryInfo> result = null;
4821
4822            final int libCount = mSharedLibraries.size();
4823            for (int i = 0; i < libCount; i++) {
4824                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4825                if (versionedLib == null) {
4826                    continue;
4827                }
4828
4829                final int versionCount = versionedLib.size();
4830                for (int j = 0; j < versionCount; j++) {
4831                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4832                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4833                        break;
4834                    }
4835                    final long identity = Binder.clearCallingIdentity();
4836                    try {
4837                        PackageInfo packageInfo = getPackageInfoVersioned(
4838                                libInfo.getDeclaringPackage(), flags
4839                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4840                        if (packageInfo == null) {
4841                            continue;
4842                        }
4843                    } finally {
4844                        Binder.restoreCallingIdentity(identity);
4845                    }
4846
4847                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4848                            libInfo.getLongVersion(), libInfo.getType(),
4849                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4850                            flags, userId));
4851
4852                    if (result == null) {
4853                        result = new ArrayList<>();
4854                    }
4855                    result.add(resLibInfo);
4856                }
4857            }
4858
4859            return result != null ? new ParceledListSlice<>(result) : null;
4860        }
4861    }
4862
4863    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4864            SharedLibraryInfo libInfo, int flags, int userId) {
4865        List<VersionedPackage> versionedPackages = null;
4866        final int packageCount = mSettings.mPackages.size();
4867        for (int i = 0; i < packageCount; i++) {
4868            PackageSetting ps = mSettings.mPackages.valueAt(i);
4869
4870            if (ps == null) {
4871                continue;
4872            }
4873
4874            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4875                continue;
4876            }
4877
4878            final String libName = libInfo.getName();
4879            if (libInfo.isStatic()) {
4880                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4881                if (libIdx < 0) {
4882                    continue;
4883                }
4884                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
4885                    continue;
4886                }
4887                if (versionedPackages == null) {
4888                    versionedPackages = new ArrayList<>();
4889                }
4890                // If the dependent is a static shared lib, use the public package name
4891                String dependentPackageName = ps.name;
4892                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4893                    dependentPackageName = ps.pkg.manifestPackageName;
4894                }
4895                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4896            } else if (ps.pkg != null) {
4897                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4898                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4899                    if (versionedPackages == null) {
4900                        versionedPackages = new ArrayList<>();
4901                    }
4902                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4903                }
4904            }
4905        }
4906
4907        return versionedPackages;
4908    }
4909
4910    @Override
4911    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4912        if (!sUserManager.exists(userId)) return null;
4913        final int callingUid = Binder.getCallingUid();
4914        flags = updateFlagsForComponent(flags, userId, component);
4915        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4916                false /* requireFullPermission */, false /* checkShell */, "get service info");
4917        synchronized (mPackages) {
4918            PackageParser.Service s = mServices.mServices.get(component);
4919            if (DEBUG_PACKAGE_INFO) Log.v(
4920                TAG, "getServiceInfo " + component + ": " + s);
4921            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4922                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4923                if (ps == null) return null;
4924                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4925                    return null;
4926                }
4927                return PackageParser.generateServiceInfo(
4928                        s, flags, ps.readUserState(userId), userId);
4929            }
4930        }
4931        return null;
4932    }
4933
4934    @Override
4935    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4936        if (!sUserManager.exists(userId)) return null;
4937        final int callingUid = Binder.getCallingUid();
4938        flags = updateFlagsForComponent(flags, userId, component);
4939        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4940                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4941        synchronized (mPackages) {
4942            PackageParser.Provider p = mProviders.mProviders.get(component);
4943            if (DEBUG_PACKAGE_INFO) Log.v(
4944                TAG, "getProviderInfo " + component + ": " + p);
4945            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4946                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4947                if (ps == null) return null;
4948                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4949                    return null;
4950                }
4951                return PackageParser.generateProviderInfo(
4952                        p, flags, ps.readUserState(userId), userId);
4953            }
4954        }
4955        return null;
4956    }
4957
4958    @Override
4959    public String[] getSystemSharedLibraryNames() {
4960        // allow instant applications
4961        synchronized (mPackages) {
4962            Set<String> libs = null;
4963            final int libCount = mSharedLibraries.size();
4964            for (int i = 0; i < libCount; i++) {
4965                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4966                if (versionedLib == null) {
4967                    continue;
4968                }
4969                final int versionCount = versionedLib.size();
4970                for (int j = 0; j < versionCount; j++) {
4971                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4972                    if (!libEntry.info.isStatic()) {
4973                        if (libs == null) {
4974                            libs = new ArraySet<>();
4975                        }
4976                        libs.add(libEntry.info.getName());
4977                        break;
4978                    }
4979                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4980                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4981                            UserHandle.getUserId(Binder.getCallingUid()),
4982                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4983                        if (libs == null) {
4984                            libs = new ArraySet<>();
4985                        }
4986                        libs.add(libEntry.info.getName());
4987                        break;
4988                    }
4989                }
4990            }
4991
4992            if (libs != null) {
4993                String[] libsArray = new String[libs.size()];
4994                libs.toArray(libsArray);
4995                return libsArray;
4996            }
4997
4998            return null;
4999        }
5000    }
5001
5002    @Override
5003    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5004        // allow instant applications
5005        synchronized (mPackages) {
5006            return mServicesSystemSharedLibraryPackageName;
5007        }
5008    }
5009
5010    @Override
5011    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5012        // allow instant applications
5013        synchronized (mPackages) {
5014            return mSharedSystemSharedLibraryPackageName;
5015        }
5016    }
5017
5018    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5019        for (int i = userList.length - 1; i >= 0; --i) {
5020            final int userId = userList[i];
5021            // don't add instant app to the list of updates
5022            if (pkgSetting.getInstantApp(userId)) {
5023                continue;
5024            }
5025            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5026            if (changedPackages == null) {
5027                changedPackages = new SparseArray<>();
5028                mChangedPackages.put(userId, changedPackages);
5029            }
5030            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5031            if (sequenceNumbers == null) {
5032                sequenceNumbers = new HashMap<>();
5033                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5034            }
5035            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5036            if (sequenceNumber != null) {
5037                changedPackages.remove(sequenceNumber);
5038            }
5039            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5040            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5041        }
5042        mChangedPackagesSequenceNumber++;
5043    }
5044
5045    @Override
5046    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5047        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5048            return null;
5049        }
5050        synchronized (mPackages) {
5051            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5052                return null;
5053            }
5054            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5055            if (changedPackages == null) {
5056                return null;
5057            }
5058            final List<String> packageNames =
5059                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5060            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5061                final String packageName = changedPackages.get(i);
5062                if (packageName != null) {
5063                    packageNames.add(packageName);
5064                }
5065            }
5066            return packageNames.isEmpty()
5067                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5068        }
5069    }
5070
5071    @Override
5072    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5073        // allow instant applications
5074        ArrayList<FeatureInfo> res;
5075        synchronized (mAvailableFeatures) {
5076            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5077            res.addAll(mAvailableFeatures.values());
5078        }
5079        final FeatureInfo fi = new FeatureInfo();
5080        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5081                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5082        res.add(fi);
5083
5084        return new ParceledListSlice<>(res);
5085    }
5086
5087    @Override
5088    public boolean hasSystemFeature(String name, int version) {
5089        // allow instant applications
5090        synchronized (mAvailableFeatures) {
5091            final FeatureInfo feat = mAvailableFeatures.get(name);
5092            if (feat == null) {
5093                return false;
5094            } else {
5095                return feat.version >= version;
5096            }
5097        }
5098    }
5099
5100    @Override
5101    public int checkPermission(String permName, String pkgName, int userId) {
5102        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5103    }
5104
5105    @Override
5106    public int checkUidPermission(String permName, int uid) {
5107        return mPermissionManager.checkUidPermission(permName, uid, getCallingUid());
5108    }
5109
5110    @Override
5111    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5112        if (UserHandle.getCallingUserId() != userId) {
5113            mContext.enforceCallingPermission(
5114                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5115                    "isPermissionRevokedByPolicy for user " + userId);
5116        }
5117
5118        if (checkPermission(permission, packageName, userId)
5119                == PackageManager.PERMISSION_GRANTED) {
5120            return false;
5121        }
5122
5123        final int callingUid = Binder.getCallingUid();
5124        if (getInstantAppPackageName(callingUid) != null) {
5125            if (!isCallerSameApp(packageName, callingUid)) {
5126                return false;
5127            }
5128        } else {
5129            if (isInstantApp(packageName, userId)) {
5130                return false;
5131            }
5132        }
5133
5134        final long identity = Binder.clearCallingIdentity();
5135        try {
5136            final int flags = getPermissionFlags(permission, packageName, userId);
5137            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5138        } finally {
5139            Binder.restoreCallingIdentity(identity);
5140        }
5141    }
5142
5143    @Override
5144    public String getPermissionControllerPackageName() {
5145        synchronized (mPackages) {
5146            return mRequiredInstallerPackage;
5147        }
5148    }
5149
5150    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5151        return mPermissionManager.addDynamicPermission(
5152                info, async, getCallingUid(), new PermissionCallback() {
5153                    @Override
5154                    public void onPermissionChanged() {
5155                        if (!async) {
5156                            mSettings.writeLPr();
5157                        } else {
5158                            scheduleWriteSettingsLocked();
5159                        }
5160                    }
5161                });
5162    }
5163
5164    @Override
5165    public boolean addPermission(PermissionInfo info) {
5166        synchronized (mPackages) {
5167            return addDynamicPermission(info, false);
5168        }
5169    }
5170
5171    @Override
5172    public boolean addPermissionAsync(PermissionInfo info) {
5173        synchronized (mPackages) {
5174            return addDynamicPermission(info, true);
5175        }
5176    }
5177
5178    @Override
5179    public void removePermission(String permName) {
5180        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5181    }
5182
5183    @Override
5184    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5185        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5186                getCallingUid(), userId, mPermissionCallback);
5187    }
5188
5189    @Override
5190    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5191        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5192                getCallingUid(), userId, mPermissionCallback);
5193    }
5194
5195    @Override
5196    public void resetRuntimePermissions() {
5197        mContext.enforceCallingOrSelfPermission(
5198                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5199                "revokeRuntimePermission");
5200
5201        int callingUid = Binder.getCallingUid();
5202        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5203            mContext.enforceCallingOrSelfPermission(
5204                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5205                    "resetRuntimePermissions");
5206        }
5207
5208        synchronized (mPackages) {
5209            mPermissionManager.updateAllPermissions(
5210                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5211                    mPermissionCallback);
5212            for (int userId : UserManagerService.getInstance().getUserIds()) {
5213                final int packageCount = mPackages.size();
5214                for (int i = 0; i < packageCount; i++) {
5215                    PackageParser.Package pkg = mPackages.valueAt(i);
5216                    if (!(pkg.mExtras instanceof PackageSetting)) {
5217                        continue;
5218                    }
5219                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5220                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5221                }
5222            }
5223        }
5224    }
5225
5226    @Override
5227    public int getPermissionFlags(String permName, String packageName, int userId) {
5228        return mPermissionManager.getPermissionFlags(
5229                permName, packageName, getCallingUid(), userId);
5230    }
5231
5232    @Override
5233    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5234            int flagValues, int userId) {
5235        mPermissionManager.updatePermissionFlags(
5236                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5237                mPermissionCallback);
5238    }
5239
5240    /**
5241     * Update the permission flags for all packages and runtime permissions of a user in order
5242     * to allow device or profile owner to remove POLICY_FIXED.
5243     */
5244    @Override
5245    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5246        synchronized (mPackages) {
5247            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5248                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5249                    mPermissionCallback);
5250            if (changed) {
5251                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5252            }
5253        }
5254    }
5255
5256    @Override
5257    public boolean shouldShowRequestPermissionRationale(String permissionName,
5258            String packageName, int userId) {
5259        if (UserHandle.getCallingUserId() != userId) {
5260            mContext.enforceCallingPermission(
5261                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5262                    "canShowRequestPermissionRationale for user " + userId);
5263        }
5264
5265        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5266        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5267            return false;
5268        }
5269
5270        if (checkPermission(permissionName, packageName, userId)
5271                == PackageManager.PERMISSION_GRANTED) {
5272            return false;
5273        }
5274
5275        final int flags;
5276
5277        final long identity = Binder.clearCallingIdentity();
5278        try {
5279            flags = getPermissionFlags(permissionName,
5280                    packageName, userId);
5281        } finally {
5282            Binder.restoreCallingIdentity(identity);
5283        }
5284
5285        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5286                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5287                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5288
5289        if ((flags & fixedFlags) != 0) {
5290            return false;
5291        }
5292
5293        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5294    }
5295
5296    @Override
5297    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5298        mContext.enforceCallingOrSelfPermission(
5299                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5300                "addOnPermissionsChangeListener");
5301
5302        synchronized (mPackages) {
5303            mOnPermissionChangeListeners.addListenerLocked(listener);
5304        }
5305    }
5306
5307    @Override
5308    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5309        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5310            throw new SecurityException("Instant applications don't have access to this method");
5311        }
5312        synchronized (mPackages) {
5313            mOnPermissionChangeListeners.removeListenerLocked(listener);
5314        }
5315    }
5316
5317    @Override
5318    public boolean isProtectedBroadcast(String actionName) {
5319        // allow instant applications
5320        synchronized (mProtectedBroadcasts) {
5321            if (mProtectedBroadcasts.contains(actionName)) {
5322                return true;
5323            } else if (actionName != null) {
5324                // TODO: remove these terrible hacks
5325                if (actionName.startsWith("android.net.netmon.lingerExpired")
5326                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5327                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5328                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5329                    return true;
5330                }
5331            }
5332        }
5333        return false;
5334    }
5335
5336    @Override
5337    public int checkSignatures(String pkg1, String pkg2) {
5338        synchronized (mPackages) {
5339            final PackageParser.Package p1 = mPackages.get(pkg1);
5340            final PackageParser.Package p2 = mPackages.get(pkg2);
5341            if (p1 == null || p1.mExtras == null
5342                    || p2 == null || p2.mExtras == null) {
5343                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5344            }
5345            final int callingUid = Binder.getCallingUid();
5346            final int callingUserId = UserHandle.getUserId(callingUid);
5347            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5348            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5349            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5350                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5351                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5352            }
5353            return compareSignatures(p1.mSignatures, p2.mSignatures);
5354        }
5355    }
5356
5357    @Override
5358    public int checkUidSignatures(int uid1, int uid2) {
5359        final int callingUid = Binder.getCallingUid();
5360        final int callingUserId = UserHandle.getUserId(callingUid);
5361        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5362        // Map to base uids.
5363        uid1 = UserHandle.getAppId(uid1);
5364        uid2 = UserHandle.getAppId(uid2);
5365        // reader
5366        synchronized (mPackages) {
5367            Signature[] s1;
5368            Signature[] s2;
5369            Object obj = mSettings.getUserIdLPr(uid1);
5370            if (obj != null) {
5371                if (obj instanceof SharedUserSetting) {
5372                    if (isCallerInstantApp) {
5373                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5374                    }
5375                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5376                } else if (obj instanceof PackageSetting) {
5377                    final PackageSetting ps = (PackageSetting) obj;
5378                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5379                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5380                    }
5381                    s1 = ps.signatures.mSignatures;
5382                } else {
5383                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5384                }
5385            } else {
5386                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5387            }
5388            obj = mSettings.getUserIdLPr(uid2);
5389            if (obj != null) {
5390                if (obj instanceof SharedUserSetting) {
5391                    if (isCallerInstantApp) {
5392                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5393                    }
5394                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5395                } else if (obj instanceof PackageSetting) {
5396                    final PackageSetting ps = (PackageSetting) obj;
5397                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5398                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5399                    }
5400                    s2 = ps.signatures.mSignatures;
5401                } else {
5402                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5403                }
5404            } else {
5405                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5406            }
5407            return compareSignatures(s1, s2);
5408        }
5409    }
5410
5411    /**
5412     * This method should typically only be used when granting or revoking
5413     * permissions, since the app may immediately restart after this call.
5414     * <p>
5415     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5416     * guard your work against the app being relaunched.
5417     */
5418    private void killUid(int appId, int userId, String reason) {
5419        final long identity = Binder.clearCallingIdentity();
5420        try {
5421            IActivityManager am = ActivityManager.getService();
5422            if (am != null) {
5423                try {
5424                    am.killUid(appId, userId, reason);
5425                } catch (RemoteException e) {
5426                    /* ignore - same process */
5427                }
5428            }
5429        } finally {
5430            Binder.restoreCallingIdentity(identity);
5431        }
5432    }
5433
5434    /**
5435     * If the database version for this type of package (internal storage or
5436     * external storage) is less than the version where package signatures
5437     * were updated, return true.
5438     */
5439    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5440        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5441        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5442    }
5443
5444    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5445        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5446        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5447    }
5448
5449    @Override
5450    public List<String> getAllPackages() {
5451        final int callingUid = Binder.getCallingUid();
5452        final int callingUserId = UserHandle.getUserId(callingUid);
5453        synchronized (mPackages) {
5454            if (canViewInstantApps(callingUid, callingUserId)) {
5455                return new ArrayList<String>(mPackages.keySet());
5456            }
5457            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5458            final List<String> result = new ArrayList<>();
5459            if (instantAppPkgName != null) {
5460                // caller is an instant application; filter unexposed applications
5461                for (PackageParser.Package pkg : mPackages.values()) {
5462                    if (!pkg.visibleToInstantApps) {
5463                        continue;
5464                    }
5465                    result.add(pkg.packageName);
5466                }
5467            } else {
5468                // caller is a normal application; filter instant applications
5469                for (PackageParser.Package pkg : mPackages.values()) {
5470                    final PackageSetting ps =
5471                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5472                    if (ps != null
5473                            && ps.getInstantApp(callingUserId)
5474                            && !mInstantAppRegistry.isInstantAccessGranted(
5475                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5476                        continue;
5477                    }
5478                    result.add(pkg.packageName);
5479                }
5480            }
5481            return result;
5482        }
5483    }
5484
5485    @Override
5486    public String[] getPackagesForUid(int uid) {
5487        final int callingUid = Binder.getCallingUid();
5488        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5489        final int userId = UserHandle.getUserId(uid);
5490        uid = UserHandle.getAppId(uid);
5491        // reader
5492        synchronized (mPackages) {
5493            Object obj = mSettings.getUserIdLPr(uid);
5494            if (obj instanceof SharedUserSetting) {
5495                if (isCallerInstantApp) {
5496                    return null;
5497                }
5498                final SharedUserSetting sus = (SharedUserSetting) obj;
5499                final int N = sus.packages.size();
5500                String[] res = new String[N];
5501                final Iterator<PackageSetting> it = sus.packages.iterator();
5502                int i = 0;
5503                while (it.hasNext()) {
5504                    PackageSetting ps = it.next();
5505                    if (ps.getInstalled(userId)) {
5506                        res[i++] = ps.name;
5507                    } else {
5508                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5509                    }
5510                }
5511                return res;
5512            } else if (obj instanceof PackageSetting) {
5513                final PackageSetting ps = (PackageSetting) obj;
5514                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5515                    return new String[]{ps.name};
5516                }
5517            }
5518        }
5519        return null;
5520    }
5521
5522    @Override
5523    public String getNameForUid(int uid) {
5524        final int callingUid = Binder.getCallingUid();
5525        if (getInstantAppPackageName(callingUid) != null) {
5526            return null;
5527        }
5528        synchronized (mPackages) {
5529            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5530            if (obj instanceof SharedUserSetting) {
5531                final SharedUserSetting sus = (SharedUserSetting) obj;
5532                return sus.name + ":" + sus.userId;
5533            } else if (obj instanceof PackageSetting) {
5534                final PackageSetting ps = (PackageSetting) obj;
5535                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5536                    return null;
5537                }
5538                return ps.name;
5539            }
5540            return null;
5541        }
5542    }
5543
5544    @Override
5545    public String[] getNamesForUids(int[] uids) {
5546        if (uids == null || uids.length == 0) {
5547            return null;
5548        }
5549        final int callingUid = Binder.getCallingUid();
5550        if (getInstantAppPackageName(callingUid) != null) {
5551            return null;
5552        }
5553        final String[] names = new String[uids.length];
5554        synchronized (mPackages) {
5555            for (int i = uids.length - 1; i >= 0; i--) {
5556                final int uid = uids[i];
5557                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5558                if (obj instanceof SharedUserSetting) {
5559                    final SharedUserSetting sus = (SharedUserSetting) obj;
5560                    names[i] = "shared:" + sus.name;
5561                } else if (obj instanceof PackageSetting) {
5562                    final PackageSetting ps = (PackageSetting) obj;
5563                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5564                        names[i] = null;
5565                    } else {
5566                        names[i] = ps.name;
5567                    }
5568                } else {
5569                    names[i] = null;
5570                }
5571            }
5572        }
5573        return names;
5574    }
5575
5576    @Override
5577    public int getUidForSharedUser(String sharedUserName) {
5578        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5579            return -1;
5580        }
5581        if (sharedUserName == null) {
5582            return -1;
5583        }
5584        // reader
5585        synchronized (mPackages) {
5586            SharedUserSetting suid;
5587            try {
5588                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5589                if (suid != null) {
5590                    return suid.userId;
5591                }
5592            } catch (PackageManagerException ignore) {
5593                // can't happen, but, still need to catch it
5594            }
5595            return -1;
5596        }
5597    }
5598
5599    @Override
5600    public int getFlagsForUid(int uid) {
5601        final int callingUid = Binder.getCallingUid();
5602        if (getInstantAppPackageName(callingUid) != null) {
5603            return 0;
5604        }
5605        synchronized (mPackages) {
5606            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5607            if (obj instanceof SharedUserSetting) {
5608                final SharedUserSetting sus = (SharedUserSetting) obj;
5609                return sus.pkgFlags;
5610            } else if (obj instanceof PackageSetting) {
5611                final PackageSetting ps = (PackageSetting) obj;
5612                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5613                    return 0;
5614                }
5615                return ps.pkgFlags;
5616            }
5617        }
5618        return 0;
5619    }
5620
5621    @Override
5622    public int getPrivateFlagsForUid(int uid) {
5623        final int callingUid = Binder.getCallingUid();
5624        if (getInstantAppPackageName(callingUid) != null) {
5625            return 0;
5626        }
5627        synchronized (mPackages) {
5628            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5629            if (obj instanceof SharedUserSetting) {
5630                final SharedUserSetting sus = (SharedUserSetting) obj;
5631                return sus.pkgPrivateFlags;
5632            } else if (obj instanceof PackageSetting) {
5633                final PackageSetting ps = (PackageSetting) obj;
5634                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5635                    return 0;
5636                }
5637                return ps.pkgPrivateFlags;
5638            }
5639        }
5640        return 0;
5641    }
5642
5643    @Override
5644    public boolean isUidPrivileged(int uid) {
5645        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5646            return false;
5647        }
5648        uid = UserHandle.getAppId(uid);
5649        // reader
5650        synchronized (mPackages) {
5651            Object obj = mSettings.getUserIdLPr(uid);
5652            if (obj instanceof SharedUserSetting) {
5653                final SharedUserSetting sus = (SharedUserSetting) obj;
5654                final Iterator<PackageSetting> it = sus.packages.iterator();
5655                while (it.hasNext()) {
5656                    if (it.next().isPrivileged()) {
5657                        return true;
5658                    }
5659                }
5660            } else if (obj instanceof PackageSetting) {
5661                final PackageSetting ps = (PackageSetting) obj;
5662                return ps.isPrivileged();
5663            }
5664        }
5665        return false;
5666    }
5667
5668    @Override
5669    public String[] getAppOpPermissionPackages(String permName) {
5670        return mPermissionManager.getAppOpPermissionPackages(permName);
5671    }
5672
5673    @Override
5674    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5675            int flags, int userId) {
5676        return resolveIntentInternal(
5677                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5678    }
5679
5680    /**
5681     * Normally instant apps can only be resolved when they're visible to the caller.
5682     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5683     * since we need to allow the system to start any installed application.
5684     */
5685    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5686            int flags, int userId, boolean resolveForStart) {
5687        try {
5688            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5689
5690            if (!sUserManager.exists(userId)) return null;
5691            final int callingUid = Binder.getCallingUid();
5692            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5693            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5694                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5695
5696            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5697            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5698                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5699            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5700
5701            final ResolveInfo bestChoice =
5702                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5703            return bestChoice;
5704        } finally {
5705            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5706        }
5707    }
5708
5709    @Override
5710    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5711        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5712            throw new SecurityException(
5713                    "findPersistentPreferredActivity can only be run by the system");
5714        }
5715        if (!sUserManager.exists(userId)) {
5716            return null;
5717        }
5718        final int callingUid = Binder.getCallingUid();
5719        intent = updateIntentForResolve(intent);
5720        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5721        final int flags = updateFlagsForResolve(
5722                0, userId, intent, callingUid, false /*includeInstantApps*/);
5723        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5724                userId);
5725        synchronized (mPackages) {
5726            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5727                    userId);
5728        }
5729    }
5730
5731    @Override
5732    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5733            IntentFilter filter, int match, ComponentName activity) {
5734        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5735            return;
5736        }
5737        final int userId = UserHandle.getCallingUserId();
5738        if (DEBUG_PREFERRED) {
5739            Log.v(TAG, "setLastChosenActivity intent=" + intent
5740                + " resolvedType=" + resolvedType
5741                + " flags=" + flags
5742                + " filter=" + filter
5743                + " match=" + match
5744                + " activity=" + activity);
5745            filter.dump(new PrintStreamPrinter(System.out), "    ");
5746        }
5747        intent.setComponent(null);
5748        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5749                userId);
5750        // Find any earlier preferred or last chosen entries and nuke them
5751        findPreferredActivity(intent, resolvedType,
5752                flags, query, 0, false, true, false, userId);
5753        // Add the new activity as the last chosen for this filter
5754        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5755                "Setting last chosen");
5756    }
5757
5758    @Override
5759    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5760        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5761            return null;
5762        }
5763        final int userId = UserHandle.getCallingUserId();
5764        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5765        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5766                userId);
5767        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5768                false, false, false, userId);
5769    }
5770
5771    /**
5772     * Returns whether or not instant apps have been disabled remotely.
5773     */
5774    private boolean isEphemeralDisabled() {
5775        return mEphemeralAppsDisabled;
5776    }
5777
5778    private boolean isInstantAppAllowed(
5779            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5780            boolean skipPackageCheck) {
5781        if (mInstantAppResolverConnection == null) {
5782            return false;
5783        }
5784        if (mInstantAppInstallerActivity == null) {
5785            return false;
5786        }
5787        if (intent.getComponent() != null) {
5788            return false;
5789        }
5790        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5791            return false;
5792        }
5793        if (!skipPackageCheck && intent.getPackage() != null) {
5794            return false;
5795        }
5796        final boolean isWebUri = hasWebURI(intent);
5797        if (!isWebUri || intent.getData().getHost() == null) {
5798            return false;
5799        }
5800        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5801        // Or if there's already an ephemeral app installed that handles the action
5802        synchronized (mPackages) {
5803            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5804            for (int n = 0; n < count; n++) {
5805                final ResolveInfo info = resolvedActivities.get(n);
5806                final String packageName = info.activityInfo.packageName;
5807                final PackageSetting ps = mSettings.mPackages.get(packageName);
5808                if (ps != null) {
5809                    // only check domain verification status if the app is not a browser
5810                    if (!info.handleAllWebDataURI) {
5811                        // Try to get the status from User settings first
5812                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5813                        final int status = (int) (packedStatus >> 32);
5814                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5815                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5816                            if (DEBUG_EPHEMERAL) {
5817                                Slog.v(TAG, "DENY instant app;"
5818                                    + " pkg: " + packageName + ", status: " + status);
5819                            }
5820                            return false;
5821                        }
5822                    }
5823                    if (ps.getInstantApp(userId)) {
5824                        if (DEBUG_EPHEMERAL) {
5825                            Slog.v(TAG, "DENY instant app installed;"
5826                                    + " pkg: " + packageName);
5827                        }
5828                        return false;
5829                    }
5830                }
5831            }
5832        }
5833        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5834        return true;
5835    }
5836
5837    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5838            Intent origIntent, String resolvedType, String callingPackage,
5839            Bundle verificationBundle, int userId) {
5840        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5841                new InstantAppRequest(responseObj, origIntent, resolvedType,
5842                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
5843        mHandler.sendMessage(msg);
5844    }
5845
5846    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5847            int flags, List<ResolveInfo> query, int userId) {
5848        if (query != null) {
5849            final int N = query.size();
5850            if (N == 1) {
5851                return query.get(0);
5852            } else if (N > 1) {
5853                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5854                // If there is more than one activity with the same priority,
5855                // then let the user decide between them.
5856                ResolveInfo r0 = query.get(0);
5857                ResolveInfo r1 = query.get(1);
5858                if (DEBUG_INTENT_MATCHING || debug) {
5859                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5860                            + r1.activityInfo.name + "=" + r1.priority);
5861                }
5862                // If the first activity has a higher priority, or a different
5863                // default, then it is always desirable to pick it.
5864                if (r0.priority != r1.priority
5865                        || r0.preferredOrder != r1.preferredOrder
5866                        || r0.isDefault != r1.isDefault) {
5867                    return query.get(0);
5868                }
5869                // If we have saved a preference for a preferred activity for
5870                // this Intent, use that.
5871                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5872                        flags, query, r0.priority, true, false, debug, userId);
5873                if (ri != null) {
5874                    return ri;
5875                }
5876                // If we have an ephemeral app, use it
5877                for (int i = 0; i < N; i++) {
5878                    ri = query.get(i);
5879                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5880                        final String packageName = ri.activityInfo.packageName;
5881                        final PackageSetting ps = mSettings.mPackages.get(packageName);
5882                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5883                        final int status = (int)(packedStatus >> 32);
5884                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5885                            return ri;
5886                        }
5887                    }
5888                }
5889                ri = new ResolveInfo(mResolveInfo);
5890                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5891                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5892                // If all of the options come from the same package, show the application's
5893                // label and icon instead of the generic resolver's.
5894                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5895                // and then throw away the ResolveInfo itself, meaning that the caller loses
5896                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5897                // a fallback for this case; we only set the target package's resources on
5898                // the ResolveInfo, not the ActivityInfo.
5899                final String intentPackage = intent.getPackage();
5900                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5901                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5902                    ri.resolvePackageName = intentPackage;
5903                    if (userNeedsBadging(userId)) {
5904                        ri.noResourceId = true;
5905                    } else {
5906                        ri.icon = appi.icon;
5907                    }
5908                    ri.iconResourceId = appi.icon;
5909                    ri.labelRes = appi.labelRes;
5910                }
5911                ri.activityInfo.applicationInfo = new ApplicationInfo(
5912                        ri.activityInfo.applicationInfo);
5913                if (userId != 0) {
5914                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5915                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5916                }
5917                // Make sure that the resolver is displayable in car mode
5918                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5919                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5920                return ri;
5921            }
5922        }
5923        return null;
5924    }
5925
5926    /**
5927     * Return true if the given list is not empty and all of its contents have
5928     * an activityInfo with the given package name.
5929     */
5930    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5931        if (ArrayUtils.isEmpty(list)) {
5932            return false;
5933        }
5934        for (int i = 0, N = list.size(); i < N; i++) {
5935            final ResolveInfo ri = list.get(i);
5936            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5937            if (ai == null || !packageName.equals(ai.packageName)) {
5938                return false;
5939            }
5940        }
5941        return true;
5942    }
5943
5944    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5945            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5946        final int N = query.size();
5947        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5948                .get(userId);
5949        // Get the list of persistent preferred activities that handle the intent
5950        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5951        List<PersistentPreferredActivity> pprefs = ppir != null
5952                ? ppir.queryIntent(intent, resolvedType,
5953                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5954                        userId)
5955                : null;
5956        if (pprefs != null && pprefs.size() > 0) {
5957            final int M = pprefs.size();
5958            for (int i=0; i<M; i++) {
5959                final PersistentPreferredActivity ppa = pprefs.get(i);
5960                if (DEBUG_PREFERRED || debug) {
5961                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5962                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5963                            + "\n  component=" + ppa.mComponent);
5964                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5965                }
5966                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5967                        flags | MATCH_DISABLED_COMPONENTS, userId);
5968                if (DEBUG_PREFERRED || debug) {
5969                    Slog.v(TAG, "Found persistent preferred activity:");
5970                    if (ai != null) {
5971                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5972                    } else {
5973                        Slog.v(TAG, "  null");
5974                    }
5975                }
5976                if (ai == null) {
5977                    // This previously registered persistent preferred activity
5978                    // component is no longer known. Ignore it and do NOT remove it.
5979                    continue;
5980                }
5981                for (int j=0; j<N; j++) {
5982                    final ResolveInfo ri = query.get(j);
5983                    if (!ri.activityInfo.applicationInfo.packageName
5984                            .equals(ai.applicationInfo.packageName)) {
5985                        continue;
5986                    }
5987                    if (!ri.activityInfo.name.equals(ai.name)) {
5988                        continue;
5989                    }
5990                    //  Found a persistent preference that can handle the intent.
5991                    if (DEBUG_PREFERRED || debug) {
5992                        Slog.v(TAG, "Returning persistent preferred activity: " +
5993                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5994                    }
5995                    return ri;
5996                }
5997            }
5998        }
5999        return null;
6000    }
6001
6002    // TODO: handle preferred activities missing while user has amnesia
6003    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6004            List<ResolveInfo> query, int priority, boolean always,
6005            boolean removeMatches, boolean debug, int userId) {
6006        if (!sUserManager.exists(userId)) return null;
6007        final int callingUid = Binder.getCallingUid();
6008        flags = updateFlagsForResolve(
6009                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6010        intent = updateIntentForResolve(intent);
6011        // writer
6012        synchronized (mPackages) {
6013            // Try to find a matching persistent preferred activity.
6014            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6015                    debug, userId);
6016
6017            // If a persistent preferred activity matched, use it.
6018            if (pri != null) {
6019                return pri;
6020            }
6021
6022            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6023            // Get the list of preferred activities that handle the intent
6024            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6025            List<PreferredActivity> prefs = pir != null
6026                    ? pir.queryIntent(intent, resolvedType,
6027                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6028                            userId)
6029                    : null;
6030            if (prefs != null && prefs.size() > 0) {
6031                boolean changed = false;
6032                try {
6033                    // First figure out how good the original match set is.
6034                    // We will only allow preferred activities that came
6035                    // from the same match quality.
6036                    int match = 0;
6037
6038                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6039
6040                    final int N = query.size();
6041                    for (int j=0; j<N; j++) {
6042                        final ResolveInfo ri = query.get(j);
6043                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6044                                + ": 0x" + Integer.toHexString(match));
6045                        if (ri.match > match) {
6046                            match = ri.match;
6047                        }
6048                    }
6049
6050                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6051                            + Integer.toHexString(match));
6052
6053                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6054                    final int M = prefs.size();
6055                    for (int i=0; i<M; i++) {
6056                        final PreferredActivity pa = prefs.get(i);
6057                        if (DEBUG_PREFERRED || debug) {
6058                            Slog.v(TAG, "Checking PreferredActivity ds="
6059                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6060                                    + "\n  component=" + pa.mPref.mComponent);
6061                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6062                        }
6063                        if (pa.mPref.mMatch != match) {
6064                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6065                                    + Integer.toHexString(pa.mPref.mMatch));
6066                            continue;
6067                        }
6068                        // If it's not an "always" type preferred activity and that's what we're
6069                        // looking for, skip it.
6070                        if (always && !pa.mPref.mAlways) {
6071                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6072                            continue;
6073                        }
6074                        final ActivityInfo ai = getActivityInfo(
6075                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6076                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6077                                userId);
6078                        if (DEBUG_PREFERRED || debug) {
6079                            Slog.v(TAG, "Found preferred activity:");
6080                            if (ai != null) {
6081                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6082                            } else {
6083                                Slog.v(TAG, "  null");
6084                            }
6085                        }
6086                        if (ai == null) {
6087                            // This previously registered preferred activity
6088                            // component is no longer known.  Most likely an update
6089                            // to the app was installed and in the new version this
6090                            // component no longer exists.  Clean it up by removing
6091                            // it from the preferred activities list, and skip it.
6092                            Slog.w(TAG, "Removing dangling preferred activity: "
6093                                    + pa.mPref.mComponent);
6094                            pir.removeFilter(pa);
6095                            changed = true;
6096                            continue;
6097                        }
6098                        for (int j=0; j<N; j++) {
6099                            final ResolveInfo ri = query.get(j);
6100                            if (!ri.activityInfo.applicationInfo.packageName
6101                                    .equals(ai.applicationInfo.packageName)) {
6102                                continue;
6103                            }
6104                            if (!ri.activityInfo.name.equals(ai.name)) {
6105                                continue;
6106                            }
6107
6108                            if (removeMatches) {
6109                                pir.removeFilter(pa);
6110                                changed = true;
6111                                if (DEBUG_PREFERRED) {
6112                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6113                                }
6114                                break;
6115                            }
6116
6117                            // Okay we found a previously set preferred or last chosen app.
6118                            // If the result set is different from when this
6119                            // was created, and is not a subset of the preferred set, we need to
6120                            // clear it and re-ask the user their preference, if we're looking for
6121                            // an "always" type entry.
6122                            if (always && !pa.mPref.sameSet(query)) {
6123                                if (pa.mPref.isSuperset(query)) {
6124                                    // some components of the set are no longer present in
6125                                    // the query, but the preferred activity can still be reused
6126                                    if (DEBUG_PREFERRED) {
6127                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6128                                                + " still valid as only non-preferred components"
6129                                                + " were removed for " + intent + " type "
6130                                                + resolvedType);
6131                                    }
6132                                    // remove obsolete components and re-add the up-to-date filter
6133                                    PreferredActivity freshPa = new PreferredActivity(pa,
6134                                            pa.mPref.mMatch,
6135                                            pa.mPref.discardObsoleteComponents(query),
6136                                            pa.mPref.mComponent,
6137                                            pa.mPref.mAlways);
6138                                    pir.removeFilter(pa);
6139                                    pir.addFilter(freshPa);
6140                                    changed = true;
6141                                } else {
6142                                    Slog.i(TAG,
6143                                            "Result set changed, dropping preferred activity for "
6144                                                    + intent + " type " + resolvedType);
6145                                    if (DEBUG_PREFERRED) {
6146                                        Slog.v(TAG, "Removing preferred activity since set changed "
6147                                                + pa.mPref.mComponent);
6148                                    }
6149                                    pir.removeFilter(pa);
6150                                    // Re-add the filter as a "last chosen" entry (!always)
6151                                    PreferredActivity lastChosen = new PreferredActivity(
6152                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6153                                    pir.addFilter(lastChosen);
6154                                    changed = true;
6155                                    return null;
6156                                }
6157                            }
6158
6159                            // Yay! Either the set matched or we're looking for the last chosen
6160                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6161                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6162                            return ri;
6163                        }
6164                    }
6165                } finally {
6166                    if (changed) {
6167                        if (DEBUG_PREFERRED) {
6168                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6169                        }
6170                        scheduleWritePackageRestrictionsLocked(userId);
6171                    }
6172                }
6173            }
6174        }
6175        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6176        return null;
6177    }
6178
6179    /*
6180     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6181     */
6182    @Override
6183    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6184            int targetUserId) {
6185        mContext.enforceCallingOrSelfPermission(
6186                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6187        List<CrossProfileIntentFilter> matches =
6188                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6189        if (matches != null) {
6190            int size = matches.size();
6191            for (int i = 0; i < size; i++) {
6192                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6193            }
6194        }
6195        if (hasWebURI(intent)) {
6196            // cross-profile app linking works only towards the parent.
6197            final int callingUid = Binder.getCallingUid();
6198            final UserInfo parent = getProfileParent(sourceUserId);
6199            synchronized(mPackages) {
6200                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6201                        false /*includeInstantApps*/);
6202                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6203                        intent, resolvedType, flags, sourceUserId, parent.id);
6204                return xpDomainInfo != null;
6205            }
6206        }
6207        return false;
6208    }
6209
6210    private UserInfo getProfileParent(int userId) {
6211        final long identity = Binder.clearCallingIdentity();
6212        try {
6213            return sUserManager.getProfileParent(userId);
6214        } finally {
6215            Binder.restoreCallingIdentity(identity);
6216        }
6217    }
6218
6219    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6220            String resolvedType, int userId) {
6221        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6222        if (resolver != null) {
6223            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6224        }
6225        return null;
6226    }
6227
6228    @Override
6229    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6230            String resolvedType, int flags, int userId) {
6231        try {
6232            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6233
6234            return new ParceledListSlice<>(
6235                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6236        } finally {
6237            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6238        }
6239    }
6240
6241    /**
6242     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6243     * instant, returns {@code null}.
6244     */
6245    private String getInstantAppPackageName(int callingUid) {
6246        synchronized (mPackages) {
6247            // If the caller is an isolated app use the owner's uid for the lookup.
6248            if (Process.isIsolated(callingUid)) {
6249                callingUid = mIsolatedOwners.get(callingUid);
6250            }
6251            final int appId = UserHandle.getAppId(callingUid);
6252            final Object obj = mSettings.getUserIdLPr(appId);
6253            if (obj instanceof PackageSetting) {
6254                final PackageSetting ps = (PackageSetting) obj;
6255                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6256                return isInstantApp ? ps.pkg.packageName : null;
6257            }
6258        }
6259        return null;
6260    }
6261
6262    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6263            String resolvedType, int flags, int userId) {
6264        return queryIntentActivitiesInternal(
6265                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6266                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6267    }
6268
6269    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6270            String resolvedType, int flags, int filterCallingUid, int userId,
6271            boolean resolveForStart, boolean allowDynamicSplits) {
6272        if (!sUserManager.exists(userId)) return Collections.emptyList();
6273        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6274        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6275                false /* requireFullPermission */, false /* checkShell */,
6276                "query intent activities");
6277        final String pkgName = intent.getPackage();
6278        ComponentName comp = intent.getComponent();
6279        if (comp == null) {
6280            if (intent.getSelector() != null) {
6281                intent = intent.getSelector();
6282                comp = intent.getComponent();
6283            }
6284        }
6285
6286        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6287                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6288        if (comp != null) {
6289            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6290            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6291            if (ai != null) {
6292                // When specifying an explicit component, we prevent the activity from being
6293                // used when either 1) the calling package is normal and the activity is within
6294                // an ephemeral application or 2) the calling package is ephemeral and the
6295                // activity is not visible to ephemeral applications.
6296                final boolean matchInstantApp =
6297                        (flags & PackageManager.MATCH_INSTANT) != 0;
6298                final boolean matchVisibleToInstantAppOnly =
6299                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6300                final boolean matchExplicitlyVisibleOnly =
6301                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6302                final boolean isCallerInstantApp =
6303                        instantAppPkgName != null;
6304                final boolean isTargetSameInstantApp =
6305                        comp.getPackageName().equals(instantAppPkgName);
6306                final boolean isTargetInstantApp =
6307                        (ai.applicationInfo.privateFlags
6308                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6309                final boolean isTargetVisibleToInstantApp =
6310                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6311                final boolean isTargetExplicitlyVisibleToInstantApp =
6312                        isTargetVisibleToInstantApp
6313                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6314                final boolean isTargetHiddenFromInstantApp =
6315                        !isTargetVisibleToInstantApp
6316                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6317                final boolean blockResolution =
6318                        !isTargetSameInstantApp
6319                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6320                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6321                                        && isTargetHiddenFromInstantApp));
6322                if (!blockResolution) {
6323                    final ResolveInfo ri = new ResolveInfo();
6324                    ri.activityInfo = ai;
6325                    list.add(ri);
6326                }
6327            }
6328            return applyPostResolutionFilter(
6329                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6330        }
6331
6332        // reader
6333        boolean sortResult = false;
6334        boolean addEphemeral = false;
6335        List<ResolveInfo> result;
6336        final boolean ephemeralDisabled = isEphemeralDisabled();
6337        synchronized (mPackages) {
6338            if (pkgName == null) {
6339                List<CrossProfileIntentFilter> matchingFilters =
6340                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6341                // Check for results that need to skip the current profile.
6342                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6343                        resolvedType, flags, userId);
6344                if (xpResolveInfo != null) {
6345                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6346                    xpResult.add(xpResolveInfo);
6347                    return applyPostResolutionFilter(
6348                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6349                            allowDynamicSplits, filterCallingUid, userId);
6350                }
6351
6352                // Check for results in the current profile.
6353                result = filterIfNotSystemUser(mActivities.queryIntent(
6354                        intent, resolvedType, flags, userId), userId);
6355                addEphemeral = !ephemeralDisabled
6356                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6357                // Check for cross profile results.
6358                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6359                xpResolveInfo = queryCrossProfileIntents(
6360                        matchingFilters, intent, resolvedType, flags, userId,
6361                        hasNonNegativePriorityResult);
6362                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6363                    boolean isVisibleToUser = filterIfNotSystemUser(
6364                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6365                    if (isVisibleToUser) {
6366                        result.add(xpResolveInfo);
6367                        sortResult = true;
6368                    }
6369                }
6370                if (hasWebURI(intent)) {
6371                    CrossProfileDomainInfo xpDomainInfo = null;
6372                    final UserInfo parent = getProfileParent(userId);
6373                    if (parent != null) {
6374                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6375                                flags, userId, parent.id);
6376                    }
6377                    if (xpDomainInfo != null) {
6378                        if (xpResolveInfo != null) {
6379                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6380                            // in the result.
6381                            result.remove(xpResolveInfo);
6382                        }
6383                        if (result.size() == 0 && !addEphemeral) {
6384                            // No result in current profile, but found candidate in parent user.
6385                            // And we are not going to add emphemeral app, so we can return the
6386                            // result straight away.
6387                            result.add(xpDomainInfo.resolveInfo);
6388                            return applyPostResolutionFilter(result, instantAppPkgName,
6389                                    allowDynamicSplits, filterCallingUid, userId);
6390                        }
6391                    } else if (result.size() <= 1 && !addEphemeral) {
6392                        // No result in parent user and <= 1 result in current profile, and we
6393                        // are not going to add emphemeral app, so we can return the result without
6394                        // further processing.
6395                        return applyPostResolutionFilter(result, instantAppPkgName,
6396                                allowDynamicSplits, filterCallingUid, userId);
6397                    }
6398                    // We have more than one candidate (combining results from current and parent
6399                    // profile), so we need filtering and sorting.
6400                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6401                            intent, flags, result, xpDomainInfo, userId);
6402                    sortResult = true;
6403                }
6404            } else {
6405                final PackageParser.Package pkg = mPackages.get(pkgName);
6406                result = null;
6407                if (pkg != null) {
6408                    result = filterIfNotSystemUser(
6409                            mActivities.queryIntentForPackage(
6410                                    intent, resolvedType, flags, pkg.activities, userId),
6411                            userId);
6412                }
6413                if (result == null || result.size() == 0) {
6414                    // the caller wants to resolve for a particular package; however, there
6415                    // were no installed results, so, try to find an ephemeral result
6416                    addEphemeral = !ephemeralDisabled
6417                            && isInstantAppAllowed(
6418                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6419                    if (result == null) {
6420                        result = new ArrayList<>();
6421                    }
6422                }
6423            }
6424        }
6425        if (addEphemeral) {
6426            result = maybeAddInstantAppInstaller(
6427                    result, intent, resolvedType, flags, userId, resolveForStart);
6428        }
6429        if (sortResult) {
6430            Collections.sort(result, mResolvePrioritySorter);
6431        }
6432        return applyPostResolutionFilter(
6433                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6434    }
6435
6436    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6437            String resolvedType, int flags, int userId, boolean resolveForStart) {
6438        // first, check to see if we've got an instant app already installed
6439        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6440        ResolveInfo localInstantApp = null;
6441        boolean blockResolution = false;
6442        if (!alreadyResolvedLocally) {
6443            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6444                    flags
6445                        | PackageManager.GET_RESOLVED_FILTER
6446                        | PackageManager.MATCH_INSTANT
6447                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6448                    userId);
6449            for (int i = instantApps.size() - 1; i >= 0; --i) {
6450                final ResolveInfo info = instantApps.get(i);
6451                final String packageName = info.activityInfo.packageName;
6452                final PackageSetting ps = mSettings.mPackages.get(packageName);
6453                if (ps.getInstantApp(userId)) {
6454                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6455                    final int status = (int)(packedStatus >> 32);
6456                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6457                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6458                        // there's a local instant application installed, but, the user has
6459                        // chosen to never use it; skip resolution and don't acknowledge
6460                        // an instant application is even available
6461                        if (DEBUG_EPHEMERAL) {
6462                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6463                        }
6464                        blockResolution = true;
6465                        break;
6466                    } else {
6467                        // we have a locally installed instant application; skip resolution
6468                        // but acknowledge there's an instant application available
6469                        if (DEBUG_EPHEMERAL) {
6470                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6471                        }
6472                        localInstantApp = info;
6473                        break;
6474                    }
6475                }
6476            }
6477        }
6478        // no app installed, let's see if one's available
6479        AuxiliaryResolveInfo auxiliaryResponse = null;
6480        if (!blockResolution) {
6481            if (localInstantApp == null) {
6482                // we don't have an instant app locally, resolve externally
6483                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6484                final InstantAppRequest requestObject = new InstantAppRequest(
6485                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6486                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6487                        resolveForStart);
6488                auxiliaryResponse =
6489                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6490                                mContext, mInstantAppResolverConnection, requestObject);
6491                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6492            } else {
6493                // we have an instant application locally, but, we can't admit that since
6494                // callers shouldn't be able to determine prior browsing. create a dummy
6495                // auxiliary response so the downstream code behaves as if there's an
6496                // instant application available externally. when it comes time to start
6497                // the instant application, we'll do the right thing.
6498                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6499                auxiliaryResponse = new AuxiliaryResolveInfo(
6500                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
6501                        ai.versionCode, null /*failureIntent*/);
6502            }
6503        }
6504        if (auxiliaryResponse != null) {
6505            if (DEBUG_EPHEMERAL) {
6506                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6507            }
6508            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6509            final PackageSetting ps =
6510                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6511            if (ps != null) {
6512                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6513                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6514                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6515                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6516                // make sure this resolver is the default
6517                ephemeralInstaller.isDefault = true;
6518                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6519                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6520                // add a non-generic filter
6521                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6522                ephemeralInstaller.filter.addDataPath(
6523                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6524                ephemeralInstaller.isInstantAppAvailable = true;
6525                result.add(ephemeralInstaller);
6526            }
6527        }
6528        return result;
6529    }
6530
6531    private static class CrossProfileDomainInfo {
6532        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6533        ResolveInfo resolveInfo;
6534        /* Best domain verification status of the activities found in the other profile */
6535        int bestDomainVerificationStatus;
6536    }
6537
6538    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6539            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6540        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6541                sourceUserId)) {
6542            return null;
6543        }
6544        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6545                resolvedType, flags, parentUserId);
6546
6547        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6548            return null;
6549        }
6550        CrossProfileDomainInfo result = null;
6551        int size = resultTargetUser.size();
6552        for (int i = 0; i < size; i++) {
6553            ResolveInfo riTargetUser = resultTargetUser.get(i);
6554            // Intent filter verification is only for filters that specify a host. So don't return
6555            // those that handle all web uris.
6556            if (riTargetUser.handleAllWebDataURI) {
6557                continue;
6558            }
6559            String packageName = riTargetUser.activityInfo.packageName;
6560            PackageSetting ps = mSettings.mPackages.get(packageName);
6561            if (ps == null) {
6562                continue;
6563            }
6564            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6565            int status = (int)(verificationState >> 32);
6566            if (result == null) {
6567                result = new CrossProfileDomainInfo();
6568                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6569                        sourceUserId, parentUserId);
6570                result.bestDomainVerificationStatus = status;
6571            } else {
6572                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6573                        result.bestDomainVerificationStatus);
6574            }
6575        }
6576        // Don't consider matches with status NEVER across profiles.
6577        if (result != null && result.bestDomainVerificationStatus
6578                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6579            return null;
6580        }
6581        return result;
6582    }
6583
6584    /**
6585     * Verification statuses are ordered from the worse to the best, except for
6586     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6587     */
6588    private int bestDomainVerificationStatus(int status1, int status2) {
6589        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6590            return status2;
6591        }
6592        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6593            return status1;
6594        }
6595        return (int) MathUtils.max(status1, status2);
6596    }
6597
6598    private boolean isUserEnabled(int userId) {
6599        long callingId = Binder.clearCallingIdentity();
6600        try {
6601            UserInfo userInfo = sUserManager.getUserInfo(userId);
6602            return userInfo != null && userInfo.isEnabled();
6603        } finally {
6604            Binder.restoreCallingIdentity(callingId);
6605        }
6606    }
6607
6608    /**
6609     * Filter out activities with systemUserOnly flag set, when current user is not System.
6610     *
6611     * @return filtered list
6612     */
6613    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6614        if (userId == UserHandle.USER_SYSTEM) {
6615            return resolveInfos;
6616        }
6617        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6618            ResolveInfo info = resolveInfos.get(i);
6619            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6620                resolveInfos.remove(i);
6621            }
6622        }
6623        return resolveInfos;
6624    }
6625
6626    /**
6627     * Filters out ephemeral activities.
6628     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6629     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6630     *
6631     * @param resolveInfos The pre-filtered list of resolved activities
6632     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6633     *          is performed.
6634     * @return A filtered list of resolved activities.
6635     */
6636    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6637            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
6638        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6639            final ResolveInfo info = resolveInfos.get(i);
6640            // allow activities that are defined in the provided package
6641            if (allowDynamicSplits
6642                    && info.activityInfo.splitName != null
6643                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6644                            info.activityInfo.splitName)) {
6645                if (mInstantAppInstallerInfo == null) {
6646                    if (DEBUG_INSTALL) {
6647                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6648                    }
6649                    resolveInfos.remove(i);
6650                    continue;
6651                }
6652                // requested activity is defined in a split that hasn't been installed yet.
6653                // add the installer to the resolve list
6654                if (DEBUG_INSTALL) {
6655                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6656                }
6657                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6658                final ComponentName installFailureActivity = findInstallFailureActivity(
6659                        info.activityInfo.packageName,  filterCallingUid, userId);
6660                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6661                        info.activityInfo.packageName, info.activityInfo.splitName,
6662                        installFailureActivity,
6663                        info.activityInfo.applicationInfo.versionCode,
6664                        null /*failureIntent*/);
6665                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6666                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6667                // add a non-generic filter
6668                installerInfo.filter = new IntentFilter();
6669
6670                // This resolve info may appear in the chooser UI, so let us make it
6671                // look as the one it replaces as far as the user is concerned which
6672                // requires loading the correct label and icon for the resolve info.
6673                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6674                installerInfo.labelRes = info.resolveLabelResId();
6675                installerInfo.icon = info.resolveIconResId();
6676
6677                // propagate priority/preferred order/default
6678                installerInfo.priority = info.priority;
6679                installerInfo.preferredOrder = info.preferredOrder;
6680                installerInfo.isDefault = info.isDefault;
6681                resolveInfos.set(i, installerInfo);
6682                continue;
6683            }
6684            // caller is a full app, don't need to apply any other filtering
6685            if (ephemeralPkgName == null) {
6686                continue;
6687            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6688                // caller is same app; don't need to apply any other filtering
6689                continue;
6690            }
6691            // allow activities that have been explicitly exposed to ephemeral apps
6692            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6693            if (!isEphemeralApp
6694                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6695                continue;
6696            }
6697            resolveInfos.remove(i);
6698        }
6699        return resolveInfos;
6700    }
6701
6702    /**
6703     * Returns the activity component that can handle install failures.
6704     * <p>By default, the instant application installer handles failures. However, an
6705     * application may want to handle failures on its own. Applications do this by
6706     * creating an activity with an intent filter that handles the action
6707     * {@link Intent#ACTION_INSTALL_FAILURE}.
6708     */
6709    private @Nullable ComponentName findInstallFailureActivity(
6710            String packageName, int filterCallingUid, int userId) {
6711        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6712        failureActivityIntent.setPackage(packageName);
6713        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6714        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6715                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6716                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6717        final int NR = result.size();
6718        if (NR > 0) {
6719            for (int i = 0; i < NR; i++) {
6720                final ResolveInfo info = result.get(i);
6721                if (info.activityInfo.splitName != null) {
6722                    continue;
6723                }
6724                return new ComponentName(packageName, info.activityInfo.name);
6725            }
6726        }
6727        return null;
6728    }
6729
6730    /**
6731     * @param resolveInfos list of resolve infos in descending priority order
6732     * @return if the list contains a resolve info with non-negative priority
6733     */
6734    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6735        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6736    }
6737
6738    private static boolean hasWebURI(Intent intent) {
6739        if (intent.getData() == null) {
6740            return false;
6741        }
6742        final String scheme = intent.getScheme();
6743        if (TextUtils.isEmpty(scheme)) {
6744            return false;
6745        }
6746        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6747    }
6748
6749    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6750            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6751            int userId) {
6752        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6753
6754        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6755            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6756                    candidates.size());
6757        }
6758
6759        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6760        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6761        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6762        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6763        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6764        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6765
6766        synchronized (mPackages) {
6767            final int count = candidates.size();
6768            // First, try to use linked apps. Partition the candidates into four lists:
6769            // one for the final results, one for the "do not use ever", one for "undefined status"
6770            // and finally one for "browser app type".
6771            for (int n=0; n<count; n++) {
6772                ResolveInfo info = candidates.get(n);
6773                String packageName = info.activityInfo.packageName;
6774                PackageSetting ps = mSettings.mPackages.get(packageName);
6775                if (ps != null) {
6776                    // Add to the special match all list (Browser use case)
6777                    if (info.handleAllWebDataURI) {
6778                        matchAllList.add(info);
6779                        continue;
6780                    }
6781                    // Try to get the status from User settings first
6782                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6783                    int status = (int)(packedStatus >> 32);
6784                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6785                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6786                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6787                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6788                                    + " : linkgen=" + linkGeneration);
6789                        }
6790                        // Use link-enabled generation as preferredOrder, i.e.
6791                        // prefer newly-enabled over earlier-enabled.
6792                        info.preferredOrder = linkGeneration;
6793                        alwaysList.add(info);
6794                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6795                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6796                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6797                        }
6798                        neverList.add(info);
6799                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6800                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6801                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6802                        }
6803                        alwaysAskList.add(info);
6804                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6805                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6806                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6807                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6808                        }
6809                        undefinedList.add(info);
6810                    }
6811                }
6812            }
6813
6814            // We'll want to include browser possibilities in a few cases
6815            boolean includeBrowser = false;
6816
6817            // First try to add the "always" resolution(s) for the current user, if any
6818            if (alwaysList.size() > 0) {
6819                result.addAll(alwaysList);
6820            } else {
6821                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6822                result.addAll(undefinedList);
6823                // Maybe add one for the other profile.
6824                if (xpDomainInfo != null && (
6825                        xpDomainInfo.bestDomainVerificationStatus
6826                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6827                    result.add(xpDomainInfo.resolveInfo);
6828                }
6829                includeBrowser = true;
6830            }
6831
6832            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6833            // If there were 'always' entries their preferred order has been set, so we also
6834            // back that off to make the alternatives equivalent
6835            if (alwaysAskList.size() > 0) {
6836                for (ResolveInfo i : result) {
6837                    i.preferredOrder = 0;
6838                }
6839                result.addAll(alwaysAskList);
6840                includeBrowser = true;
6841            }
6842
6843            if (includeBrowser) {
6844                // Also add browsers (all of them or only the default one)
6845                if (DEBUG_DOMAIN_VERIFICATION) {
6846                    Slog.v(TAG, "   ...including browsers in candidate set");
6847                }
6848                if ((matchFlags & MATCH_ALL) != 0) {
6849                    result.addAll(matchAllList);
6850                } else {
6851                    // Browser/generic handling case.  If there's a default browser, go straight
6852                    // to that (but only if there is no other higher-priority match).
6853                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6854                    int maxMatchPrio = 0;
6855                    ResolveInfo defaultBrowserMatch = null;
6856                    final int numCandidates = matchAllList.size();
6857                    for (int n = 0; n < numCandidates; n++) {
6858                        ResolveInfo info = matchAllList.get(n);
6859                        // track the highest overall match priority...
6860                        if (info.priority > maxMatchPrio) {
6861                            maxMatchPrio = info.priority;
6862                        }
6863                        // ...and the highest-priority default browser match
6864                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6865                            if (defaultBrowserMatch == null
6866                                    || (defaultBrowserMatch.priority < info.priority)) {
6867                                if (debug) {
6868                                    Slog.v(TAG, "Considering default browser match " + info);
6869                                }
6870                                defaultBrowserMatch = info;
6871                            }
6872                        }
6873                    }
6874                    if (defaultBrowserMatch != null
6875                            && defaultBrowserMatch.priority >= maxMatchPrio
6876                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6877                    {
6878                        if (debug) {
6879                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6880                        }
6881                        result.add(defaultBrowserMatch);
6882                    } else {
6883                        result.addAll(matchAllList);
6884                    }
6885                }
6886
6887                // If there is nothing selected, add all candidates and remove the ones that the user
6888                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6889                if (result.size() == 0) {
6890                    result.addAll(candidates);
6891                    result.removeAll(neverList);
6892                }
6893            }
6894        }
6895        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6896            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6897                    result.size());
6898            for (ResolveInfo info : result) {
6899                Slog.v(TAG, "  + " + info.activityInfo);
6900            }
6901        }
6902        return result;
6903    }
6904
6905    // Returns a packed value as a long:
6906    //
6907    // high 'int'-sized word: link status: undefined/ask/never/always.
6908    // low 'int'-sized word: relative priority among 'always' results.
6909    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6910        long result = ps.getDomainVerificationStatusForUser(userId);
6911        // if none available, get the master status
6912        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6913            if (ps.getIntentFilterVerificationInfo() != null) {
6914                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6915            }
6916        }
6917        return result;
6918    }
6919
6920    private ResolveInfo querySkipCurrentProfileIntents(
6921            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6922            int flags, int sourceUserId) {
6923        if (matchingFilters != null) {
6924            int size = matchingFilters.size();
6925            for (int i = 0; i < size; i ++) {
6926                CrossProfileIntentFilter filter = matchingFilters.get(i);
6927                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6928                    // Checking if there are activities in the target user that can handle the
6929                    // intent.
6930                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6931                            resolvedType, flags, sourceUserId);
6932                    if (resolveInfo != null) {
6933                        return resolveInfo;
6934                    }
6935                }
6936            }
6937        }
6938        return null;
6939    }
6940
6941    // Return matching ResolveInfo in target user if any.
6942    private ResolveInfo queryCrossProfileIntents(
6943            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6944            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6945        if (matchingFilters != null) {
6946            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6947            // match the same intent. For performance reasons, it is better not to
6948            // run queryIntent twice for the same userId
6949            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6950            int size = matchingFilters.size();
6951            for (int i = 0; i < size; i++) {
6952                CrossProfileIntentFilter filter = matchingFilters.get(i);
6953                int targetUserId = filter.getTargetUserId();
6954                boolean skipCurrentProfile =
6955                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6956                boolean skipCurrentProfileIfNoMatchFound =
6957                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6958                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6959                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6960                    // Checking if there are activities in the target user that can handle the
6961                    // intent.
6962                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6963                            resolvedType, flags, sourceUserId);
6964                    if (resolveInfo != null) return resolveInfo;
6965                    alreadyTriedUserIds.put(targetUserId, true);
6966                }
6967            }
6968        }
6969        return null;
6970    }
6971
6972    /**
6973     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6974     * will forward the intent to the filter's target user.
6975     * Otherwise, returns null.
6976     */
6977    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6978            String resolvedType, int flags, int sourceUserId) {
6979        int targetUserId = filter.getTargetUserId();
6980        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6981                resolvedType, flags, targetUserId);
6982        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6983            // If all the matches in the target profile are suspended, return null.
6984            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6985                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6986                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6987                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6988                            targetUserId);
6989                }
6990            }
6991        }
6992        return null;
6993    }
6994
6995    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6996            int sourceUserId, int targetUserId) {
6997        ResolveInfo forwardingResolveInfo = new ResolveInfo();
6998        long ident = Binder.clearCallingIdentity();
6999        boolean targetIsProfile;
7000        try {
7001            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7002        } finally {
7003            Binder.restoreCallingIdentity(ident);
7004        }
7005        String className;
7006        if (targetIsProfile) {
7007            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7008        } else {
7009            className = FORWARD_INTENT_TO_PARENT;
7010        }
7011        ComponentName forwardingActivityComponentName = new ComponentName(
7012                mAndroidApplication.packageName, className);
7013        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7014                sourceUserId);
7015        if (!targetIsProfile) {
7016            forwardingActivityInfo.showUserIcon = targetUserId;
7017            forwardingResolveInfo.noResourceId = true;
7018        }
7019        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7020        forwardingResolveInfo.priority = 0;
7021        forwardingResolveInfo.preferredOrder = 0;
7022        forwardingResolveInfo.match = 0;
7023        forwardingResolveInfo.isDefault = true;
7024        forwardingResolveInfo.filter = filter;
7025        forwardingResolveInfo.targetUserId = targetUserId;
7026        return forwardingResolveInfo;
7027    }
7028
7029    @Override
7030    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7031            Intent[] specifics, String[] specificTypes, Intent intent,
7032            String resolvedType, int flags, int userId) {
7033        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7034                specificTypes, intent, resolvedType, flags, userId));
7035    }
7036
7037    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7038            Intent[] specifics, String[] specificTypes, Intent intent,
7039            String resolvedType, int flags, int userId) {
7040        if (!sUserManager.exists(userId)) return Collections.emptyList();
7041        final int callingUid = Binder.getCallingUid();
7042        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7043                false /*includeInstantApps*/);
7044        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7045                false /*requireFullPermission*/, false /*checkShell*/,
7046                "query intent activity options");
7047        final String resultsAction = intent.getAction();
7048
7049        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7050                | PackageManager.GET_RESOLVED_FILTER, userId);
7051
7052        if (DEBUG_INTENT_MATCHING) {
7053            Log.v(TAG, "Query " + intent + ": " + results);
7054        }
7055
7056        int specificsPos = 0;
7057        int N;
7058
7059        // todo: note that the algorithm used here is O(N^2).  This
7060        // isn't a problem in our current environment, but if we start running
7061        // into situations where we have more than 5 or 10 matches then this
7062        // should probably be changed to something smarter...
7063
7064        // First we go through and resolve each of the specific items
7065        // that were supplied, taking care of removing any corresponding
7066        // duplicate items in the generic resolve list.
7067        if (specifics != null) {
7068            for (int i=0; i<specifics.length; i++) {
7069                final Intent sintent = specifics[i];
7070                if (sintent == null) {
7071                    continue;
7072                }
7073
7074                if (DEBUG_INTENT_MATCHING) {
7075                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7076                }
7077
7078                String action = sintent.getAction();
7079                if (resultsAction != null && resultsAction.equals(action)) {
7080                    // If this action was explicitly requested, then don't
7081                    // remove things that have it.
7082                    action = null;
7083                }
7084
7085                ResolveInfo ri = null;
7086                ActivityInfo ai = null;
7087
7088                ComponentName comp = sintent.getComponent();
7089                if (comp == null) {
7090                    ri = resolveIntent(
7091                        sintent,
7092                        specificTypes != null ? specificTypes[i] : null,
7093                            flags, userId);
7094                    if (ri == null) {
7095                        continue;
7096                    }
7097                    if (ri == mResolveInfo) {
7098                        // ACK!  Must do something better with this.
7099                    }
7100                    ai = ri.activityInfo;
7101                    comp = new ComponentName(ai.applicationInfo.packageName,
7102                            ai.name);
7103                } else {
7104                    ai = getActivityInfo(comp, flags, userId);
7105                    if (ai == null) {
7106                        continue;
7107                    }
7108                }
7109
7110                // Look for any generic query activities that are duplicates
7111                // of this specific one, and remove them from the results.
7112                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7113                N = results.size();
7114                int j;
7115                for (j=specificsPos; j<N; j++) {
7116                    ResolveInfo sri = results.get(j);
7117                    if ((sri.activityInfo.name.equals(comp.getClassName())
7118                            && sri.activityInfo.applicationInfo.packageName.equals(
7119                                    comp.getPackageName()))
7120                        || (action != null && sri.filter.matchAction(action))) {
7121                        results.remove(j);
7122                        if (DEBUG_INTENT_MATCHING) Log.v(
7123                            TAG, "Removing duplicate item from " + j
7124                            + " due to specific " + specificsPos);
7125                        if (ri == null) {
7126                            ri = sri;
7127                        }
7128                        j--;
7129                        N--;
7130                    }
7131                }
7132
7133                // Add this specific item to its proper place.
7134                if (ri == null) {
7135                    ri = new ResolveInfo();
7136                    ri.activityInfo = ai;
7137                }
7138                results.add(specificsPos, ri);
7139                ri.specificIndex = i;
7140                specificsPos++;
7141            }
7142        }
7143
7144        // Now we go through the remaining generic results and remove any
7145        // duplicate actions that are found here.
7146        N = results.size();
7147        for (int i=specificsPos; i<N-1; i++) {
7148            final ResolveInfo rii = results.get(i);
7149            if (rii.filter == null) {
7150                continue;
7151            }
7152
7153            // Iterate over all of the actions of this result's intent
7154            // filter...  typically this should be just one.
7155            final Iterator<String> it = rii.filter.actionsIterator();
7156            if (it == null) {
7157                continue;
7158            }
7159            while (it.hasNext()) {
7160                final String action = it.next();
7161                if (resultsAction != null && resultsAction.equals(action)) {
7162                    // If this action was explicitly requested, then don't
7163                    // remove things that have it.
7164                    continue;
7165                }
7166                for (int j=i+1; j<N; j++) {
7167                    final ResolveInfo rij = results.get(j);
7168                    if (rij.filter != null && rij.filter.hasAction(action)) {
7169                        results.remove(j);
7170                        if (DEBUG_INTENT_MATCHING) Log.v(
7171                            TAG, "Removing duplicate item from " + j
7172                            + " due to action " + action + " at " + i);
7173                        j--;
7174                        N--;
7175                    }
7176                }
7177            }
7178
7179            // If the caller didn't request filter information, drop it now
7180            // so we don't have to marshall/unmarshall it.
7181            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7182                rii.filter = null;
7183            }
7184        }
7185
7186        // Filter out the caller activity if so requested.
7187        if (caller != null) {
7188            N = results.size();
7189            for (int i=0; i<N; i++) {
7190                ActivityInfo ainfo = results.get(i).activityInfo;
7191                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7192                        && caller.getClassName().equals(ainfo.name)) {
7193                    results.remove(i);
7194                    break;
7195                }
7196            }
7197        }
7198
7199        // If the caller didn't request filter information,
7200        // drop them now so we don't have to
7201        // marshall/unmarshall it.
7202        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7203            N = results.size();
7204            for (int i=0; i<N; i++) {
7205                results.get(i).filter = null;
7206            }
7207        }
7208
7209        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7210        return results;
7211    }
7212
7213    @Override
7214    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7215            String resolvedType, int flags, int userId) {
7216        return new ParceledListSlice<>(
7217                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7218                        false /*allowDynamicSplits*/));
7219    }
7220
7221    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7222            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7223        if (!sUserManager.exists(userId)) return Collections.emptyList();
7224        final int callingUid = Binder.getCallingUid();
7225        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7226                false /*requireFullPermission*/, false /*checkShell*/,
7227                "query intent receivers");
7228        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7229        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7230                false /*includeInstantApps*/);
7231        ComponentName comp = intent.getComponent();
7232        if (comp == null) {
7233            if (intent.getSelector() != null) {
7234                intent = intent.getSelector();
7235                comp = intent.getComponent();
7236            }
7237        }
7238        if (comp != null) {
7239            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7240            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7241            if (ai != null) {
7242                // When specifying an explicit component, we prevent the activity from being
7243                // used when either 1) the calling package is normal and the activity is within
7244                // an instant application or 2) the calling package is ephemeral and the
7245                // activity is not visible to instant applications.
7246                final boolean matchInstantApp =
7247                        (flags & PackageManager.MATCH_INSTANT) != 0;
7248                final boolean matchVisibleToInstantAppOnly =
7249                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7250                final boolean matchExplicitlyVisibleOnly =
7251                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7252                final boolean isCallerInstantApp =
7253                        instantAppPkgName != null;
7254                final boolean isTargetSameInstantApp =
7255                        comp.getPackageName().equals(instantAppPkgName);
7256                final boolean isTargetInstantApp =
7257                        (ai.applicationInfo.privateFlags
7258                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7259                final boolean isTargetVisibleToInstantApp =
7260                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7261                final boolean isTargetExplicitlyVisibleToInstantApp =
7262                        isTargetVisibleToInstantApp
7263                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7264                final boolean isTargetHiddenFromInstantApp =
7265                        !isTargetVisibleToInstantApp
7266                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7267                final boolean blockResolution =
7268                        !isTargetSameInstantApp
7269                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7270                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7271                                        && isTargetHiddenFromInstantApp));
7272                if (!blockResolution) {
7273                    ResolveInfo ri = new ResolveInfo();
7274                    ri.activityInfo = ai;
7275                    list.add(ri);
7276                }
7277            }
7278            return applyPostResolutionFilter(
7279                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7280        }
7281
7282        // reader
7283        synchronized (mPackages) {
7284            String pkgName = intent.getPackage();
7285            if (pkgName == null) {
7286                final List<ResolveInfo> result =
7287                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7288                return applyPostResolutionFilter(
7289                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7290            }
7291            final PackageParser.Package pkg = mPackages.get(pkgName);
7292            if (pkg != null) {
7293                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7294                        intent, resolvedType, flags, pkg.receivers, userId);
7295                return applyPostResolutionFilter(
7296                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7297            }
7298            return Collections.emptyList();
7299        }
7300    }
7301
7302    @Override
7303    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7304        final int callingUid = Binder.getCallingUid();
7305        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7306    }
7307
7308    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7309            int userId, int callingUid) {
7310        if (!sUserManager.exists(userId)) return null;
7311        flags = updateFlagsForResolve(
7312                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7313        List<ResolveInfo> query = queryIntentServicesInternal(
7314                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7315        if (query != null) {
7316            if (query.size() >= 1) {
7317                // If there is more than one service with the same priority,
7318                // just arbitrarily pick the first one.
7319                return query.get(0);
7320            }
7321        }
7322        return null;
7323    }
7324
7325    @Override
7326    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7327            String resolvedType, int flags, int userId) {
7328        final int callingUid = Binder.getCallingUid();
7329        return new ParceledListSlice<>(queryIntentServicesInternal(
7330                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7331    }
7332
7333    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7334            String resolvedType, int flags, int userId, int callingUid,
7335            boolean includeInstantApps) {
7336        if (!sUserManager.exists(userId)) return Collections.emptyList();
7337        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7338                false /*requireFullPermission*/, false /*checkShell*/,
7339                "query intent receivers");
7340        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7341        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7342        ComponentName comp = intent.getComponent();
7343        if (comp == null) {
7344            if (intent.getSelector() != null) {
7345                intent = intent.getSelector();
7346                comp = intent.getComponent();
7347            }
7348        }
7349        if (comp != null) {
7350            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7351            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7352            if (si != null) {
7353                // When specifying an explicit component, we prevent the service from being
7354                // used when either 1) the service is in an instant application and the
7355                // caller is not the same instant application or 2) the calling package is
7356                // ephemeral and the activity is not visible to ephemeral applications.
7357                final boolean matchInstantApp =
7358                        (flags & PackageManager.MATCH_INSTANT) != 0;
7359                final boolean matchVisibleToInstantAppOnly =
7360                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7361                final boolean isCallerInstantApp =
7362                        instantAppPkgName != null;
7363                final boolean isTargetSameInstantApp =
7364                        comp.getPackageName().equals(instantAppPkgName);
7365                final boolean isTargetInstantApp =
7366                        (si.applicationInfo.privateFlags
7367                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7368                final boolean isTargetHiddenFromInstantApp =
7369                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7370                final boolean blockResolution =
7371                        !isTargetSameInstantApp
7372                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7373                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7374                                        && isTargetHiddenFromInstantApp));
7375                if (!blockResolution) {
7376                    final ResolveInfo ri = new ResolveInfo();
7377                    ri.serviceInfo = si;
7378                    list.add(ri);
7379                }
7380            }
7381            return list;
7382        }
7383
7384        // reader
7385        synchronized (mPackages) {
7386            String pkgName = intent.getPackage();
7387            if (pkgName == null) {
7388                return applyPostServiceResolutionFilter(
7389                        mServices.queryIntent(intent, resolvedType, flags, userId),
7390                        instantAppPkgName);
7391            }
7392            final PackageParser.Package pkg = mPackages.get(pkgName);
7393            if (pkg != null) {
7394                return applyPostServiceResolutionFilter(
7395                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7396                                userId),
7397                        instantAppPkgName);
7398            }
7399            return Collections.emptyList();
7400        }
7401    }
7402
7403    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7404            String instantAppPkgName) {
7405        if (instantAppPkgName == null) {
7406            return resolveInfos;
7407        }
7408        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7409            final ResolveInfo info = resolveInfos.get(i);
7410            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7411            // allow services that are defined in the provided package
7412            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7413                if (info.serviceInfo.splitName != null
7414                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7415                                info.serviceInfo.splitName)) {
7416                    // requested service is defined in a split that hasn't been installed yet.
7417                    // add the installer to the resolve list
7418                    if (DEBUG_EPHEMERAL) {
7419                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7420                    }
7421                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7422                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7423                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7424                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
7425                            null /*failureIntent*/);
7426                    // make sure this resolver is the default
7427                    installerInfo.isDefault = true;
7428                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7429                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7430                    // add a non-generic filter
7431                    installerInfo.filter = new IntentFilter();
7432                    // load resources from the correct package
7433                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7434                    resolveInfos.set(i, installerInfo);
7435                }
7436                continue;
7437            }
7438            // allow services that have been explicitly exposed to ephemeral apps
7439            if (!isEphemeralApp
7440                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7441                continue;
7442            }
7443            resolveInfos.remove(i);
7444        }
7445        return resolveInfos;
7446    }
7447
7448    @Override
7449    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7450            String resolvedType, int flags, int userId) {
7451        return new ParceledListSlice<>(
7452                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7453    }
7454
7455    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7456            Intent intent, String resolvedType, int flags, int userId) {
7457        if (!sUserManager.exists(userId)) return Collections.emptyList();
7458        final int callingUid = Binder.getCallingUid();
7459        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7460        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7461                false /*includeInstantApps*/);
7462        ComponentName comp = intent.getComponent();
7463        if (comp == null) {
7464            if (intent.getSelector() != null) {
7465                intent = intent.getSelector();
7466                comp = intent.getComponent();
7467            }
7468        }
7469        if (comp != null) {
7470            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7471            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7472            if (pi != null) {
7473                // When specifying an explicit component, we prevent the provider from being
7474                // used when either 1) the provider is in an instant application and the
7475                // caller is not the same instant application or 2) the calling package is an
7476                // instant application and the provider is not visible to instant applications.
7477                final boolean matchInstantApp =
7478                        (flags & PackageManager.MATCH_INSTANT) != 0;
7479                final boolean matchVisibleToInstantAppOnly =
7480                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7481                final boolean isCallerInstantApp =
7482                        instantAppPkgName != null;
7483                final boolean isTargetSameInstantApp =
7484                        comp.getPackageName().equals(instantAppPkgName);
7485                final boolean isTargetInstantApp =
7486                        (pi.applicationInfo.privateFlags
7487                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7488                final boolean isTargetHiddenFromInstantApp =
7489                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7490                final boolean blockResolution =
7491                        !isTargetSameInstantApp
7492                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7493                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7494                                        && isTargetHiddenFromInstantApp));
7495                if (!blockResolution) {
7496                    final ResolveInfo ri = new ResolveInfo();
7497                    ri.providerInfo = pi;
7498                    list.add(ri);
7499                }
7500            }
7501            return list;
7502        }
7503
7504        // reader
7505        synchronized (mPackages) {
7506            String pkgName = intent.getPackage();
7507            if (pkgName == null) {
7508                return applyPostContentProviderResolutionFilter(
7509                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7510                        instantAppPkgName);
7511            }
7512            final PackageParser.Package pkg = mPackages.get(pkgName);
7513            if (pkg != null) {
7514                return applyPostContentProviderResolutionFilter(
7515                        mProviders.queryIntentForPackage(
7516                        intent, resolvedType, flags, pkg.providers, userId),
7517                        instantAppPkgName);
7518            }
7519            return Collections.emptyList();
7520        }
7521    }
7522
7523    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7524            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7525        if (instantAppPkgName == null) {
7526            return resolveInfos;
7527        }
7528        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7529            final ResolveInfo info = resolveInfos.get(i);
7530            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7531            // allow providers that are defined in the provided package
7532            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7533                if (info.providerInfo.splitName != null
7534                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7535                                info.providerInfo.splitName)) {
7536                    // requested provider is defined in a split that hasn't been installed yet.
7537                    // add the installer to the resolve list
7538                    if (DEBUG_EPHEMERAL) {
7539                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7540                    }
7541                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7542                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7543                            info.providerInfo.packageName, info.providerInfo.splitName,
7544                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
7545                            null /*failureIntent*/);
7546                    // make sure this resolver is the default
7547                    installerInfo.isDefault = true;
7548                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7549                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7550                    // add a non-generic filter
7551                    installerInfo.filter = new IntentFilter();
7552                    // load resources from the correct package
7553                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7554                    resolveInfos.set(i, installerInfo);
7555                }
7556                continue;
7557            }
7558            // allow providers that have been explicitly exposed to instant applications
7559            if (!isEphemeralApp
7560                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7561                continue;
7562            }
7563            resolveInfos.remove(i);
7564        }
7565        return resolveInfos;
7566    }
7567
7568    @Override
7569    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7570        final int callingUid = Binder.getCallingUid();
7571        if (getInstantAppPackageName(callingUid) != null) {
7572            return ParceledListSlice.emptyList();
7573        }
7574        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7575        flags = updateFlagsForPackage(flags, userId, null);
7576        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7577        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7578                true /* requireFullPermission */, false /* checkShell */,
7579                "get installed packages");
7580
7581        // writer
7582        synchronized (mPackages) {
7583            ArrayList<PackageInfo> list;
7584            if (listUninstalled) {
7585                list = new ArrayList<>(mSettings.mPackages.size());
7586                for (PackageSetting ps : mSettings.mPackages.values()) {
7587                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7588                        continue;
7589                    }
7590                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7591                        continue;
7592                    }
7593                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7594                    if (pi != null) {
7595                        list.add(pi);
7596                    }
7597                }
7598            } else {
7599                list = new ArrayList<>(mPackages.size());
7600                for (PackageParser.Package p : mPackages.values()) {
7601                    final PackageSetting ps = (PackageSetting) p.mExtras;
7602                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7603                        continue;
7604                    }
7605                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7606                        continue;
7607                    }
7608                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7609                            p.mExtras, flags, userId);
7610                    if (pi != null) {
7611                        list.add(pi);
7612                    }
7613                }
7614            }
7615
7616            return new ParceledListSlice<>(list);
7617        }
7618    }
7619
7620    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7621            String[] permissions, boolean[] tmp, int flags, int userId) {
7622        int numMatch = 0;
7623        final PermissionsState permissionsState = ps.getPermissionsState();
7624        for (int i=0; i<permissions.length; i++) {
7625            final String permission = permissions[i];
7626            if (permissionsState.hasPermission(permission, userId)) {
7627                tmp[i] = true;
7628                numMatch++;
7629            } else {
7630                tmp[i] = false;
7631            }
7632        }
7633        if (numMatch == 0) {
7634            return;
7635        }
7636        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7637
7638        // The above might return null in cases of uninstalled apps or install-state
7639        // skew across users/profiles.
7640        if (pi != null) {
7641            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7642                if (numMatch == permissions.length) {
7643                    pi.requestedPermissions = permissions;
7644                } else {
7645                    pi.requestedPermissions = new String[numMatch];
7646                    numMatch = 0;
7647                    for (int i=0; i<permissions.length; i++) {
7648                        if (tmp[i]) {
7649                            pi.requestedPermissions[numMatch] = permissions[i];
7650                            numMatch++;
7651                        }
7652                    }
7653                }
7654            }
7655            list.add(pi);
7656        }
7657    }
7658
7659    @Override
7660    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7661            String[] permissions, int flags, int userId) {
7662        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7663        flags = updateFlagsForPackage(flags, userId, permissions);
7664        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7665                true /* requireFullPermission */, false /* checkShell */,
7666                "get packages holding permissions");
7667        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7668
7669        // writer
7670        synchronized (mPackages) {
7671            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7672            boolean[] tmpBools = new boolean[permissions.length];
7673            if (listUninstalled) {
7674                for (PackageSetting ps : mSettings.mPackages.values()) {
7675                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7676                            userId);
7677                }
7678            } else {
7679                for (PackageParser.Package pkg : mPackages.values()) {
7680                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7681                    if (ps != null) {
7682                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7683                                userId);
7684                    }
7685                }
7686            }
7687
7688            return new ParceledListSlice<PackageInfo>(list);
7689        }
7690    }
7691
7692    @Override
7693    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7694        final int callingUid = Binder.getCallingUid();
7695        if (getInstantAppPackageName(callingUid) != null) {
7696            return ParceledListSlice.emptyList();
7697        }
7698        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7699        flags = updateFlagsForApplication(flags, userId, null);
7700        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7701
7702        // writer
7703        synchronized (mPackages) {
7704            ArrayList<ApplicationInfo> list;
7705            if (listUninstalled) {
7706                list = new ArrayList<>(mSettings.mPackages.size());
7707                for (PackageSetting ps : mSettings.mPackages.values()) {
7708                    ApplicationInfo ai;
7709                    int effectiveFlags = flags;
7710                    if (ps.isSystem()) {
7711                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7712                    }
7713                    if (ps.pkg != null) {
7714                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7715                            continue;
7716                        }
7717                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7718                            continue;
7719                        }
7720                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7721                                ps.readUserState(userId), userId);
7722                        if (ai != null) {
7723                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7724                        }
7725                    } else {
7726                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7727                        // and already converts to externally visible package name
7728                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7729                                callingUid, effectiveFlags, userId);
7730                    }
7731                    if (ai != null) {
7732                        list.add(ai);
7733                    }
7734                }
7735            } else {
7736                list = new ArrayList<>(mPackages.size());
7737                for (PackageParser.Package p : mPackages.values()) {
7738                    if (p.mExtras != null) {
7739                        PackageSetting ps = (PackageSetting) p.mExtras;
7740                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7741                            continue;
7742                        }
7743                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7744                            continue;
7745                        }
7746                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7747                                ps.readUserState(userId), userId);
7748                        if (ai != null) {
7749                            ai.packageName = resolveExternalPackageNameLPr(p);
7750                            list.add(ai);
7751                        }
7752                    }
7753                }
7754            }
7755
7756            return new ParceledListSlice<>(list);
7757        }
7758    }
7759
7760    @Override
7761    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7762        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7763            return null;
7764        }
7765        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7766            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7767                    "getEphemeralApplications");
7768        }
7769        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7770                true /* requireFullPermission */, false /* checkShell */,
7771                "getEphemeralApplications");
7772        synchronized (mPackages) {
7773            List<InstantAppInfo> instantApps = mInstantAppRegistry
7774                    .getInstantAppsLPr(userId);
7775            if (instantApps != null) {
7776                return new ParceledListSlice<>(instantApps);
7777            }
7778        }
7779        return null;
7780    }
7781
7782    @Override
7783    public boolean isInstantApp(String packageName, int userId) {
7784        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7785                true /* requireFullPermission */, false /* checkShell */,
7786                "isInstantApp");
7787        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7788            return false;
7789        }
7790
7791        synchronized (mPackages) {
7792            int callingUid = Binder.getCallingUid();
7793            if (Process.isIsolated(callingUid)) {
7794                callingUid = mIsolatedOwners.get(callingUid);
7795            }
7796            final PackageSetting ps = mSettings.mPackages.get(packageName);
7797            PackageParser.Package pkg = mPackages.get(packageName);
7798            final boolean returnAllowed =
7799                    ps != null
7800                    && (isCallerSameApp(packageName, callingUid)
7801                            || canViewInstantApps(callingUid, userId)
7802                            || mInstantAppRegistry.isInstantAccessGranted(
7803                                    userId, UserHandle.getAppId(callingUid), ps.appId));
7804            if (returnAllowed) {
7805                return ps.getInstantApp(userId);
7806            }
7807        }
7808        return false;
7809    }
7810
7811    @Override
7812    public byte[] getInstantAppCookie(String packageName, int userId) {
7813        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7814            return null;
7815        }
7816
7817        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7818                true /* requireFullPermission */, false /* checkShell */,
7819                "getInstantAppCookie");
7820        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7821            return null;
7822        }
7823        synchronized (mPackages) {
7824            return mInstantAppRegistry.getInstantAppCookieLPw(
7825                    packageName, userId);
7826        }
7827    }
7828
7829    @Override
7830    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7831        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7832            return true;
7833        }
7834
7835        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7836                true /* requireFullPermission */, true /* checkShell */,
7837                "setInstantAppCookie");
7838        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7839            return false;
7840        }
7841        synchronized (mPackages) {
7842            return mInstantAppRegistry.setInstantAppCookieLPw(
7843                    packageName, cookie, userId);
7844        }
7845    }
7846
7847    @Override
7848    public Bitmap getInstantAppIcon(String packageName, int userId) {
7849        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7850            return null;
7851        }
7852
7853        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7854            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7855                    "getInstantAppIcon");
7856        }
7857        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7858                true /* requireFullPermission */, false /* checkShell */,
7859                "getInstantAppIcon");
7860
7861        synchronized (mPackages) {
7862            return mInstantAppRegistry.getInstantAppIconLPw(
7863                    packageName, userId);
7864        }
7865    }
7866
7867    private boolean isCallerSameApp(String packageName, int uid) {
7868        PackageParser.Package pkg = mPackages.get(packageName);
7869        return pkg != null
7870                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7871    }
7872
7873    @Override
7874    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7875        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7876            return ParceledListSlice.emptyList();
7877        }
7878        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7879    }
7880
7881    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7882        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7883
7884        // reader
7885        synchronized (mPackages) {
7886            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7887            final int userId = UserHandle.getCallingUserId();
7888            while (i.hasNext()) {
7889                final PackageParser.Package p = i.next();
7890                if (p.applicationInfo == null) continue;
7891
7892                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7893                        && !p.applicationInfo.isDirectBootAware();
7894                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7895                        && p.applicationInfo.isDirectBootAware();
7896
7897                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7898                        && (!mSafeMode || isSystemApp(p))
7899                        && (matchesUnaware || matchesAware)) {
7900                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7901                    if (ps != null) {
7902                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7903                                ps.readUserState(userId), userId);
7904                        if (ai != null) {
7905                            finalList.add(ai);
7906                        }
7907                    }
7908                }
7909            }
7910        }
7911
7912        return finalList;
7913    }
7914
7915    @Override
7916    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7917        return resolveContentProviderInternal(name, flags, userId);
7918    }
7919
7920    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
7921        if (!sUserManager.exists(userId)) return null;
7922        flags = updateFlagsForComponent(flags, userId, name);
7923        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7924        // reader
7925        synchronized (mPackages) {
7926            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7927            PackageSetting ps = provider != null
7928                    ? mSettings.mPackages.get(provider.owner.packageName)
7929                    : null;
7930            if (ps != null) {
7931                final boolean isInstantApp = ps.getInstantApp(userId);
7932                // normal application; filter out instant application provider
7933                if (instantAppPkgName == null && isInstantApp) {
7934                    return null;
7935                }
7936                // instant application; filter out other instant applications
7937                if (instantAppPkgName != null
7938                        && isInstantApp
7939                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7940                    return null;
7941                }
7942                // instant application; filter out non-exposed provider
7943                if (instantAppPkgName != null
7944                        && !isInstantApp
7945                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
7946                    return null;
7947                }
7948                // provider not enabled
7949                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7950                    return null;
7951                }
7952                return PackageParser.generateProviderInfo(
7953                        provider, flags, ps.readUserState(userId), userId);
7954            }
7955            return null;
7956        }
7957    }
7958
7959    /**
7960     * @deprecated
7961     */
7962    @Deprecated
7963    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7964        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7965            return;
7966        }
7967        // reader
7968        synchronized (mPackages) {
7969            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7970                    .entrySet().iterator();
7971            final int userId = UserHandle.getCallingUserId();
7972            while (i.hasNext()) {
7973                Map.Entry<String, PackageParser.Provider> entry = i.next();
7974                PackageParser.Provider p = entry.getValue();
7975                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7976
7977                if (ps != null && p.syncable
7978                        && (!mSafeMode || (p.info.applicationInfo.flags
7979                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7980                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7981                            ps.readUserState(userId), userId);
7982                    if (info != null) {
7983                        outNames.add(entry.getKey());
7984                        outInfo.add(info);
7985                    }
7986                }
7987            }
7988        }
7989    }
7990
7991    @Override
7992    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7993            int uid, int flags, String metaDataKey) {
7994        final int callingUid = Binder.getCallingUid();
7995        final int userId = processName != null ? UserHandle.getUserId(uid)
7996                : UserHandle.getCallingUserId();
7997        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7998        flags = updateFlagsForComponent(flags, userId, processName);
7999        ArrayList<ProviderInfo> finalList = null;
8000        // reader
8001        synchronized (mPackages) {
8002            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8003            while (i.hasNext()) {
8004                final PackageParser.Provider p = i.next();
8005                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8006                if (ps != null && p.info.authority != null
8007                        && (processName == null
8008                                || (p.info.processName.equals(processName)
8009                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8010                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8011
8012                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8013                    // parameter.
8014                    if (metaDataKey != null
8015                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8016                        continue;
8017                    }
8018                    final ComponentName component =
8019                            new ComponentName(p.info.packageName, p.info.name);
8020                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8021                        continue;
8022                    }
8023                    if (finalList == null) {
8024                        finalList = new ArrayList<ProviderInfo>(3);
8025                    }
8026                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8027                            ps.readUserState(userId), userId);
8028                    if (info != null) {
8029                        finalList.add(info);
8030                    }
8031                }
8032            }
8033        }
8034
8035        if (finalList != null) {
8036            Collections.sort(finalList, mProviderInitOrderSorter);
8037            return new ParceledListSlice<ProviderInfo>(finalList);
8038        }
8039
8040        return ParceledListSlice.emptyList();
8041    }
8042
8043    @Override
8044    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8045        // reader
8046        synchronized (mPackages) {
8047            final int callingUid = Binder.getCallingUid();
8048            final int callingUserId = UserHandle.getUserId(callingUid);
8049            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8050            if (ps == null) return null;
8051            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8052                return null;
8053            }
8054            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8055            return PackageParser.generateInstrumentationInfo(i, flags);
8056        }
8057    }
8058
8059    @Override
8060    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8061            String targetPackage, int flags) {
8062        final int callingUid = Binder.getCallingUid();
8063        final int callingUserId = UserHandle.getUserId(callingUid);
8064        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8065        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8066            return ParceledListSlice.emptyList();
8067        }
8068        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8069    }
8070
8071    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8072            int flags) {
8073        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8074
8075        // reader
8076        synchronized (mPackages) {
8077            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8078            while (i.hasNext()) {
8079                final PackageParser.Instrumentation p = i.next();
8080                if (targetPackage == null
8081                        || targetPackage.equals(p.info.targetPackage)) {
8082                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8083                            flags);
8084                    if (ii != null) {
8085                        finalList.add(ii);
8086                    }
8087                }
8088            }
8089        }
8090
8091        return finalList;
8092    }
8093
8094    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8095        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8096        try {
8097            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8098        } finally {
8099            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8100        }
8101    }
8102
8103    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8104        final File[] files = scanDir.listFiles();
8105        if (ArrayUtils.isEmpty(files)) {
8106            Log.d(TAG, "No files in app dir " + scanDir);
8107            return;
8108        }
8109
8110        if (DEBUG_PACKAGE_SCANNING) {
8111            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8112                    + " flags=0x" + Integer.toHexString(parseFlags));
8113        }
8114        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8115                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8116                mParallelPackageParserCallback)) {
8117            // Submit files for parsing in parallel
8118            int fileCount = 0;
8119            for (File file : files) {
8120                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8121                        && !PackageInstallerService.isStageName(file.getName());
8122                if (!isPackage) {
8123                    // Ignore entries which are not packages
8124                    continue;
8125                }
8126                parallelPackageParser.submit(file, parseFlags);
8127                fileCount++;
8128            }
8129
8130            // Process results one by one
8131            for (; fileCount > 0; fileCount--) {
8132                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8133                Throwable throwable = parseResult.throwable;
8134                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8135
8136                if (throwable == null) {
8137                    // TODO(toddke): move lower in the scan chain
8138                    // Static shared libraries have synthetic package names
8139                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8140                        renameStaticSharedLibraryPackage(parseResult.pkg);
8141                    }
8142                    try {
8143                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8144                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8145                                    currentTime, null);
8146                        }
8147                    } catch (PackageManagerException e) {
8148                        errorCode = e.error;
8149                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8150                    }
8151                } else if (throwable instanceof PackageParser.PackageParserException) {
8152                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8153                            throwable;
8154                    errorCode = e.error;
8155                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8156                } else {
8157                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8158                            + parseResult.scanFile, throwable);
8159                }
8160
8161                // Delete invalid userdata apps
8162                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8163                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8164                    logCriticalInfo(Log.WARN,
8165                            "Deleting invalid package at " + parseResult.scanFile);
8166                    removeCodePathLI(parseResult.scanFile);
8167                }
8168            }
8169        }
8170    }
8171
8172    public static void reportSettingsProblem(int priority, String msg) {
8173        logCriticalInfo(priority, msg);
8174    }
8175
8176    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8177            final @ParseFlags int parseFlags) throws PackageManagerException {
8178        // When upgrading from pre-N MR1, verify the package time stamp using the package
8179        // directory and not the APK file.
8180        final long lastModifiedTime = mIsPreNMR1Upgrade
8181                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8182        if (ps != null
8183                && ps.codePathString.equals(pkg.codePath)
8184                && ps.timeStamp == lastModifiedTime
8185                && !isCompatSignatureUpdateNeeded(pkg)
8186                && !isRecoverSignatureUpdateNeeded(pkg)) {
8187            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8188            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
8189            ArraySet<PublicKey> signingKs;
8190            synchronized (mPackages) {
8191                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8192            }
8193            if (ps.signatures.mSignatures != null
8194                    && ps.signatures.mSignatures.length != 0
8195                    && signingKs != null) {
8196                // Optimization: reuse the existing cached certificates
8197                // if the package appears to be unchanged.
8198                pkg.mSignatures = ps.signatures.mSignatures;
8199                pkg.mSigningKeys = signingKs;
8200                return;
8201            }
8202
8203            Slog.w(TAG, "PackageSetting for " + ps.name
8204                    + " is missing signatures.  Collecting certs again to recover them.");
8205        } else {
8206            Slog.i(TAG, toString() + " changed; collecting certs");
8207        }
8208
8209        try {
8210            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8211            PackageParser.collectCertificates(pkg, parseFlags);
8212        } catch (PackageParserException e) {
8213            throw PackageManagerException.from(e);
8214        } finally {
8215            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8216        }
8217    }
8218
8219    /**
8220     *  Traces a package scan.
8221     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8222     */
8223    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8224            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8225        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8226        try {
8227            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8228        } finally {
8229            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8230        }
8231    }
8232
8233    /**
8234     *  Scans a package and returns the newly parsed package.
8235     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8236     */
8237    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8238            long currentTime, UserHandle user) throws PackageManagerException {
8239        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8240        PackageParser pp = new PackageParser();
8241        pp.setSeparateProcesses(mSeparateProcesses);
8242        pp.setOnlyCoreApps(mOnlyCore);
8243        pp.setDisplayMetrics(mMetrics);
8244        pp.setCallback(mPackageParserCallback);
8245
8246        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8247        final PackageParser.Package pkg;
8248        try {
8249            pkg = pp.parsePackage(scanFile, parseFlags);
8250        } catch (PackageParserException e) {
8251            throw PackageManagerException.from(e);
8252        } finally {
8253            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8254        }
8255
8256        // Static shared libraries have synthetic package names
8257        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8258            renameStaticSharedLibraryPackage(pkg);
8259        }
8260
8261        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8262    }
8263
8264    /**
8265     *  Scans a package and returns the newly parsed package.
8266     *  @throws PackageManagerException on a parse error.
8267     */
8268    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8269            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8270            @Nullable UserHandle user)
8271                    throws PackageManagerException {
8272        // If the package has children and this is the first dive in the function
8273        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8274        // packages (parent and children) would be successfully scanned before the
8275        // actual scan since scanning mutates internal state and we want to atomically
8276        // install the package and its children.
8277        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8278            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8279                scanFlags |= SCAN_CHECK_ONLY;
8280            }
8281        } else {
8282            scanFlags &= ~SCAN_CHECK_ONLY;
8283        }
8284
8285        // Scan the parent
8286        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, parseFlags,
8287                scanFlags, currentTime, user);
8288
8289        // Scan the children
8290        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8291        for (int i = 0; i < childCount; i++) {
8292            PackageParser.Package childPackage = pkg.childPackages.get(i);
8293            scanPackageInternalLI(childPackage, parseFlags, scanFlags,
8294                    currentTime, user);
8295        }
8296
8297
8298        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8299            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8300        }
8301
8302        return scannedPkg;
8303    }
8304
8305    /**
8306     *  Scans a package and returns the newly parsed package.
8307     *  @throws PackageManagerException on a parse error.
8308     */
8309    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg,
8310            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8311            @Nullable UserHandle user)
8312                    throws PackageManagerException {
8313        PackageSetting ps = null;
8314        PackageSetting updatedPs;
8315        // reader
8316        synchronized (mPackages) {
8317            // Look to see if we already know about this package.
8318            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8319            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8320                // This package has been renamed to its original name.  Let's
8321                // use that.
8322                ps = mSettings.getPackageLPr(oldName);
8323            }
8324            // If there was no original package, see one for the real package name.
8325            if (ps == null) {
8326                ps = mSettings.getPackageLPr(pkg.packageName);
8327            }
8328            // Check to see if this package could be hiding/updating a system
8329            // package.  Must look for it either under the original or real
8330            // package name depending on our state.
8331            updatedPs = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8332            if (DEBUG_INSTALL && updatedPs != null) Slog.d(TAG, "updatedPkg = " + updatedPs);
8333
8334            // If this is a package we don't know about on the system partition, we
8335            // may need to remove disabled child packages on the system partition
8336            // or may need to not add child packages if the parent apk is updated
8337            // on the data partition and no longer defines this child package.
8338            if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
8339                // If this is a parent package for an updated system app and this system
8340                // app got an OTA update which no longer defines some of the child packages
8341                // we have to prune them from the disabled system packages.
8342                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8343                if (disabledPs != null) {
8344                    final int scannedChildCount = (pkg.childPackages != null)
8345                            ? pkg.childPackages.size() : 0;
8346                    final int disabledChildCount = disabledPs.childPackageNames != null
8347                            ? disabledPs.childPackageNames.size() : 0;
8348                    for (int i = 0; i < disabledChildCount; i++) {
8349                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8350                        boolean disabledPackageAvailable = false;
8351                        for (int j = 0; j < scannedChildCount; j++) {
8352                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8353                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8354                                disabledPackageAvailable = true;
8355                                break;
8356                            }
8357                         }
8358                         if (!disabledPackageAvailable) {
8359                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8360                         }
8361                    }
8362                }
8363            }
8364        }
8365
8366        final boolean isUpdatedPkg = updatedPs != null;
8367        final boolean isUpdatedSystemPkg = isUpdatedPkg && (scanFlags & SCAN_AS_SYSTEM) != 0;
8368        boolean isUpdatedPkgBetter = false;
8369        // First check if this is a system package that may involve an update
8370        if (isUpdatedSystemPkg) {
8371            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8372            // it needs to drop FLAG_PRIVILEGED.
8373            if (locationIsPrivileged(pkg.codePath)) {
8374                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8375            } else {
8376                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8377            }
8378            // If new package is not located in "/oem" (e.g. due to an OTA),
8379            // it needs to drop FLAG_OEM.
8380            if (locationIsOem(pkg.codePath)) {
8381                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
8382            } else {
8383                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_OEM;
8384            }
8385            // If new package is not located in "/vendor" (e.g. due to an OTA),
8386            // it needs to drop FLAG_VENDOR.
8387            if (locationIsVendor(pkg.codePath)) {
8388                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
8389            } else {
8390                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VENDOR;
8391            }
8392
8393            if (ps != null && !ps.codePathString.equals(pkg.codePath)) {
8394                // The path has changed from what was last scanned...  check the
8395                // version of the new path against what we have stored to determine
8396                // what to do.
8397                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8398                if (pkg.getLongVersionCode() <= ps.versionCode) {
8399                    // The system package has been updated and the code path does not match
8400                    // Ignore entry. Skip it.
8401                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + pkg.codePath
8402                            + " ignored: updated version " + ps.versionCode
8403                            + " better than this " + pkg.getLongVersionCode());
8404                    if (!updatedPs.codePathString.equals(pkg.codePath)) {
8405                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8406                                + ps.name + " changing from " + updatedPs.codePathString
8407                                + " to " + pkg.codePath);
8408                        final File codePath = new File(pkg.codePath);
8409                        updatedPs.codePath = codePath;
8410                        updatedPs.codePathString = pkg.codePath;
8411                        updatedPs.resourcePath = codePath;
8412                        updatedPs.resourcePathString = pkg.codePath;
8413                    }
8414                    updatedPs.pkg = pkg;
8415                    updatedPs.versionCode = pkg.getLongVersionCode();
8416
8417                    // Update the disabled system child packages to point to the package too.
8418                    final int childCount = updatedPs.childPackageNames != null
8419                            ? updatedPs.childPackageNames.size() : 0;
8420                    for (int i = 0; i < childCount; i++) {
8421                        String childPackageName = updatedPs.childPackageNames.get(i);
8422                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8423                                childPackageName);
8424                        if (updatedChildPkg != null) {
8425                            updatedChildPkg.pkg = pkg;
8426                            updatedChildPkg.versionCode = pkg.getLongVersionCode();
8427                        }
8428                    }
8429                } else {
8430                    // The current app on the system partition is better than
8431                    // what we have updated to on the data partition; switch
8432                    // back to the system partition version.
8433                    // At this point, its safely assumed that package installation for
8434                    // apps in system partition will go through. If not there won't be a working
8435                    // version of the app
8436                    // writer
8437                    synchronized (mPackages) {
8438                        // Just remove the loaded entries from package lists.
8439                        mPackages.remove(ps.name);
8440                    }
8441
8442                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
8443                            + " reverting from " + ps.codePathString
8444                            + ": new version " + pkg.getLongVersionCode()
8445                            + " better than installed " + ps.versionCode);
8446
8447                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8448                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8449                    synchronized (mInstallLock) {
8450                        args.cleanUpResourcesLI();
8451                    }
8452                    synchronized (mPackages) {
8453                        mSettings.enableSystemPackageLPw(ps.name);
8454                    }
8455                    isUpdatedPkgBetter = true;
8456                }
8457            }
8458        }
8459
8460        String resourcePath = null;
8461        String baseResourcePath = null;
8462        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
8463            if (ps != null && ps.resourcePathString != null) {
8464                resourcePath = ps.resourcePathString;
8465                baseResourcePath = ps.resourcePathString;
8466            } else {
8467                // Should not happen at all. Just log an error.
8468                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8469            }
8470        } else {
8471            resourcePath = pkg.codePath;
8472            baseResourcePath = pkg.baseCodePath;
8473        }
8474
8475        // Set application objects path explicitly.
8476        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8477        pkg.setApplicationInfoCodePath(pkg.codePath);
8478        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8479        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8480        pkg.setApplicationInfoResourcePath(resourcePath);
8481        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8482        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8483
8484        // throw an exception if we have an update to a system application, but, it's not more
8485        // recent than the package we've already scanned
8486        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
8487            // Set CPU Abis to application info.
8488            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
8489                final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPs);
8490                derivePackageAbi(pkg, cpuAbiOverride, false);
8491            } else {
8492                pkg.applicationInfo.primaryCpuAbi = updatedPs.primaryCpuAbiString;
8493                pkg.applicationInfo.secondaryCpuAbi = updatedPs.secondaryCpuAbiString;
8494            }
8495            pkg.mExtras = updatedPs;
8496
8497            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8498                    + pkg.codePath + " ignored: updated version " + updatedPs.versionCode
8499                    + " better than this " + pkg.getLongVersionCode());
8500        }
8501
8502        if (isUpdatedPkg) {
8503            // updated system applications don't initially have the SCAN_AS_SYSTEM flag set
8504            scanFlags |= SCAN_AS_SYSTEM;
8505
8506            // An updated privileged application will not have the PARSE_IS_PRIVILEGED
8507            // flag set initially
8508            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8509                scanFlags |= SCAN_AS_PRIVILEGED;
8510            }
8511
8512            // An updated OEM app will not have the SCAN_AS_OEM
8513            // flag set initially
8514            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
8515                scanFlags |= SCAN_AS_OEM;
8516            }
8517
8518            // An updated vendor app will not have the SCAN_AS_VENDOR
8519            // flag set initially
8520            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
8521                scanFlags |= SCAN_AS_VENDOR;
8522            }
8523        }
8524
8525        // Verify certificates against what was last scanned
8526        collectCertificatesLI(ps, pkg, parseFlags);
8527
8528        /*
8529         * A new system app appeared, but we already had a non-system one of the
8530         * same name installed earlier.
8531         */
8532        boolean shouldHideSystemApp = false;
8533        if (!isUpdatedPkg && ps != null
8534                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8535            /*
8536             * Check to make sure the signatures match first. If they don't,
8537             * wipe the installed application and its data.
8538             */
8539            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8540                    != PackageManager.SIGNATURE_MATCH) {
8541                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8542                        + " signatures don't match existing userdata copy; removing");
8543                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8544                        "scanPackageInternalLI")) {
8545                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8546                }
8547                ps = null;
8548            } else {
8549                /*
8550                 * If the newly-added system app is an older version than the
8551                 * already installed version, hide it. It will be scanned later
8552                 * and re-added like an update.
8553                 */
8554                if (pkg.getLongVersionCode() <= ps.versionCode) {
8555                    shouldHideSystemApp = true;
8556                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + pkg.codePath
8557                            + " but new version " + pkg.getLongVersionCode()
8558                            + " better than installed " + ps.versionCode + "; hiding system");
8559                } else {
8560                    /*
8561                     * The newly found system app is a newer version that the
8562                     * one previously installed. Simply remove the
8563                     * already-installed application and replace it with our own
8564                     * while keeping the application data.
8565                     */
8566                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
8567                            + " reverting from " + ps.codePathString + ": new version "
8568                            + pkg.getLongVersionCode() + " better than installed "
8569                            + ps.versionCode);
8570                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8571                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8572                    synchronized (mInstallLock) {
8573                        args.cleanUpResourcesLI();
8574                    }
8575                }
8576            }
8577        }
8578
8579        // The apk is forward locked (not public) if its code and resources
8580        // are kept in different files. (except for app in either system or
8581        // vendor path).
8582        // TODO grab this value from PackageSettings
8583        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8584            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8585                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
8586            }
8587        }
8588
8589        final int userId = ((user == null) ? 0 : user.getIdentifier());
8590        if (ps != null && ps.getInstantApp(userId)) {
8591            scanFlags |= SCAN_AS_INSTANT_APP;
8592        }
8593        if (ps != null && ps.getVirtulalPreload(userId)) {
8594            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
8595        }
8596
8597        // Note that we invoke the following method only if we are about to unpack an application
8598        PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8599                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8600
8601        /*
8602         * If the system app should be overridden by a previously installed
8603         * data, hide the system app now and let the /data/app scan pick it up
8604         * again.
8605         */
8606        if (shouldHideSystemApp) {
8607            synchronized (mPackages) {
8608                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8609            }
8610        }
8611
8612        return scannedPkg;
8613    }
8614
8615    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8616        // Derive the new package synthetic package name
8617        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8618                + pkg.staticSharedLibVersion);
8619    }
8620
8621    private static String fixProcessName(String defProcessName,
8622            String processName) {
8623        if (processName == null) {
8624            return defProcessName;
8625        }
8626        return processName;
8627    }
8628
8629    /**
8630     * Enforces that only the system UID or root's UID can call a method exposed
8631     * via Binder.
8632     *
8633     * @param message used as message if SecurityException is thrown
8634     * @throws SecurityException if the caller is not system or root
8635     */
8636    private static final void enforceSystemOrRoot(String message) {
8637        final int uid = Binder.getCallingUid();
8638        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8639            throw new SecurityException(message);
8640        }
8641    }
8642
8643    @Override
8644    public void performFstrimIfNeeded() {
8645        enforceSystemOrRoot("Only the system can request fstrim");
8646
8647        // Before everything else, see whether we need to fstrim.
8648        try {
8649            IStorageManager sm = PackageHelper.getStorageManager();
8650            if (sm != null) {
8651                boolean doTrim = false;
8652                final long interval = android.provider.Settings.Global.getLong(
8653                        mContext.getContentResolver(),
8654                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8655                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8656                if (interval > 0) {
8657                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8658                    if (timeSinceLast > interval) {
8659                        doTrim = true;
8660                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8661                                + "; running immediately");
8662                    }
8663                }
8664                if (doTrim) {
8665                    final boolean dexOptDialogShown;
8666                    synchronized (mPackages) {
8667                        dexOptDialogShown = mDexOptDialogShown;
8668                    }
8669                    if (!isFirstBoot() && dexOptDialogShown) {
8670                        try {
8671                            ActivityManager.getService().showBootMessage(
8672                                    mContext.getResources().getString(
8673                                            R.string.android_upgrading_fstrim), true);
8674                        } catch (RemoteException e) {
8675                        }
8676                    }
8677                    sm.runMaintenance();
8678                }
8679            } else {
8680                Slog.e(TAG, "storageManager service unavailable!");
8681            }
8682        } catch (RemoteException e) {
8683            // Can't happen; StorageManagerService is local
8684        }
8685    }
8686
8687    @Override
8688    public void updatePackagesIfNeeded() {
8689        enforceSystemOrRoot("Only the system can request package update");
8690
8691        // We need to re-extract after an OTA.
8692        boolean causeUpgrade = isUpgrade();
8693
8694        // First boot or factory reset.
8695        // Note: we also handle devices that are upgrading to N right now as if it is their
8696        //       first boot, as they do not have profile data.
8697        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8698
8699        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8700        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8701
8702        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8703            return;
8704        }
8705
8706        List<PackageParser.Package> pkgs;
8707        synchronized (mPackages) {
8708            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8709        }
8710
8711        final long startTime = System.nanoTime();
8712        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8713                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
8714                    false /* bootComplete */);
8715
8716        final int elapsedTimeSeconds =
8717                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8718
8719        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8720        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8721        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8722        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8723        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8724    }
8725
8726    /*
8727     * Return the prebuilt profile path given a package base code path.
8728     */
8729    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8730        return pkg.baseCodePath + ".prof";
8731    }
8732
8733    /**
8734     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8735     * containing statistics about the invocation. The array consists of three elements,
8736     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8737     * and {@code numberOfPackagesFailed}.
8738     */
8739    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8740            final String compilerFilter, boolean bootComplete) {
8741
8742        int numberOfPackagesVisited = 0;
8743        int numberOfPackagesOptimized = 0;
8744        int numberOfPackagesSkipped = 0;
8745        int numberOfPackagesFailed = 0;
8746        final int numberOfPackagesToDexopt = pkgs.size();
8747
8748        for (PackageParser.Package pkg : pkgs) {
8749            numberOfPackagesVisited++;
8750
8751            boolean useProfileForDexopt = false;
8752
8753            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8754                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8755                // that are already compiled.
8756                File profileFile = new File(getPrebuildProfilePath(pkg));
8757                // Copy profile if it exists.
8758                if (profileFile.exists()) {
8759                    try {
8760                        // We could also do this lazily before calling dexopt in
8761                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8762                        // is that we don't have a good way to say "do this only once".
8763                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8764                                pkg.applicationInfo.uid, pkg.packageName)) {
8765                            Log.e(TAG, "Installer failed to copy system profile!");
8766                        } else {
8767                            // Disabled as this causes speed-profile compilation during first boot
8768                            // even if things are already compiled.
8769                            // useProfileForDexopt = true;
8770                        }
8771                    } catch (Exception e) {
8772                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8773                                e);
8774                    }
8775                } else {
8776                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8777                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8778                    // minimize the number off apps being speed-profile compiled during first boot.
8779                    // The other paths will not change the filter.
8780                    if (disabledPs != null && disabledPs.pkg.isStub) {
8781                        // The package is the stub one, remove the stub suffix to get the normal
8782                        // package and APK names.
8783                        String systemProfilePath =
8784                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8785                        profileFile = new File(systemProfilePath);
8786                        // If we have a profile for a compressed APK, copy it to the reference
8787                        // location.
8788                        // Note that copying the profile here will cause it to override the
8789                        // reference profile every OTA even though the existing reference profile
8790                        // may have more data. We can't copy during decompression since the
8791                        // directories are not set up at that point.
8792                        if (profileFile.exists()) {
8793                            try {
8794                                // We could also do this lazily before calling dexopt in
8795                                // PackageDexOptimizer to prevent this happening on first boot. The
8796                                // issue is that we don't have a good way to say "do this only
8797                                // once".
8798                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8799                                        pkg.applicationInfo.uid, pkg.packageName)) {
8800                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8801                                } else {
8802                                    useProfileForDexopt = true;
8803                                }
8804                            } catch (Exception e) {
8805                                Log.e(TAG, "Failed to copy profile " +
8806                                        profileFile.getAbsolutePath() + " ", e);
8807                            }
8808                        }
8809                    }
8810                }
8811            }
8812
8813            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8814                if (DEBUG_DEXOPT) {
8815                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8816                }
8817                numberOfPackagesSkipped++;
8818                continue;
8819            }
8820
8821            if (DEBUG_DEXOPT) {
8822                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8823                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8824            }
8825
8826            if (showDialog) {
8827                try {
8828                    ActivityManager.getService().showBootMessage(
8829                            mContext.getResources().getString(R.string.android_upgrading_apk,
8830                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8831                } catch (RemoteException e) {
8832                }
8833                synchronized (mPackages) {
8834                    mDexOptDialogShown = true;
8835                }
8836            }
8837
8838            String pkgCompilerFilter = compilerFilter;
8839            if (useProfileForDexopt) {
8840                // Use background dexopt mode to try and use the profile. Note that this does not
8841                // guarantee usage of the profile.
8842                pkgCompilerFilter =
8843                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
8844                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
8845            }
8846
8847            // checkProfiles is false to avoid merging profiles during boot which
8848            // might interfere with background compilation (b/28612421).
8849            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8850            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8851            // trade-off worth doing to save boot time work.
8852            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
8853            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
8854                    pkg.packageName,
8855                    pkgCompilerFilter,
8856                    dexoptFlags));
8857
8858            switch (primaryDexOptStaus) {
8859                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8860                    numberOfPackagesOptimized++;
8861                    break;
8862                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8863                    numberOfPackagesSkipped++;
8864                    break;
8865                case PackageDexOptimizer.DEX_OPT_FAILED:
8866                    numberOfPackagesFailed++;
8867                    break;
8868                default:
8869                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
8870                    break;
8871            }
8872        }
8873
8874        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8875                numberOfPackagesFailed };
8876    }
8877
8878    @Override
8879    public void notifyPackageUse(String packageName, int reason) {
8880        synchronized (mPackages) {
8881            final int callingUid = Binder.getCallingUid();
8882            final int callingUserId = UserHandle.getUserId(callingUid);
8883            if (getInstantAppPackageName(callingUid) != null) {
8884                if (!isCallerSameApp(packageName, callingUid)) {
8885                    return;
8886                }
8887            } else {
8888                if (isInstantApp(packageName, callingUserId)) {
8889                    return;
8890                }
8891            }
8892            notifyPackageUseLocked(packageName, reason);
8893        }
8894    }
8895
8896    private void notifyPackageUseLocked(String packageName, int reason) {
8897        final PackageParser.Package p = mPackages.get(packageName);
8898        if (p == null) {
8899            return;
8900        }
8901        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8902    }
8903
8904    @Override
8905    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
8906            List<String> classPaths, String loaderIsa) {
8907        int userId = UserHandle.getCallingUserId();
8908        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8909        if (ai == null) {
8910            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8911                + loadingPackageName + ", user=" + userId);
8912            return;
8913        }
8914        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
8915    }
8916
8917    @Override
8918    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
8919            IDexModuleRegisterCallback callback) {
8920        int userId = UserHandle.getCallingUserId();
8921        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
8922        DexManager.RegisterDexModuleResult result;
8923        if (ai == null) {
8924            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
8925                     " calling user. package=" + packageName + ", user=" + userId);
8926            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
8927        } else {
8928            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
8929        }
8930
8931        if (callback != null) {
8932            mHandler.post(() -> {
8933                try {
8934                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
8935                } catch (RemoteException e) {
8936                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
8937                }
8938            });
8939        }
8940    }
8941
8942    /**
8943     * Ask the package manager to perform a dex-opt with the given compiler filter.
8944     *
8945     * Note: exposed only for the shell command to allow moving packages explicitly to a
8946     *       definite state.
8947     */
8948    @Override
8949    public boolean performDexOptMode(String packageName,
8950            boolean checkProfiles, String targetCompilerFilter, boolean force,
8951            boolean bootComplete, String splitName) {
8952        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
8953                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
8954                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
8955        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
8956                splitName, flags));
8957    }
8958
8959    /**
8960     * Ask the package manager to perform a dex-opt with the given compiler filter on the
8961     * secondary dex files belonging to the given package.
8962     *
8963     * Note: exposed only for the shell command to allow moving packages explicitly to a
8964     *       definite state.
8965     */
8966    @Override
8967    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8968            boolean force) {
8969        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
8970                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
8971                DexoptOptions.DEXOPT_BOOT_COMPLETE |
8972                (force ? DexoptOptions.DEXOPT_FORCE : 0);
8973        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
8974    }
8975
8976    /*package*/ boolean performDexOpt(DexoptOptions options) {
8977        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8978            return false;
8979        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
8980            return false;
8981        }
8982
8983        if (options.isDexoptOnlySecondaryDex()) {
8984            return mDexManager.dexoptSecondaryDex(options);
8985        } else {
8986            int dexoptStatus = performDexOptWithStatus(options);
8987            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8988        }
8989    }
8990
8991    /**
8992     * Perform dexopt on the given package and return one of following result:
8993     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
8994     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
8995     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
8996     */
8997    /* package */ int performDexOptWithStatus(DexoptOptions options) {
8998        return performDexOptTraced(options);
8999    }
9000
9001    private int performDexOptTraced(DexoptOptions options) {
9002        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9003        try {
9004            return performDexOptInternal(options);
9005        } finally {
9006            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9007        }
9008    }
9009
9010    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9011    // if the package can now be considered up to date for the given filter.
9012    private int performDexOptInternal(DexoptOptions options) {
9013        PackageParser.Package p;
9014        synchronized (mPackages) {
9015            p = mPackages.get(options.getPackageName());
9016            if (p == null) {
9017                // Package could not be found. Report failure.
9018                return PackageDexOptimizer.DEX_OPT_FAILED;
9019            }
9020            mPackageUsage.maybeWriteAsync(mPackages);
9021            mCompilerStats.maybeWriteAsync();
9022        }
9023        long callingId = Binder.clearCallingIdentity();
9024        try {
9025            synchronized (mInstallLock) {
9026                return performDexOptInternalWithDependenciesLI(p, options);
9027            }
9028        } finally {
9029            Binder.restoreCallingIdentity(callingId);
9030        }
9031    }
9032
9033    public ArraySet<String> getOptimizablePackages() {
9034        ArraySet<String> pkgs = new ArraySet<String>();
9035        synchronized (mPackages) {
9036            for (PackageParser.Package p : mPackages.values()) {
9037                if (PackageDexOptimizer.canOptimizePackage(p)) {
9038                    pkgs.add(p.packageName);
9039                }
9040            }
9041        }
9042        return pkgs;
9043    }
9044
9045    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9046            DexoptOptions options) {
9047        // Select the dex optimizer based on the force parameter.
9048        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9049        //       allocate an object here.
9050        PackageDexOptimizer pdo = options.isForce()
9051                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9052                : mPackageDexOptimizer;
9053
9054        // Dexopt all dependencies first. Note: we ignore the return value and march on
9055        // on errors.
9056        // Note that we are going to call performDexOpt on those libraries as many times as
9057        // they are referenced in packages. When we do a batch of performDexOpt (for example
9058        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9059        // and the first package that uses the library will dexopt it. The
9060        // others will see that the compiled code for the library is up to date.
9061        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9062        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9063        if (!deps.isEmpty()) {
9064            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9065                    options.getCompilerFilter(), options.getSplitName(),
9066                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9067            for (PackageParser.Package depPackage : deps) {
9068                // TODO: Analyze and investigate if we (should) profile libraries.
9069                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9070                        getOrCreateCompilerPackageStats(depPackage),
9071                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9072            }
9073        }
9074        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9075                getOrCreateCompilerPackageStats(p),
9076                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9077    }
9078
9079    /**
9080     * Reconcile the information we have about the secondary dex files belonging to
9081     * {@code packagName} and the actual dex files. For all dex files that were
9082     * deleted, update the internal records and delete the generated oat files.
9083     */
9084    @Override
9085    public void reconcileSecondaryDexFiles(String packageName) {
9086        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9087            return;
9088        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9089            return;
9090        }
9091        mDexManager.reconcileSecondaryDexFiles(packageName);
9092    }
9093
9094    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9095    // a reference there.
9096    /*package*/ DexManager getDexManager() {
9097        return mDexManager;
9098    }
9099
9100    /**
9101     * Execute the background dexopt job immediately.
9102     */
9103    @Override
9104    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9105        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9106            return false;
9107        }
9108        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9109    }
9110
9111    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9112        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9113                || p.usesStaticLibraries != null) {
9114            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9115            Set<String> collectedNames = new HashSet<>();
9116            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9117
9118            retValue.remove(p);
9119
9120            return retValue;
9121        } else {
9122            return Collections.emptyList();
9123        }
9124    }
9125
9126    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9127            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9128        if (!collectedNames.contains(p.packageName)) {
9129            collectedNames.add(p.packageName);
9130            collected.add(p);
9131
9132            if (p.usesLibraries != null) {
9133                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9134                        null, collected, collectedNames);
9135            }
9136            if (p.usesOptionalLibraries != null) {
9137                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9138                        null, collected, collectedNames);
9139            }
9140            if (p.usesStaticLibraries != null) {
9141                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9142                        p.usesStaticLibrariesVersions, collected, collectedNames);
9143            }
9144        }
9145    }
9146
9147    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9148            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9149        final int libNameCount = libs.size();
9150        for (int i = 0; i < libNameCount; i++) {
9151            String libName = libs.get(i);
9152            long version = (versions != null && versions.length == libNameCount)
9153                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9154            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9155            if (libPkg != null) {
9156                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9157            }
9158        }
9159    }
9160
9161    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9162        synchronized (mPackages) {
9163            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9164            if (libEntry != null) {
9165                return mPackages.get(libEntry.apk);
9166            }
9167            return null;
9168        }
9169    }
9170
9171    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9172        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9173        if (versionedLib == null) {
9174            return null;
9175        }
9176        return versionedLib.get(version);
9177    }
9178
9179    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9180        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9181                pkg.staticSharedLibName);
9182        if (versionedLib == null) {
9183            return null;
9184        }
9185        long previousLibVersion = -1;
9186        final int versionCount = versionedLib.size();
9187        for (int i = 0; i < versionCount; i++) {
9188            final long libVersion = versionedLib.keyAt(i);
9189            if (libVersion < pkg.staticSharedLibVersion) {
9190                previousLibVersion = Math.max(previousLibVersion, libVersion);
9191            }
9192        }
9193        if (previousLibVersion >= 0) {
9194            return versionedLib.get(previousLibVersion);
9195        }
9196        return null;
9197    }
9198
9199    public void shutdown() {
9200        mPackageUsage.writeNow(mPackages);
9201        mCompilerStats.writeNow();
9202        mDexManager.writePackageDexUsageNow();
9203    }
9204
9205    @Override
9206    public void dumpProfiles(String packageName) {
9207        PackageParser.Package pkg;
9208        synchronized (mPackages) {
9209            pkg = mPackages.get(packageName);
9210            if (pkg == null) {
9211                throw new IllegalArgumentException("Unknown package: " + packageName);
9212            }
9213        }
9214        /* Only the shell, root, or the app user should be able to dump profiles. */
9215        int callingUid = Binder.getCallingUid();
9216        if (callingUid != Process.SHELL_UID &&
9217            callingUid != Process.ROOT_UID &&
9218            callingUid != pkg.applicationInfo.uid) {
9219            throw new SecurityException("dumpProfiles");
9220        }
9221
9222        synchronized (mInstallLock) {
9223            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9224            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9225            try {
9226                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9227                String codePaths = TextUtils.join(";", allCodePaths);
9228                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9229            } catch (InstallerException e) {
9230                Slog.w(TAG, "Failed to dump profiles", e);
9231            }
9232            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9233        }
9234    }
9235
9236    @Override
9237    public void forceDexOpt(String packageName) {
9238        enforceSystemOrRoot("forceDexOpt");
9239
9240        PackageParser.Package pkg;
9241        synchronized (mPackages) {
9242            pkg = mPackages.get(packageName);
9243            if (pkg == null) {
9244                throw new IllegalArgumentException("Unknown package: " + packageName);
9245            }
9246        }
9247
9248        synchronized (mInstallLock) {
9249            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9250
9251            // Whoever is calling forceDexOpt wants a compiled package.
9252            // Don't use profiles since that may cause compilation to be skipped.
9253            final int res = performDexOptInternalWithDependenciesLI(
9254                    pkg,
9255                    new DexoptOptions(packageName,
9256                            getDefaultCompilerFilter(),
9257                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9258
9259            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9260            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9261                throw new IllegalStateException("Failed to dexopt: " + res);
9262            }
9263        }
9264    }
9265
9266    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9267        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9268            Slog.w(TAG, "Unable to update from " + oldPkg.name
9269                    + " to " + newPkg.packageName
9270                    + ": old package not in system partition");
9271            return false;
9272        } else if (mPackages.get(oldPkg.name) != null) {
9273            Slog.w(TAG, "Unable to update from " + oldPkg.name
9274                    + " to " + newPkg.packageName
9275                    + ": old package still exists");
9276            return false;
9277        }
9278        return true;
9279    }
9280
9281    void removeCodePathLI(File codePath) {
9282        if (codePath.isDirectory()) {
9283            try {
9284                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9285            } catch (InstallerException e) {
9286                Slog.w(TAG, "Failed to remove code path", e);
9287            }
9288        } else {
9289            codePath.delete();
9290        }
9291    }
9292
9293    private int[] resolveUserIds(int userId) {
9294        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9295    }
9296
9297    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9298        if (pkg == null) {
9299            Slog.wtf(TAG, "Package was null!", new Throwable());
9300            return;
9301        }
9302        clearAppDataLeafLIF(pkg, userId, flags);
9303        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9304        for (int i = 0; i < childCount; i++) {
9305            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9306        }
9307    }
9308
9309    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9310        final PackageSetting ps;
9311        synchronized (mPackages) {
9312            ps = mSettings.mPackages.get(pkg.packageName);
9313        }
9314        for (int realUserId : resolveUserIds(userId)) {
9315            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9316            try {
9317                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9318                        ceDataInode);
9319            } catch (InstallerException e) {
9320                Slog.w(TAG, String.valueOf(e));
9321            }
9322        }
9323    }
9324
9325    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9326        if (pkg == null) {
9327            Slog.wtf(TAG, "Package was null!", new Throwable());
9328            return;
9329        }
9330        destroyAppDataLeafLIF(pkg, userId, flags);
9331        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9332        for (int i = 0; i < childCount; i++) {
9333            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9334        }
9335    }
9336
9337    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9338        final PackageSetting ps;
9339        synchronized (mPackages) {
9340            ps = mSettings.mPackages.get(pkg.packageName);
9341        }
9342        for (int realUserId : resolveUserIds(userId)) {
9343            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9344            try {
9345                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9346                        ceDataInode);
9347            } catch (InstallerException e) {
9348                Slog.w(TAG, String.valueOf(e));
9349            }
9350            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9351        }
9352    }
9353
9354    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9355        if (pkg == null) {
9356            Slog.wtf(TAG, "Package was null!", new Throwable());
9357            return;
9358        }
9359        destroyAppProfilesLeafLIF(pkg);
9360        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9361        for (int i = 0; i < childCount; i++) {
9362            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9363        }
9364    }
9365
9366    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9367        try {
9368            mInstaller.destroyAppProfiles(pkg.packageName);
9369        } catch (InstallerException e) {
9370            Slog.w(TAG, String.valueOf(e));
9371        }
9372    }
9373
9374    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9375        if (pkg == null) {
9376            Slog.wtf(TAG, "Package was null!", new Throwable());
9377            return;
9378        }
9379        clearAppProfilesLeafLIF(pkg);
9380        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9381        for (int i = 0; i < childCount; i++) {
9382            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9383        }
9384    }
9385
9386    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9387        try {
9388            mInstaller.clearAppProfiles(pkg.packageName);
9389        } catch (InstallerException e) {
9390            Slog.w(TAG, String.valueOf(e));
9391        }
9392    }
9393
9394    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9395            long lastUpdateTime) {
9396        // Set parent install/update time
9397        PackageSetting ps = (PackageSetting) pkg.mExtras;
9398        if (ps != null) {
9399            ps.firstInstallTime = firstInstallTime;
9400            ps.lastUpdateTime = lastUpdateTime;
9401        }
9402        // Set children install/update time
9403        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9404        for (int i = 0; i < childCount; i++) {
9405            PackageParser.Package childPkg = pkg.childPackages.get(i);
9406            ps = (PackageSetting) childPkg.mExtras;
9407            if (ps != null) {
9408                ps.firstInstallTime = firstInstallTime;
9409                ps.lastUpdateTime = lastUpdateTime;
9410            }
9411        }
9412    }
9413
9414    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9415            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        // The collection used here must maintain the order of addition (so
9445        // that libraries are searched in the correct order) and must have no
9446        // duplicates.
9447        Set<String> usesLibraryFiles = null;
9448        if (pkg.usesLibraries != null) {
9449            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9450                    null, null, pkg.packageName, changingLib, true,
9451                    pkg.applicationInfo.targetSdkVersion, null);
9452        }
9453        if (pkg.usesStaticLibraries != null) {
9454            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9455                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9456                    pkg.packageName, changingLib, true,
9457                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9458        }
9459        if (pkg.usesOptionalLibraries != null) {
9460            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9461                    null, null, pkg.packageName, changingLib, false,
9462                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9463        }
9464        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9465            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9466        } else {
9467            pkg.usesLibraryFiles = null;
9468        }
9469    }
9470
9471    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9472            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9473            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9474            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9475            throws PackageManagerException {
9476        final int libCount = requestedLibraries.size();
9477        for (int i = 0; i < libCount; i++) {
9478            final String libName = requestedLibraries.get(i);
9479            final long libVersion = requiredVersions != null ? requiredVersions[i]
9480                    : SharedLibraryInfo.VERSION_UNDEFINED;
9481            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9482            if (libEntry == null) {
9483                if (required) {
9484                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9485                            "Package " + packageName + " requires unavailable shared library "
9486                                    + libName + "; failing!");
9487                } else if (DEBUG_SHARED_LIBRARIES) {
9488                    Slog.i(TAG, "Package " + packageName
9489                            + " desires unavailable shared library "
9490                            + libName + "; ignoring!");
9491                }
9492            } else {
9493                if (requiredVersions != null && requiredCertDigests != null) {
9494                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9495                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9496                            "Package " + packageName + " requires unavailable static shared"
9497                                    + " library " + libName + " version "
9498                                    + libEntry.info.getLongVersion() + "; failing!");
9499                    }
9500
9501                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9502                    if (libPkg == null) {
9503                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9504                                "Package " + packageName + " requires unavailable static shared"
9505                                        + " library; failing!");
9506                    }
9507
9508                    final String[] expectedCertDigests = requiredCertDigests[i];
9509                    // For apps targeting O MR1 we require explicit enumeration of all certs.
9510                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9511                            ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
9512                            : PackageUtils.computeSignaturesSha256Digests(
9513                                    new Signature[]{libPkg.mSignatures[0]});
9514
9515                    // Take a shortcut if sizes don't match. Note that if an app doesn't
9516                    // target O we don't parse the "additional-certificate" tags similarly
9517                    // how we only consider all certs only for apps targeting O (see above).
9518                    // Therefore, the size check is safe to make.
9519                    if (expectedCertDigests.length != libCertDigests.length) {
9520                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9521                                "Package " + packageName + " requires differently signed" +
9522                                        " static shared library; failing!");
9523                    }
9524
9525                    // Use a predictable order as signature order may vary
9526                    Arrays.sort(libCertDigests);
9527                    Arrays.sort(expectedCertDigests);
9528
9529                    final int certCount = libCertDigests.length;
9530                    for (int j = 0; j < certCount; j++) {
9531                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9532                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9533                                    "Package " + packageName + " requires differently signed" +
9534                                            " static shared library; failing!");
9535                        }
9536                    }
9537                }
9538
9539                if (outUsedLibraries == null) {
9540                    // Use LinkedHashSet to preserve the order of files added to
9541                    // usesLibraryFiles while eliminating duplicates.
9542                    outUsedLibraries = new LinkedHashSet<>();
9543                }
9544                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9545            }
9546        }
9547        return outUsedLibraries;
9548    }
9549
9550    private static boolean hasString(List<String> list, List<String> which) {
9551        if (list == null) {
9552            return false;
9553        }
9554        for (int i=list.size()-1; i>=0; i--) {
9555            for (int j=which.size()-1; j>=0; j--) {
9556                if (which.get(j).equals(list.get(i))) {
9557                    return true;
9558                }
9559            }
9560        }
9561        return false;
9562    }
9563
9564    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9565            PackageParser.Package changingPkg) {
9566        ArrayList<PackageParser.Package> res = null;
9567        for (PackageParser.Package pkg : mPackages.values()) {
9568            if (changingPkg != null
9569                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9570                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9571                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9572                            changingPkg.staticSharedLibName)) {
9573                return null;
9574            }
9575            if (res == null) {
9576                res = new ArrayList<>();
9577            }
9578            res.add(pkg);
9579            try {
9580                updateSharedLibrariesLPr(pkg, changingPkg);
9581            } catch (PackageManagerException e) {
9582                // If a system app update or an app and a required lib missing we
9583                // delete the package and for updated system apps keep the data as
9584                // it is better for the user to reinstall than to be in an limbo
9585                // state. Also libs disappearing under an app should never happen
9586                // - just in case.
9587                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9588                    final int flags = pkg.isUpdatedSystemApp()
9589                            ? PackageManager.DELETE_KEEP_DATA : 0;
9590                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9591                            flags , null, true, null);
9592                }
9593                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9594            }
9595        }
9596        return res;
9597    }
9598
9599    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9600            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9601            @Nullable UserHandle user) throws PackageManagerException {
9602        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9603        // If the package has children and this is the first dive in the function
9604        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9605        // whether all packages (parent and children) would be successfully scanned
9606        // before the actual scan since scanning mutates internal state and we want
9607        // to atomically install the package and its children.
9608        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9609            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9610                scanFlags |= SCAN_CHECK_ONLY;
9611            }
9612        } else {
9613            scanFlags &= ~SCAN_CHECK_ONLY;
9614        }
9615
9616        final PackageParser.Package scannedPkg;
9617        try {
9618            // Scan the parent
9619            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9620            // Scan the children
9621            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9622            for (int i = 0; i < childCount; i++) {
9623                PackageParser.Package childPkg = pkg.childPackages.get(i);
9624                scanPackageNewLI(childPkg, parseFlags,
9625                        scanFlags, currentTime, user);
9626            }
9627        } finally {
9628            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9629        }
9630
9631        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9632            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9633        }
9634
9635        return scannedPkg;
9636    }
9637
9638    /** The result of a package scan. */
9639    private static class ScanResult {
9640        /** Whether or not the package scan was successful */
9641        public final boolean success;
9642        /**
9643         * The final package settings. This may be the same object passed in
9644         * the {@link ScanRequest}, but, with modified values.
9645         */
9646        @Nullable public final PackageSetting pkgSetting;
9647        /** ABI code paths that have changed in the package scan */
9648        @Nullable public final List<String> changedAbiCodePath;
9649        public ScanResult(
9650                boolean success,
9651                @Nullable PackageSetting pkgSetting,
9652                @Nullable List<String> changedAbiCodePath) {
9653            this.success = success;
9654            this.pkgSetting = pkgSetting;
9655            this.changedAbiCodePath = changedAbiCodePath;
9656        }
9657    }
9658
9659    /** A package to be scanned */
9660    private static class ScanRequest {
9661        /** The parsed package */
9662        @NonNull public final PackageParser.Package pkg;
9663        /** Shared user settings, if the package has a shared user */
9664        @Nullable public final SharedUserSetting sharedUserSetting;
9665        /**
9666         * Package settings of the currently installed version.
9667         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9668         * during scan.
9669         */
9670        @Nullable public final PackageSetting pkgSetting;
9671        /** A copy of the settings for the currently installed version */
9672        @Nullable public final PackageSetting oldPkgSetting;
9673        /** Package settings for the disabled version on the /system partition */
9674        @Nullable public final PackageSetting disabledPkgSetting;
9675        /** Package settings for the installed version under its original package name */
9676        @Nullable public final PackageSetting originalPkgSetting;
9677        /** The real package name of a renamed application */
9678        @Nullable public final String realPkgName;
9679        public final @ParseFlags int parseFlags;
9680        public final @ScanFlags int scanFlags;
9681        /** The user for which the package is being scanned */
9682        @Nullable public final UserHandle user;
9683        /** Whether or not the platform package is being scanned */
9684        public final boolean isPlatformPackage;
9685        public ScanRequest(
9686                @NonNull PackageParser.Package pkg,
9687                @Nullable SharedUserSetting sharedUserSetting,
9688                @Nullable PackageSetting pkgSetting,
9689                @Nullable PackageSetting disabledPkgSetting,
9690                @Nullable PackageSetting originalPkgSetting,
9691                @Nullable String realPkgName,
9692                @ParseFlags int parseFlags,
9693                @ScanFlags int scanFlags,
9694                boolean isPlatformPackage,
9695                @Nullable UserHandle user) {
9696            this.pkg = pkg;
9697            this.pkgSetting = pkgSetting;
9698            this.sharedUserSetting = sharedUserSetting;
9699            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9700            this.disabledPkgSetting = disabledPkgSetting;
9701            this.originalPkgSetting = originalPkgSetting;
9702            this.realPkgName = realPkgName;
9703            this.parseFlags = parseFlags;
9704            this.scanFlags = scanFlags;
9705            this.isPlatformPackage = isPlatformPackage;
9706            this.user = user;
9707        }
9708    }
9709
9710    @GuardedBy("mInstallLock")
9711    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9712            final @ParseFlags int parseFlags, final @ScanFlags int scanFlags, long currentTime,
9713            @Nullable UserHandle user) throws PackageManagerException {
9714
9715        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9716        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9717        if (realPkgName != null) {
9718            ensurePackageRenamed(pkg, renamedPkgName);
9719        }
9720        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9721        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9722        final PackageSetting disabledPkgSetting =
9723                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9724
9725        if (mTransferedPackages.contains(pkg.packageName)) {
9726            Slog.w(TAG, "Package " + pkg.packageName
9727                    + " was transferred to another, but its .apk remains");
9728        }
9729
9730        synchronized (mPackages) {
9731            applyPolicy(pkg, parseFlags, scanFlags);
9732            assertPackageIsValid(pkg, parseFlags, scanFlags);
9733
9734            SharedUserSetting sharedUserSetting = null;
9735            if (pkg.mSharedUserId != null) {
9736                // SIDE EFFECTS; may potentially allocate a new shared user
9737                sharedUserSetting = mSettings.getSharedUserLPw(
9738                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9739                if (DEBUG_PACKAGE_SCANNING) {
9740                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9741                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9742                                + " (uid=" + sharedUserSetting.userId + "):"
9743                                + " packages=" + sharedUserSetting.packages);
9744                }
9745            }
9746
9747            boolean scanSucceeded = false;
9748            try {
9749                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
9750                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
9751                        (pkg == mPlatformPackage), user);
9752                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
9753                if (result.success) {
9754                    commitScanResultsLocked(request, result);
9755                }
9756                scanSucceeded = true;
9757            } finally {
9758                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9759                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
9760                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9761                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9762                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9763                  }
9764            }
9765        }
9766        return pkg;
9767    }
9768
9769    /**
9770     * Commits the package scan and modifies system state.
9771     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
9772     * of committing the package, leaving the system in an inconsistent state.
9773     * This needs to be fixed so, once we get to this point, no errors are
9774     * possible and the system is not left in an inconsistent state.
9775     */
9776    @GuardedBy("mPackages")
9777    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
9778            throws PackageManagerException {
9779        final PackageParser.Package pkg = request.pkg;
9780        final @ParseFlags int parseFlags = request.parseFlags;
9781        final @ScanFlags int scanFlags = request.scanFlags;
9782        final PackageSetting oldPkgSetting = request.oldPkgSetting;
9783        final PackageSetting originalPkgSetting = request.originalPkgSetting;
9784        final UserHandle user = request.user;
9785        final String realPkgName = request.realPkgName;
9786        final PackageSetting pkgSetting = result.pkgSetting;
9787        final List<String> changedAbiCodePath = result.changedAbiCodePath;
9788        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
9789
9790        if (newPkgSettingCreated) {
9791            if (originalPkgSetting != null) {
9792                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
9793            }
9794            // THROWS: when we can't allocate a user id. add call to check if there's
9795            // enough space to ensure we won't throw; otherwise, don't modify state
9796            mSettings.addUserToSettingLPw(pkgSetting);
9797
9798            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
9799                mTransferedPackages.add(originalPkgSetting.name);
9800            }
9801        }
9802        // TODO(toddke): Consider a method specifically for modifying the Package object
9803        // post scan; or, moving this stuff out of the Package object since it has nothing
9804        // to do with the package on disk.
9805        // We need to have this here because addUserToSettingLPw() is sometimes responsible
9806        // for creating the application ID. If we did this earlier, we would be saving the
9807        // correct ID.
9808        pkg.applicationInfo.uid = pkgSetting.appId;
9809
9810        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9811
9812        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
9813            mTransferedPackages.add(pkg.packageName);
9814        }
9815
9816        // THROWS: when requested libraries that can't be found. it only changes
9817        // the state of the passed in pkg object, so, move to the top of the method
9818        // and allow it to abort
9819        if ((scanFlags & SCAN_BOOTING) == 0
9820                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9821            // Check all shared libraries and map to their actual file path.
9822            // We only do this here for apps not on a system dir, because those
9823            // are the only ones that can fail an install due to this.  We
9824            // will take care of the system apps by updating all of their
9825            // library paths after the scan is done. Also during the initial
9826            // scan don't update any libs as we do this wholesale after all
9827            // apps are scanned to avoid dependency based scanning.
9828            updateSharedLibrariesLPr(pkg, null);
9829        }
9830
9831        // All versions of a static shared library are referenced with the same
9832        // package name. Internally, we use a synthetic package name to allow
9833        // multiple versions of the same shared library to be installed. So,
9834        // we need to generate the synthetic package name of the latest shared
9835        // library in order to compare signatures.
9836        PackageSetting signatureCheckPs = pkgSetting;
9837        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9838            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9839            if (libraryEntry != null) {
9840                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9841            }
9842        }
9843
9844        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
9845        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
9846            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
9847                // We just determined the app is signed correctly, so bring
9848                // over the latest parsed certs.
9849                pkgSetting.signatures.mSignatures = pkg.mSignatures;
9850            } else {
9851                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9852                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9853                            "Package " + pkg.packageName + " upgrade keys do not match the "
9854                                    + "previously installed version");
9855                } else {
9856                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9857                    String msg = "System package " + pkg.packageName
9858                            + " signature changed; retaining data.";
9859                    reportSettingsProblem(Log.WARN, msg);
9860                }
9861            }
9862        } else {
9863            try {
9864                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
9865                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
9866                final boolean compatMatch = verifySignatures(signatureCheckPs, pkg.mSignatures,
9867                        compareCompat, compareRecover);
9868                // The new KeySets will be re-added later in the scanning process.
9869                if (compatMatch) {
9870                    synchronized (mPackages) {
9871                        ksms.removeAppKeySetDataLPw(pkg.packageName);
9872                    }
9873                }
9874                // We just determined the app is signed correctly, so bring
9875                // over the latest parsed certs.
9876                pkgSetting.signatures.mSignatures = pkg.mSignatures;
9877            } catch (PackageManagerException e) {
9878                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9879                    throw e;
9880                }
9881                // The signature has changed, but this package is in the system
9882                // image...  let's recover!
9883                pkgSetting.signatures.mSignatures = pkg.mSignatures;
9884                // However...  if this package is part of a shared user, but it
9885                // doesn't match the signature of the shared user, let's fail.
9886                // What this means is that you can't change the signatures
9887                // associated with an overall shared user, which doesn't seem all
9888                // that unreasonable.
9889                if (signatureCheckPs.sharedUser != null) {
9890                    if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9891                            pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9892                        throw new PackageManagerException(
9893                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9894                                "Signature mismatch for shared user: "
9895                                        + pkgSetting.sharedUser);
9896                    }
9897                }
9898                // File a report about this.
9899                String msg = "System package " + pkg.packageName
9900                        + " signature changed; retaining data.";
9901                reportSettingsProblem(Log.WARN, msg);
9902            }
9903        }
9904
9905        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9906            // This package wants to adopt ownership of permissions from
9907            // another package.
9908            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9909                final String origName = pkg.mAdoptPermissions.get(i);
9910                final PackageSetting orig = mSettings.getPackageLPr(origName);
9911                if (orig != null) {
9912                    if (verifyPackageUpdateLPr(orig, pkg)) {
9913                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
9914                                + pkg.packageName);
9915                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
9916                    }
9917                }
9918            }
9919        }
9920
9921        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
9922            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
9923                final String codePathString = changedAbiCodePath.get(i);
9924                try {
9925                    mInstaller.rmdex(codePathString,
9926                            getDexCodeInstructionSet(getPreferredInstructionSet()));
9927                } catch (InstallerException ignored) {
9928                }
9929            }
9930        }
9931
9932        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9933            if (oldPkgSetting != null) {
9934                synchronized (mPackages) {
9935                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
9936                }
9937            }
9938        } else {
9939            final int userId = user == null ? 0 : user.getIdentifier();
9940            // Modify state for the given package setting
9941            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9942                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9943            if (pkgSetting.getInstantApp(userId)) {
9944                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9945            }
9946        }
9947    }
9948
9949    /**
9950     * Returns the "real" name of the package.
9951     * <p>This may differ from the package's actual name if the application has already
9952     * been installed under one of this package's original names.
9953     */
9954    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
9955            @Nullable String renamedPkgName) {
9956        if (pkg.mOriginalPackages == null || !pkg.mOriginalPackages.contains(renamedPkgName)) {
9957            return null;
9958        }
9959        return pkg.mRealPackage;
9960    }
9961
9962    /**
9963     * Returns the original package setting.
9964     * <p>A package can migrate its name during an update. In this scenario, a package
9965     * designates a set of names that it considers as one of its original names.
9966     * <p>An original package must be signed identically and it must have the same
9967     * shared user [if any].
9968     */
9969    @GuardedBy("mPackages")
9970    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
9971            @Nullable String renamedPkgName) {
9972        if (pkg.mOriginalPackages == null || pkg.mOriginalPackages.contains(renamedPkgName)) {
9973            return null;
9974        }
9975        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
9976            final PackageSetting originalPs =
9977                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
9978            if (originalPs != null) {
9979                // the package is already installed under its original name...
9980                // but, should we use it?
9981                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
9982                    // the new package is incompatible with the original
9983                    continue;
9984                } else if (originalPs.sharedUser != null) {
9985                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
9986                        // the shared user id is incompatible with the original
9987                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
9988                                + " to " + pkg.packageName + ": old uid "
9989                                + originalPs.sharedUser.name
9990                                + " differs from " + pkg.mSharedUserId);
9991                        continue;
9992                    }
9993                    // TODO: Add case when shared user id is added [b/28144775]
9994                } else {
9995                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9996                            + pkg.packageName + " to old name " + originalPs.name);
9997                }
9998                return originalPs;
9999            }
10000        }
10001        return null;
10002    }
10003
10004    /**
10005     * Renames the package if it was installed under a different name.
10006     * <p>When we've already installed the package under an original name, update
10007     * the new package so we can continue to have the old name.
10008     */
10009    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10010            @NonNull String renamedPackageName) {
10011        if (pkg.mOriginalPackages == null
10012                || !pkg.mOriginalPackages.contains(renamedPackageName)
10013                || pkg.packageName.equals(renamedPackageName)) {
10014            return;
10015        }
10016        pkg.setPackageName(renamedPackageName);
10017    }
10018
10019    /**
10020     * Just scans the package without any side effects.
10021     * <p>Not entirely true at the moment. There is still one side effect -- this
10022     * method potentially modifies a live {@link PackageSetting} object representing
10023     * the package being scanned. This will be resolved in the future.
10024     *
10025     * @param request Information about the package to be scanned
10026     * @param isUnderFactoryTest Whether or not the device is under factory test
10027     * @param currentTime The current time, in millis
10028     * @return The results of the scan
10029     */
10030    @GuardedBy("mInstallLock")
10031    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10032            boolean isUnderFactoryTest, long currentTime)
10033                    throws PackageManagerException {
10034        final PackageParser.Package pkg = request.pkg;
10035        PackageSetting pkgSetting = request.pkgSetting;
10036        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10037        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10038        final @ParseFlags int parseFlags = request.parseFlags;
10039        final @ScanFlags int scanFlags = request.scanFlags;
10040        final String realPkgName = request.realPkgName;
10041        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10042        final UserHandle user = request.user;
10043        final boolean isPlatformPackage = request.isPlatformPackage;
10044
10045        List<String> changedAbiCodePath = null;
10046
10047        if (DEBUG_PACKAGE_SCANNING) {
10048            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10049                Log.d(TAG, "Scanning package " + pkg.packageName);
10050        }
10051
10052        if (Build.IS_DEBUGGABLE &&
10053                pkg.isPrivileged() &&
10054                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10055            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10056        }
10057
10058        // Initialize package source and resource directories
10059        final File scanFile = new File(pkg.codePath);
10060        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10061        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10062
10063        // We keep references to the derived CPU Abis from settings in oder to reuse
10064        // them in the case where we're not upgrading or booting for the first time.
10065        String primaryCpuAbiFromSettings = null;
10066        String secondaryCpuAbiFromSettings = null;
10067        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10068
10069        if (!needToDeriveAbi) {
10070            if (pkgSetting != null) {
10071                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10072                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10073            } else {
10074                // Re-scanning a system package after uninstalling updates; need to derive ABI
10075                needToDeriveAbi = true;
10076            }
10077        }
10078
10079        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10080            PackageManagerService.reportSettingsProblem(Log.WARN,
10081                    "Package " + pkg.packageName + " shared user changed from "
10082                            + (pkgSetting.sharedUser != null
10083                            ? pkgSetting.sharedUser.name : "<nothing>")
10084                            + " to "
10085                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10086                            + "; replacing with new");
10087            pkgSetting = null;
10088        }
10089
10090        String[] usesStaticLibraries = null;
10091        if (pkg.usesStaticLibraries != null) {
10092            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10093            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10094        }
10095
10096        final boolean createNewPackage = (pkgSetting == null);
10097        if (createNewPackage) {
10098            final String parentPackageName = (pkg.parentPackage != null)
10099                    ? pkg.parentPackage.packageName : null;
10100            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10101            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10102            // REMOVE SharedUserSetting from method; update in a separate call
10103            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10104                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10105                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10106                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10107                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10108                    user, true /*allowInstall*/, instantApp, virtualPreload,
10109                    parentPackageName, pkg.getChildPackageNames(),
10110                    UserManagerService.getInstance(), usesStaticLibraries,
10111                    pkg.usesStaticLibrariesVersions);
10112        } else {
10113            // REMOVE SharedUserSetting from method; update in a separate call.
10114            //
10115            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10116            // secondaryCpuAbi are not known at this point so we always update them
10117            // to null here, only to reset them at a later point.
10118            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10119                    destCodeFile, pkg.applicationInfo.nativeLibraryDir,
10120                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10121                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10122                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10123                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10124        }
10125        if (createNewPackage && originalPkgSetting != null) {
10126            // If we are first transitioning from an original package,
10127            // fix up the new package's name now.  We need to do this after
10128            // looking up the package under its new name, so getPackageLP
10129            // can take care of fiddling things correctly.
10130            pkg.setPackageName(originalPkgSetting.name);
10131
10132            // File a report about this.
10133            String msg = "New package " + pkgSetting.realName
10134                    + " renamed to replace old package " + pkgSetting.name;
10135            reportSettingsProblem(Log.WARN, msg);
10136        }
10137
10138        if (disabledPkgSetting != null) {
10139            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10140        }
10141
10142        SELinuxMMAC.assignSeInfoValue(pkg);
10143
10144        pkg.mExtras = pkgSetting;
10145        pkg.applicationInfo.processName = fixProcessName(
10146                pkg.applicationInfo.packageName,
10147                pkg.applicationInfo.processName);
10148
10149        if (!isPlatformPackage) {
10150            // Get all of our default paths setup
10151            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10152        }
10153
10154        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10155
10156        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10157            if (needToDeriveAbi) {
10158                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10159                final boolean extractNativeLibs = !pkg.isLibrary();
10160                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10161                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10162
10163                // Some system apps still use directory structure for native libraries
10164                // in which case we might end up not detecting abi solely based on apk
10165                // structure. Try to detect abi based on directory structure.
10166                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10167                        pkg.applicationInfo.primaryCpuAbi == null) {
10168                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10169                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10170                }
10171            } else {
10172                // This is not a first boot or an upgrade, don't bother deriving the
10173                // ABI during the scan. Instead, trust the value that was stored in the
10174                // package setting.
10175                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10176                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10177
10178                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10179
10180                if (DEBUG_ABI_SELECTION) {
10181                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10182                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10183                            pkg.applicationInfo.secondaryCpuAbi);
10184                }
10185            }
10186        } else {
10187            if ((scanFlags & SCAN_MOVE) != 0) {
10188                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10189                // but we already have this packages package info in the PackageSetting. We just
10190                // use that and derive the native library path based on the new codepath.
10191                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10192                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10193            }
10194
10195            // Set native library paths again. For moves, the path will be updated based on the
10196            // ABIs we've determined above. For non-moves, the path will be updated based on the
10197            // ABIs we determined during compilation, but the path will depend on the final
10198            // package path (after the rename away from the stage path).
10199            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10200        }
10201
10202        // This is a special case for the "system" package, where the ABI is
10203        // dictated by the zygote configuration (and init.rc). We should keep track
10204        // of this ABI so that we can deal with "normal" applications that run under
10205        // the same UID correctly.
10206        if (isPlatformPackage) {
10207            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10208                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10209        }
10210
10211        // If there's a mismatch between the abi-override in the package setting
10212        // and the abiOverride specified for the install. Warn about this because we
10213        // would've already compiled the app without taking the package setting into
10214        // account.
10215        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10216            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10217                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10218                        " for package " + pkg.packageName);
10219            }
10220        }
10221
10222        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10223        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10224        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10225
10226        // Copy the derived override back to the parsed package, so that we can
10227        // update the package settings accordingly.
10228        pkg.cpuAbiOverride = cpuAbiOverride;
10229
10230        if (DEBUG_ABI_SELECTION) {
10231            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10232                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10233                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10234        }
10235
10236        // Push the derived path down into PackageSettings so we know what to
10237        // clean up at uninstall time.
10238        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10239
10240        if (DEBUG_ABI_SELECTION) {
10241            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10242                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10243                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10244        }
10245
10246        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10247            // We don't do this here during boot because we can do it all
10248            // at once after scanning all existing packages.
10249            //
10250            // We also do this *before* we perform dexopt on this package, so that
10251            // we can avoid redundant dexopts, and also to make sure we've got the
10252            // code and package path correct.
10253            changedAbiCodePath =
10254                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10255        }
10256
10257        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10258                android.Manifest.permission.FACTORY_TEST)) {
10259            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10260        }
10261
10262        if (isSystemApp(pkg)) {
10263            pkgSetting.isOrphaned = true;
10264        }
10265
10266        // Take care of first install / last update times.
10267        final long scanFileTime = getLastModifiedTime(pkg);
10268        if (currentTime != 0) {
10269            if (pkgSetting.firstInstallTime == 0) {
10270                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10271            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10272                pkgSetting.lastUpdateTime = currentTime;
10273            }
10274        } else if (pkgSetting.firstInstallTime == 0) {
10275            // We need *something*.  Take time time stamp of the file.
10276            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10277        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10278            if (scanFileTime != pkgSetting.timeStamp) {
10279                // A package on the system image has changed; consider this
10280                // to be an update.
10281                pkgSetting.lastUpdateTime = scanFileTime;
10282            }
10283        }
10284        pkgSetting.setTimeStamp(scanFileTime);
10285
10286        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10287    }
10288
10289    /**
10290     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10291     */
10292    private static boolean apkHasCode(String fileName) {
10293        StrictJarFile jarFile = null;
10294        try {
10295            jarFile = new StrictJarFile(fileName,
10296                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10297            return jarFile.findEntry("classes.dex") != null;
10298        } catch (IOException ignore) {
10299        } finally {
10300            try {
10301                if (jarFile != null) {
10302                    jarFile.close();
10303                }
10304            } catch (IOException ignore) {}
10305        }
10306        return false;
10307    }
10308
10309    /**
10310     * Enforces code policy for the package. This ensures that if an APK has
10311     * declared hasCode="true" in its manifest that the APK actually contains
10312     * code.
10313     *
10314     * @throws PackageManagerException If bytecode could not be found when it should exist
10315     */
10316    private static void assertCodePolicy(PackageParser.Package pkg)
10317            throws PackageManagerException {
10318        final boolean shouldHaveCode =
10319                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10320        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10321            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10322                    "Package " + pkg.baseCodePath + " code is missing");
10323        }
10324
10325        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10326            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10327                final boolean splitShouldHaveCode =
10328                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10329                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10330                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10331                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10332                }
10333            }
10334        }
10335    }
10336
10337    /**
10338     * Applies policy to the parsed package based upon the given policy flags.
10339     * Ensures the package is in a good state.
10340     * <p>
10341     * Implementation detail: This method must NOT have any side effect. It would
10342     * ideally be static, but, it requires locks to read system state.
10343     */
10344    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10345            final @ScanFlags int scanFlags) {
10346        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10347            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10348            if (pkg.applicationInfo.isDirectBootAware()) {
10349                // we're direct boot aware; set for all components
10350                for (PackageParser.Service s : pkg.services) {
10351                    s.info.encryptionAware = s.info.directBootAware = true;
10352                }
10353                for (PackageParser.Provider p : pkg.providers) {
10354                    p.info.encryptionAware = p.info.directBootAware = true;
10355                }
10356                for (PackageParser.Activity a : pkg.activities) {
10357                    a.info.encryptionAware = a.info.directBootAware = true;
10358                }
10359                for (PackageParser.Activity r : pkg.receivers) {
10360                    r.info.encryptionAware = r.info.directBootAware = true;
10361                }
10362            }
10363            if (compressedFileExists(pkg.codePath)) {
10364                pkg.isStub = true;
10365            }
10366        } else {
10367            // non system apps can't be flagged as core
10368            pkg.coreApp = false;
10369            // clear flags not applicable to regular apps
10370            pkg.applicationInfo.flags &=
10371                    ~ApplicationInfo.FLAG_PERSISTENT;
10372            pkg.applicationInfo.privateFlags &=
10373                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10374            pkg.applicationInfo.privateFlags &=
10375                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10376            // clear protected broadcasts
10377            pkg.protectedBroadcasts = null;
10378            // cap permission priorities
10379            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10380                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10381                    pkg.permissionGroups.get(i).info.priority = 0;
10382                }
10383            }
10384        }
10385        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10386            // ignore export request for single user receivers
10387            if (pkg.receivers != null) {
10388                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10389                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10390                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10391                        receiver.info.exported = false;
10392                    }
10393                }
10394            }
10395            // ignore export request for single user services
10396            if (pkg.services != null) {
10397                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10398                    final PackageParser.Service service = pkg.services.get(i);
10399                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10400                        service.info.exported = false;
10401                    }
10402                }
10403            }
10404            // ignore export request for single user providers
10405            if (pkg.providers != null) {
10406                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10407                    final PackageParser.Provider provider = pkg.providers.get(i);
10408                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10409                        provider.info.exported = false;
10410                    }
10411                }
10412            }
10413        }
10414        pkg.mTrustedOverlay = (scanFlags & SCAN_TRUSTED_OVERLAY) != 0;
10415
10416        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10417            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10418        }
10419
10420        if ((scanFlags & SCAN_AS_OEM) != 0) {
10421            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10422        }
10423
10424        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10425            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10426        }
10427
10428        if (!isSystemApp(pkg)) {
10429            // Only system apps can use these features.
10430            pkg.mOriginalPackages = null;
10431            pkg.mRealPackage = null;
10432            pkg.mAdoptPermissions = null;
10433        }
10434    }
10435
10436    /**
10437     * Asserts the parsed package is valid according to the given policy. If the
10438     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10439     * <p>
10440     * Implementation detail: This method must NOT have any side effects. It would
10441     * ideally be static, but, it requires locks to read system state.
10442     *
10443     * @throws PackageManagerException If the package fails any of the validation checks
10444     */
10445    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10446            final @ScanFlags int scanFlags)
10447                    throws PackageManagerException {
10448        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10449            assertCodePolicy(pkg);
10450        }
10451
10452        if (pkg.applicationInfo.getCodePath() == null ||
10453                pkg.applicationInfo.getResourcePath() == null) {
10454            // Bail out. The resource and code paths haven't been set.
10455            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10456                    "Code and resource paths haven't been set correctly");
10457        }
10458
10459        // Make sure we're not adding any bogus keyset info
10460        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10461        ksms.assertScannedPackageValid(pkg);
10462
10463        synchronized (mPackages) {
10464            // The special "android" package can only be defined once
10465            if (pkg.packageName.equals("android")) {
10466                if (mAndroidApplication != null) {
10467                    Slog.w(TAG, "*************************************************");
10468                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10469                    Slog.w(TAG, " codePath=" + pkg.codePath);
10470                    Slog.w(TAG, "*************************************************");
10471                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10472                            "Core android package being redefined.  Skipping.");
10473                }
10474            }
10475
10476            // A package name must be unique; don't allow duplicates
10477            if (mPackages.containsKey(pkg.packageName)) {
10478                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10479                        "Application package " + pkg.packageName
10480                        + " already installed.  Skipping duplicate.");
10481            }
10482
10483            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10484                // Static libs have a synthetic package name containing the version
10485                // but we still want the base name to be unique.
10486                if (mPackages.containsKey(pkg.manifestPackageName)) {
10487                    throw new PackageManagerException(
10488                            "Duplicate static shared lib provider package");
10489                }
10490
10491                // Static shared libraries should have at least O target SDK
10492                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10493                    throw new PackageManagerException(
10494                            "Packages declaring static-shared libs must target O SDK or higher");
10495                }
10496
10497                // Package declaring static a shared lib cannot be instant apps
10498                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10499                    throw new PackageManagerException(
10500                            "Packages declaring static-shared libs cannot be instant apps");
10501                }
10502
10503                // Package declaring static a shared lib cannot be renamed since the package
10504                // name is synthetic and apps can't code around package manager internals.
10505                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10506                    throw new PackageManagerException(
10507                            "Packages declaring static-shared libs cannot be renamed");
10508                }
10509
10510                // Package declaring static a shared lib cannot declare child packages
10511                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10512                    throw new PackageManagerException(
10513                            "Packages declaring static-shared libs cannot have child packages");
10514                }
10515
10516                // Package declaring static a shared lib cannot declare dynamic libs
10517                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10518                    throw new PackageManagerException(
10519                            "Packages declaring static-shared libs cannot declare dynamic libs");
10520                }
10521
10522                // Package declaring static a shared lib cannot declare shared users
10523                if (pkg.mSharedUserId != null) {
10524                    throw new PackageManagerException(
10525                            "Packages declaring static-shared libs cannot declare shared users");
10526                }
10527
10528                // Static shared libs cannot declare activities
10529                if (!pkg.activities.isEmpty()) {
10530                    throw new PackageManagerException(
10531                            "Static shared libs cannot declare activities");
10532                }
10533
10534                // Static shared libs cannot declare services
10535                if (!pkg.services.isEmpty()) {
10536                    throw new PackageManagerException(
10537                            "Static shared libs cannot declare services");
10538                }
10539
10540                // Static shared libs cannot declare providers
10541                if (!pkg.providers.isEmpty()) {
10542                    throw new PackageManagerException(
10543                            "Static shared libs cannot declare content providers");
10544                }
10545
10546                // Static shared libs cannot declare receivers
10547                if (!pkg.receivers.isEmpty()) {
10548                    throw new PackageManagerException(
10549                            "Static shared libs cannot declare broadcast receivers");
10550                }
10551
10552                // Static shared libs cannot declare permission groups
10553                if (!pkg.permissionGroups.isEmpty()) {
10554                    throw new PackageManagerException(
10555                            "Static shared libs cannot declare permission groups");
10556                }
10557
10558                // Static shared libs cannot declare permissions
10559                if (!pkg.permissions.isEmpty()) {
10560                    throw new PackageManagerException(
10561                            "Static shared libs cannot declare permissions");
10562                }
10563
10564                // Static shared libs cannot declare protected broadcasts
10565                if (pkg.protectedBroadcasts != null) {
10566                    throw new PackageManagerException(
10567                            "Static shared libs cannot declare protected broadcasts");
10568                }
10569
10570                // Static shared libs cannot be overlay targets
10571                if (pkg.mOverlayTarget != null) {
10572                    throw new PackageManagerException(
10573                            "Static shared libs cannot be overlay targets");
10574                }
10575
10576                // The version codes must be ordered as lib versions
10577                long minVersionCode = Long.MIN_VALUE;
10578                long maxVersionCode = Long.MAX_VALUE;
10579
10580                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10581                        pkg.staticSharedLibName);
10582                if (versionedLib != null) {
10583                    final int versionCount = versionedLib.size();
10584                    for (int i = 0; i < versionCount; i++) {
10585                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10586                        final long libVersionCode = libInfo.getDeclaringPackage()
10587                                .getLongVersionCode();
10588                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10589                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10590                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10591                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10592                        } else {
10593                            minVersionCode = maxVersionCode = libVersionCode;
10594                            break;
10595                        }
10596                    }
10597                }
10598                if (pkg.getLongVersionCode() < minVersionCode
10599                        || pkg.getLongVersionCode() > maxVersionCode) {
10600                    throw new PackageManagerException("Static shared"
10601                            + " lib version codes must be ordered as lib versions");
10602                }
10603            }
10604
10605            // Only privileged apps and updated privileged apps can add child packages.
10606            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10607                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10608                    throw new PackageManagerException("Only privileged apps can add child "
10609                            + "packages. Ignoring package " + pkg.packageName);
10610                }
10611                final int childCount = pkg.childPackages.size();
10612                for (int i = 0; i < childCount; i++) {
10613                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10614                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10615                            childPkg.packageName)) {
10616                        throw new PackageManagerException("Can't override child of "
10617                                + "another disabled app. Ignoring package " + pkg.packageName);
10618                    }
10619                }
10620            }
10621
10622            // If we're only installing presumed-existing packages, require that the
10623            // scanned APK is both already known and at the path previously established
10624            // for it.  Previously unknown packages we pick up normally, but if we have an
10625            // a priori expectation about this package's install presence, enforce it.
10626            // With a singular exception for new system packages. When an OTA contains
10627            // a new system package, we allow the codepath to change from a system location
10628            // to the user-installed location. If we don't allow this change, any newer,
10629            // user-installed version of the application will be ignored.
10630            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10631                if (mExpectingBetter.containsKey(pkg.packageName)) {
10632                    logCriticalInfo(Log.WARN,
10633                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10634                } else {
10635                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10636                    if (known != null) {
10637                        if (DEBUG_PACKAGE_SCANNING) {
10638                            Log.d(TAG, "Examining " + pkg.codePath
10639                                    + " and requiring known paths " + known.codePathString
10640                                    + " & " + known.resourcePathString);
10641                        }
10642                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10643                                || !pkg.applicationInfo.getResourcePath().equals(
10644                                        known.resourcePathString)) {
10645                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10646                                    "Application package " + pkg.packageName
10647                                    + " found at " + pkg.applicationInfo.getCodePath()
10648                                    + " but expected at " + known.codePathString
10649                                    + "; ignoring.");
10650                        }
10651                    } else {
10652                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10653                                "Application package " + pkg.packageName
10654                                + " not found; ignoring.");
10655                    }
10656                }
10657            }
10658
10659            // Verify that this new package doesn't have any content providers
10660            // that conflict with existing packages.  Only do this if the
10661            // package isn't already installed, since we don't want to break
10662            // things that are installed.
10663            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10664                final int N = pkg.providers.size();
10665                int i;
10666                for (i=0; i<N; i++) {
10667                    PackageParser.Provider p = pkg.providers.get(i);
10668                    if (p.info.authority != null) {
10669                        String names[] = p.info.authority.split(";");
10670                        for (int j = 0; j < names.length; j++) {
10671                            if (mProvidersByAuthority.containsKey(names[j])) {
10672                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10673                                final String otherPackageName =
10674                                        ((other != null && other.getComponentName() != null) ?
10675                                                other.getComponentName().getPackageName() : "?");
10676                                throw new PackageManagerException(
10677                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10678                                        "Can't install because provider name " + names[j]
10679                                                + " (in package " + pkg.applicationInfo.packageName
10680                                                + ") is already used by " + otherPackageName);
10681                            }
10682                        }
10683                    }
10684                }
10685            }
10686        }
10687    }
10688
10689    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
10690            int type, String declaringPackageName, long declaringVersionCode) {
10691        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10692        if (versionedLib == null) {
10693            versionedLib = new LongSparseArray<>();
10694            mSharedLibraries.put(name, versionedLib);
10695            if (type == SharedLibraryInfo.TYPE_STATIC) {
10696                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10697            }
10698        } else if (versionedLib.indexOfKey(version) >= 0) {
10699            return false;
10700        }
10701        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10702                version, type, declaringPackageName, declaringVersionCode);
10703        versionedLib.put(version, libEntry);
10704        return true;
10705    }
10706
10707    private boolean removeSharedLibraryLPw(String name, long version) {
10708        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10709        if (versionedLib == null) {
10710            return false;
10711        }
10712        final int libIdx = versionedLib.indexOfKey(version);
10713        if (libIdx < 0) {
10714            return false;
10715        }
10716        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10717        versionedLib.remove(version);
10718        if (versionedLib.size() <= 0) {
10719            mSharedLibraries.remove(name);
10720            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10721                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10722                        .getPackageName());
10723            }
10724        }
10725        return true;
10726    }
10727
10728    /**
10729     * Adds a scanned package to the system. When this method is finished, the package will
10730     * be available for query, resolution, etc...
10731     */
10732    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10733            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
10734        final String pkgName = pkg.packageName;
10735        if (mCustomResolverComponentName != null &&
10736                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10737            setUpCustomResolverActivity(pkg);
10738        }
10739
10740        if (pkg.packageName.equals("android")) {
10741            synchronized (mPackages) {
10742                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10743                    // Set up information for our fall-back user intent resolution activity.
10744                    mPlatformPackage = pkg;
10745                    pkg.mVersionCode = mSdkVersion;
10746                    pkg.mVersionCodeMajor = 0;
10747                    mAndroidApplication = pkg.applicationInfo;
10748                    if (!mResolverReplaced) {
10749                        mResolveActivity.applicationInfo = mAndroidApplication;
10750                        mResolveActivity.name = ResolverActivity.class.getName();
10751                        mResolveActivity.packageName = mAndroidApplication.packageName;
10752                        mResolveActivity.processName = "system:ui";
10753                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10754                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10755                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10756                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10757                        mResolveActivity.exported = true;
10758                        mResolveActivity.enabled = true;
10759                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10760                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10761                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10762                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10763                                | ActivityInfo.CONFIG_ORIENTATION
10764                                | ActivityInfo.CONFIG_KEYBOARD
10765                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10766                        mResolveInfo.activityInfo = mResolveActivity;
10767                        mResolveInfo.priority = 0;
10768                        mResolveInfo.preferredOrder = 0;
10769                        mResolveInfo.match = 0;
10770                        mResolveComponentName = new ComponentName(
10771                                mAndroidApplication.packageName, mResolveActivity.name);
10772                    }
10773                }
10774            }
10775        }
10776
10777        ArrayList<PackageParser.Package> clientLibPkgs = null;
10778        // writer
10779        synchronized (mPackages) {
10780            boolean hasStaticSharedLibs = false;
10781
10782            // Any app can add new static shared libraries
10783            if (pkg.staticSharedLibName != null) {
10784                // Static shared libs don't allow renaming as they have synthetic package
10785                // names to allow install of multiple versions, so use name from manifest.
10786                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10787                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10788                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
10789                    hasStaticSharedLibs = true;
10790                } else {
10791                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10792                                + pkg.staticSharedLibName + " already exists; skipping");
10793                }
10794                // Static shared libs cannot be updated once installed since they
10795                // use synthetic package name which includes the version code, so
10796                // not need to update other packages's shared lib dependencies.
10797            }
10798
10799            if (!hasStaticSharedLibs
10800                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10801                // Only system apps can add new dynamic shared libraries.
10802                if (pkg.libraryNames != null) {
10803                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10804                        String name = pkg.libraryNames.get(i);
10805                        boolean allowed = false;
10806                        if (pkg.isUpdatedSystemApp()) {
10807                            // New library entries can only be added through the
10808                            // system image.  This is important to get rid of a lot
10809                            // of nasty edge cases: for example if we allowed a non-
10810                            // system update of the app to add a library, then uninstalling
10811                            // the update would make the library go away, and assumptions
10812                            // we made such as through app install filtering would now
10813                            // have allowed apps on the device which aren't compatible
10814                            // with it.  Better to just have the restriction here, be
10815                            // conservative, and create many fewer cases that can negatively
10816                            // impact the user experience.
10817                            final PackageSetting sysPs = mSettings
10818                                    .getDisabledSystemPkgLPr(pkg.packageName);
10819                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10820                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10821                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10822                                        allowed = true;
10823                                        break;
10824                                    }
10825                                }
10826                            }
10827                        } else {
10828                            allowed = true;
10829                        }
10830                        if (allowed) {
10831                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10832                                    SharedLibraryInfo.VERSION_UNDEFINED,
10833                                    SharedLibraryInfo.TYPE_DYNAMIC,
10834                                    pkg.packageName, pkg.getLongVersionCode())) {
10835                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10836                                        + name + " already exists; skipping");
10837                            }
10838                        } else {
10839                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10840                                    + name + " that is not declared on system image; skipping");
10841                        }
10842                    }
10843
10844                    if ((scanFlags & SCAN_BOOTING) == 0) {
10845                        // If we are not booting, we need to update any applications
10846                        // that are clients of our shared library.  If we are booting,
10847                        // this will all be done once the scan is complete.
10848                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10849                    }
10850                }
10851            }
10852        }
10853
10854        if ((scanFlags & SCAN_BOOTING) != 0) {
10855            // No apps can run during boot scan, so they don't need to be frozen
10856        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10857            // Caller asked to not kill app, so it's probably not frozen
10858        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10859            // Caller asked us to ignore frozen check for some reason; they
10860            // probably didn't know the package name
10861        } else {
10862            // We're doing major surgery on this package, so it better be frozen
10863            // right now to keep it from launching
10864            checkPackageFrozen(pkgName);
10865        }
10866
10867        // Also need to kill any apps that are dependent on the library.
10868        if (clientLibPkgs != null) {
10869            for (int i=0; i<clientLibPkgs.size(); i++) {
10870                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10871                killApplication(clientPkg.applicationInfo.packageName,
10872                        clientPkg.applicationInfo.uid, "update lib");
10873            }
10874        }
10875
10876        // writer
10877        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10878
10879        synchronized (mPackages) {
10880            // We don't expect installation to fail beyond this point
10881
10882            // Add the new setting to mSettings
10883            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10884            // Add the new setting to mPackages
10885            mPackages.put(pkg.applicationInfo.packageName, pkg);
10886            // Make sure we don't accidentally delete its data.
10887            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10888            while (iter.hasNext()) {
10889                PackageCleanItem item = iter.next();
10890                if (pkgName.equals(item.packageName)) {
10891                    iter.remove();
10892                }
10893            }
10894
10895            // Add the package's KeySets to the global KeySetManagerService
10896            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10897            ksms.addScannedPackageLPw(pkg);
10898
10899            int N = pkg.providers.size();
10900            StringBuilder r = null;
10901            int i;
10902            for (i=0; i<N; i++) {
10903                PackageParser.Provider p = pkg.providers.get(i);
10904                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10905                        p.info.processName);
10906                mProviders.addProvider(p);
10907                p.syncable = p.info.isSyncable;
10908                if (p.info.authority != null) {
10909                    String names[] = p.info.authority.split(";");
10910                    p.info.authority = null;
10911                    for (int j = 0; j < names.length; j++) {
10912                        if (j == 1 && p.syncable) {
10913                            // We only want the first authority for a provider to possibly be
10914                            // syncable, so if we already added this provider using a different
10915                            // authority clear the syncable flag. We copy the provider before
10916                            // changing it because the mProviders object contains a reference
10917                            // to a provider that we don't want to change.
10918                            // Only do this for the second authority since the resulting provider
10919                            // object can be the same for all future authorities for this provider.
10920                            p = new PackageParser.Provider(p);
10921                            p.syncable = false;
10922                        }
10923                        if (!mProvidersByAuthority.containsKey(names[j])) {
10924                            mProvidersByAuthority.put(names[j], p);
10925                            if (p.info.authority == null) {
10926                                p.info.authority = names[j];
10927                            } else {
10928                                p.info.authority = p.info.authority + ";" + names[j];
10929                            }
10930                            if (DEBUG_PACKAGE_SCANNING) {
10931                                if (chatty)
10932                                    Log.d(TAG, "Registered content provider: " + names[j]
10933                                            + ", className = " + p.info.name + ", isSyncable = "
10934                                            + p.info.isSyncable);
10935                            }
10936                        } else {
10937                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10938                            Slog.w(TAG, "Skipping provider name " + names[j] +
10939                                    " (in package " + pkg.applicationInfo.packageName +
10940                                    "): name already used by "
10941                                    + ((other != null && other.getComponentName() != null)
10942                                            ? other.getComponentName().getPackageName() : "?"));
10943                        }
10944                    }
10945                }
10946                if (chatty) {
10947                    if (r == null) {
10948                        r = new StringBuilder(256);
10949                    } else {
10950                        r.append(' ');
10951                    }
10952                    r.append(p.info.name);
10953                }
10954            }
10955            if (r != null) {
10956                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10957            }
10958
10959            N = pkg.services.size();
10960            r = null;
10961            for (i=0; i<N; i++) {
10962                PackageParser.Service s = pkg.services.get(i);
10963                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10964                        s.info.processName);
10965                mServices.addService(s);
10966                if (chatty) {
10967                    if (r == null) {
10968                        r = new StringBuilder(256);
10969                    } else {
10970                        r.append(' ');
10971                    }
10972                    r.append(s.info.name);
10973                }
10974            }
10975            if (r != null) {
10976                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10977            }
10978
10979            N = pkg.receivers.size();
10980            r = null;
10981            for (i=0; i<N; i++) {
10982                PackageParser.Activity a = pkg.receivers.get(i);
10983                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10984                        a.info.processName);
10985                mReceivers.addActivity(a, "receiver");
10986                if (chatty) {
10987                    if (r == null) {
10988                        r = new StringBuilder(256);
10989                    } else {
10990                        r.append(' ');
10991                    }
10992                    r.append(a.info.name);
10993                }
10994            }
10995            if (r != null) {
10996                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10997            }
10998
10999            N = pkg.activities.size();
11000            r = null;
11001            for (i=0; i<N; i++) {
11002                PackageParser.Activity a = pkg.activities.get(i);
11003                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11004                        a.info.processName);
11005                mActivities.addActivity(a, "activity");
11006                if (chatty) {
11007                    if (r == null) {
11008                        r = new StringBuilder(256);
11009                    } else {
11010                        r.append(' ');
11011                    }
11012                    r.append(a.info.name);
11013                }
11014            }
11015            if (r != null) {
11016                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11017            }
11018
11019            // Don't allow ephemeral applications to define new permissions groups.
11020            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11021                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11022                        + " ignored: instant apps cannot define new permission groups.");
11023            } else {
11024                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11025            }
11026
11027            // Don't allow ephemeral applications to define new permissions.
11028            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11029                Slog.w(TAG, "Permissions from package " + pkg.packageName
11030                        + " ignored: instant apps cannot define new permissions.");
11031            } else {
11032                mPermissionManager.addAllPermissions(pkg, chatty);
11033            }
11034
11035            N = pkg.instrumentation.size();
11036            r = null;
11037            for (i=0; i<N; i++) {
11038                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11039                a.info.packageName = pkg.applicationInfo.packageName;
11040                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11041                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11042                a.info.splitNames = pkg.splitNames;
11043                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11044                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11045                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11046                a.info.dataDir = pkg.applicationInfo.dataDir;
11047                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11048                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11049                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11050                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11051                mInstrumentation.put(a.getComponentName(), a);
11052                if (chatty) {
11053                    if (r == null) {
11054                        r = new StringBuilder(256);
11055                    } else {
11056                        r.append(' ');
11057                    }
11058                    r.append(a.info.name);
11059                }
11060            }
11061            if (r != null) {
11062                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11063            }
11064
11065            if (pkg.protectedBroadcasts != null) {
11066                N = pkg.protectedBroadcasts.size();
11067                synchronized (mProtectedBroadcasts) {
11068                    for (i = 0; i < N; i++) {
11069                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11070                    }
11071                }
11072            }
11073        }
11074
11075        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11076    }
11077
11078    /**
11079     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11080     * is derived purely on the basis of the contents of {@code scanFile} and
11081     * {@code cpuAbiOverride}.
11082     *
11083     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11084     */
11085    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11086            boolean extractLibs)
11087                    throws PackageManagerException {
11088        // Give ourselves some initial paths; we'll come back for another
11089        // pass once we've determined ABI below.
11090        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11091
11092        // We would never need to extract libs for forward-locked and external packages,
11093        // since the container service will do it for us. We shouldn't attempt to
11094        // extract libs from system app when it was not updated.
11095        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11096                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11097            extractLibs = false;
11098        }
11099
11100        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11101        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11102
11103        NativeLibraryHelper.Handle handle = null;
11104        try {
11105            handle = NativeLibraryHelper.Handle.create(pkg);
11106            // TODO(multiArch): This can be null for apps that didn't go through the
11107            // usual installation process. We can calculate it again, like we
11108            // do during install time.
11109            //
11110            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11111            // unnecessary.
11112            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11113
11114            // Null out the abis so that they can be recalculated.
11115            pkg.applicationInfo.primaryCpuAbi = null;
11116            pkg.applicationInfo.secondaryCpuAbi = null;
11117            if (isMultiArch(pkg.applicationInfo)) {
11118                // Warn if we've set an abiOverride for multi-lib packages..
11119                // By definition, we need to copy both 32 and 64 bit libraries for
11120                // such packages.
11121                if (pkg.cpuAbiOverride != null
11122                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11123                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11124                }
11125
11126                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11127                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11128                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11129                    if (extractLibs) {
11130                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11131                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11132                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11133                                useIsaSpecificSubdirs);
11134                    } else {
11135                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11136                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11137                    }
11138                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11139                }
11140
11141                // Shared library native code should be in the APK zip aligned
11142                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11143                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11144                            "Shared library native lib extraction not supported");
11145                }
11146
11147                maybeThrowExceptionForMultiArchCopy(
11148                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11149
11150                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11151                    if (extractLibs) {
11152                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11153                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11154                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11155                                useIsaSpecificSubdirs);
11156                    } else {
11157                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11158                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11159                    }
11160                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11161                }
11162
11163                maybeThrowExceptionForMultiArchCopy(
11164                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11165
11166                if (abi64 >= 0) {
11167                    // Shared library native libs should be in the APK zip aligned
11168                    if (extractLibs && pkg.isLibrary()) {
11169                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11170                                "Shared library native lib extraction not supported");
11171                    }
11172                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11173                }
11174
11175                if (abi32 >= 0) {
11176                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11177                    if (abi64 >= 0) {
11178                        if (pkg.use32bitAbi) {
11179                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11180                            pkg.applicationInfo.primaryCpuAbi = abi;
11181                        } else {
11182                            pkg.applicationInfo.secondaryCpuAbi = abi;
11183                        }
11184                    } else {
11185                        pkg.applicationInfo.primaryCpuAbi = abi;
11186                    }
11187                }
11188            } else {
11189                String[] abiList = (cpuAbiOverride != null) ?
11190                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11191
11192                // Enable gross and lame hacks for apps that are built with old
11193                // SDK tools. We must scan their APKs for renderscript bitcode and
11194                // not launch them if it's present. Don't bother checking on devices
11195                // that don't have 64 bit support.
11196                boolean needsRenderScriptOverride = false;
11197                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11198                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11199                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11200                    needsRenderScriptOverride = true;
11201                }
11202
11203                final int copyRet;
11204                if (extractLibs) {
11205                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11206                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11207                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11208                } else {
11209                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11210                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11211                }
11212                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11213
11214                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11215                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11216                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11217                }
11218
11219                if (copyRet >= 0) {
11220                    // Shared libraries that have native libs must be multi-architecture
11221                    if (pkg.isLibrary()) {
11222                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11223                                "Shared library with native libs must be multiarch");
11224                    }
11225                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11226                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11227                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11228                } else if (needsRenderScriptOverride) {
11229                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11230                }
11231            }
11232        } catch (IOException ioe) {
11233            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11234        } finally {
11235            IoUtils.closeQuietly(handle);
11236        }
11237
11238        // Now that we've calculated the ABIs and determined if it's an internal app,
11239        // we will go ahead and populate the nativeLibraryPath.
11240        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11241    }
11242
11243    /**
11244     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11245     * i.e, so that all packages can be run inside a single process if required.
11246     *
11247     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11248     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11249     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11250     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11251     * updating a package that belongs to a shared user.
11252     *
11253     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11254     * adds unnecessary complexity.
11255     */
11256    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11257            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11258        List<String> changedAbiCodePath = null;
11259        String requiredInstructionSet = null;
11260        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11261            requiredInstructionSet = VMRuntime.getInstructionSet(
11262                     scannedPackage.applicationInfo.primaryCpuAbi);
11263        }
11264
11265        PackageSetting requirer = null;
11266        for (PackageSetting ps : packagesForUser) {
11267            // If packagesForUser contains scannedPackage, we skip it. This will happen
11268            // when scannedPackage is an update of an existing package. Without this check,
11269            // we will never be able to change the ABI of any package belonging to a shared
11270            // user, even if it's compatible with other packages.
11271            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11272                if (ps.primaryCpuAbiString == null) {
11273                    continue;
11274                }
11275
11276                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11277                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11278                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11279                    // this but there's not much we can do.
11280                    String errorMessage = "Instruction set mismatch, "
11281                            + ((requirer == null) ? "[caller]" : requirer)
11282                            + " requires " + requiredInstructionSet + " whereas " + ps
11283                            + " requires " + instructionSet;
11284                    Slog.w(TAG, errorMessage);
11285                }
11286
11287                if (requiredInstructionSet == null) {
11288                    requiredInstructionSet = instructionSet;
11289                    requirer = ps;
11290                }
11291            }
11292        }
11293
11294        if (requiredInstructionSet != null) {
11295            String adjustedAbi;
11296            if (requirer != null) {
11297                // requirer != null implies that either scannedPackage was null or that scannedPackage
11298                // did not require an ABI, in which case we have to adjust scannedPackage to match
11299                // the ABI of the set (which is the same as requirer's ABI)
11300                adjustedAbi = requirer.primaryCpuAbiString;
11301                if (scannedPackage != null) {
11302                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11303                }
11304            } else {
11305                // requirer == null implies that we're updating all ABIs in the set to
11306                // match scannedPackage.
11307                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11308            }
11309
11310            for (PackageSetting ps : packagesForUser) {
11311                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11312                    if (ps.primaryCpuAbiString != null) {
11313                        continue;
11314                    }
11315
11316                    ps.primaryCpuAbiString = adjustedAbi;
11317                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11318                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11319                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11320                        if (DEBUG_ABI_SELECTION) {
11321                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11322                                    + " (requirer="
11323                                    + (requirer != null ? requirer.pkg : "null")
11324                                    + ", scannedPackage="
11325                                    + (scannedPackage != null ? scannedPackage : "null")
11326                                    + ")");
11327                        }
11328                        if (changedAbiCodePath == null) {
11329                            changedAbiCodePath = new ArrayList<>();
11330                        }
11331                        changedAbiCodePath.add(ps.codePathString);
11332                    }
11333                }
11334            }
11335        }
11336        return changedAbiCodePath;
11337    }
11338
11339    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11340        synchronized (mPackages) {
11341            mResolverReplaced = true;
11342            // Set up information for custom user intent resolution activity.
11343            mResolveActivity.applicationInfo = pkg.applicationInfo;
11344            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11345            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11346            mResolveActivity.processName = pkg.applicationInfo.packageName;
11347            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11348            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11349                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11350            mResolveActivity.theme = 0;
11351            mResolveActivity.exported = true;
11352            mResolveActivity.enabled = true;
11353            mResolveInfo.activityInfo = mResolveActivity;
11354            mResolveInfo.priority = 0;
11355            mResolveInfo.preferredOrder = 0;
11356            mResolveInfo.match = 0;
11357            mResolveComponentName = mCustomResolverComponentName;
11358            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11359                    mResolveComponentName);
11360        }
11361    }
11362
11363    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11364        if (installerActivity == null) {
11365            if (DEBUG_EPHEMERAL) {
11366                Slog.d(TAG, "Clear ephemeral installer activity");
11367            }
11368            mInstantAppInstallerActivity = null;
11369            return;
11370        }
11371
11372        if (DEBUG_EPHEMERAL) {
11373            Slog.d(TAG, "Set ephemeral installer activity: "
11374                    + installerActivity.getComponentName());
11375        }
11376        // Set up information for ephemeral installer activity
11377        mInstantAppInstallerActivity = installerActivity;
11378        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11379                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11380        mInstantAppInstallerActivity.exported = true;
11381        mInstantAppInstallerActivity.enabled = true;
11382        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11383        mInstantAppInstallerInfo.priority = 0;
11384        mInstantAppInstallerInfo.preferredOrder = 1;
11385        mInstantAppInstallerInfo.isDefault = true;
11386        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11387                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11388    }
11389
11390    private static String calculateBundledApkRoot(final String codePathString) {
11391        final File codePath = new File(codePathString);
11392        final File codeRoot;
11393        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11394            codeRoot = Environment.getRootDirectory();
11395        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11396            codeRoot = Environment.getOemDirectory();
11397        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11398            codeRoot = Environment.getVendorDirectory();
11399        } else {
11400            // Unrecognized code path; take its top real segment as the apk root:
11401            // e.g. /something/app/blah.apk => /something
11402            try {
11403                File f = codePath.getCanonicalFile();
11404                File parent = f.getParentFile();    // non-null because codePath is a file
11405                File tmp;
11406                while ((tmp = parent.getParentFile()) != null) {
11407                    f = parent;
11408                    parent = tmp;
11409                }
11410                codeRoot = f;
11411                Slog.w(TAG, "Unrecognized code path "
11412                        + codePath + " - using " + codeRoot);
11413            } catch (IOException e) {
11414                // Can't canonicalize the code path -- shenanigans?
11415                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11416                return Environment.getRootDirectory().getPath();
11417            }
11418        }
11419        return codeRoot.getPath();
11420    }
11421
11422    /**
11423     * Derive and set the location of native libraries for the given package,
11424     * which varies depending on where and how the package was installed.
11425     */
11426    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11427        final ApplicationInfo info = pkg.applicationInfo;
11428        final String codePath = pkg.codePath;
11429        final File codeFile = new File(codePath);
11430        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11431        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11432
11433        info.nativeLibraryRootDir = null;
11434        info.nativeLibraryRootRequiresIsa = false;
11435        info.nativeLibraryDir = null;
11436        info.secondaryNativeLibraryDir = null;
11437
11438        if (isApkFile(codeFile)) {
11439            // Monolithic install
11440            if (bundledApp) {
11441                // If "/system/lib64/apkname" exists, assume that is the per-package
11442                // native library directory to use; otherwise use "/system/lib/apkname".
11443                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11444                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11445                        getPrimaryInstructionSet(info));
11446
11447                // This is a bundled system app so choose the path based on the ABI.
11448                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11449                // is just the default path.
11450                final String apkName = deriveCodePathName(codePath);
11451                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11452                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11453                        apkName).getAbsolutePath();
11454
11455                if (info.secondaryCpuAbi != null) {
11456                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11457                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11458                            secondaryLibDir, apkName).getAbsolutePath();
11459                }
11460            } else if (asecApp) {
11461                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11462                        .getAbsolutePath();
11463            } else {
11464                final String apkName = deriveCodePathName(codePath);
11465                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11466                        .getAbsolutePath();
11467            }
11468
11469            info.nativeLibraryRootRequiresIsa = false;
11470            info.nativeLibraryDir = info.nativeLibraryRootDir;
11471        } else {
11472            // Cluster install
11473            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11474            info.nativeLibraryRootRequiresIsa = true;
11475
11476            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11477                    getPrimaryInstructionSet(info)).getAbsolutePath();
11478
11479            if (info.secondaryCpuAbi != null) {
11480                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11481                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11482            }
11483        }
11484    }
11485
11486    /**
11487     * Calculate the abis and roots for a bundled app. These can uniquely
11488     * be determined from the contents of the system partition, i.e whether
11489     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11490     * of this information, and instead assume that the system was built
11491     * sensibly.
11492     */
11493    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11494                                           PackageSetting pkgSetting) {
11495        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11496
11497        // If "/system/lib64/apkname" exists, assume that is the per-package
11498        // native library directory to use; otherwise use "/system/lib/apkname".
11499        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11500        setBundledAppAbi(pkg, apkRoot, apkName);
11501        // pkgSetting might be null during rescan following uninstall of updates
11502        // to a bundled app, so accommodate that possibility.  The settings in
11503        // that case will be established later from the parsed package.
11504        //
11505        // If the settings aren't null, sync them up with what we've just derived.
11506        // note that apkRoot isn't stored in the package settings.
11507        if (pkgSetting != null) {
11508            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11509            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11510        }
11511    }
11512
11513    /**
11514     * Deduces the ABI of a bundled app and sets the relevant fields on the
11515     * parsed pkg object.
11516     *
11517     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11518     *        under which system libraries are installed.
11519     * @param apkName the name of the installed package.
11520     */
11521    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11522        final File codeFile = new File(pkg.codePath);
11523
11524        final boolean has64BitLibs;
11525        final boolean has32BitLibs;
11526        if (isApkFile(codeFile)) {
11527            // Monolithic install
11528            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11529            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11530        } else {
11531            // Cluster install
11532            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11533            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11534                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11535                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11536                has64BitLibs = (new File(rootDir, isa)).exists();
11537            } else {
11538                has64BitLibs = false;
11539            }
11540            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11541                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11542                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11543                has32BitLibs = (new File(rootDir, isa)).exists();
11544            } else {
11545                has32BitLibs = false;
11546            }
11547        }
11548
11549        if (has64BitLibs && !has32BitLibs) {
11550            // The package has 64 bit libs, but not 32 bit libs. Its primary
11551            // ABI should be 64 bit. We can safely assume here that the bundled
11552            // native libraries correspond to the most preferred ABI in the list.
11553
11554            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11555            pkg.applicationInfo.secondaryCpuAbi = null;
11556        } else if (has32BitLibs && !has64BitLibs) {
11557            // The package has 32 bit libs but not 64 bit libs. Its primary
11558            // ABI should be 32 bit.
11559
11560            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11561            pkg.applicationInfo.secondaryCpuAbi = null;
11562        } else if (has32BitLibs && has64BitLibs) {
11563            // The application has both 64 and 32 bit bundled libraries. We check
11564            // here that the app declares multiArch support, and warn if it doesn't.
11565            //
11566            // We will be lenient here and record both ABIs. The primary will be the
11567            // ABI that's higher on the list, i.e, a device that's configured to prefer
11568            // 64 bit apps will see a 64 bit primary ABI,
11569
11570            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11571                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11572            }
11573
11574            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11575                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11576                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11577            } else {
11578                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11579                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11580            }
11581        } else {
11582            pkg.applicationInfo.primaryCpuAbi = null;
11583            pkg.applicationInfo.secondaryCpuAbi = null;
11584        }
11585    }
11586
11587    private void killApplication(String pkgName, int appId, String reason) {
11588        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11589    }
11590
11591    private void killApplication(String pkgName, int appId, int userId, String reason) {
11592        // Request the ActivityManager to kill the process(only for existing packages)
11593        // so that we do not end up in a confused state while the user is still using the older
11594        // version of the application while the new one gets installed.
11595        final long token = Binder.clearCallingIdentity();
11596        try {
11597            IActivityManager am = ActivityManager.getService();
11598            if (am != null) {
11599                try {
11600                    am.killApplication(pkgName, appId, userId, reason);
11601                } catch (RemoteException e) {
11602                }
11603            }
11604        } finally {
11605            Binder.restoreCallingIdentity(token);
11606        }
11607    }
11608
11609    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11610        // Remove the parent package setting
11611        PackageSetting ps = (PackageSetting) pkg.mExtras;
11612        if (ps != null) {
11613            removePackageLI(ps, chatty);
11614        }
11615        // Remove the child package setting
11616        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11617        for (int i = 0; i < childCount; i++) {
11618            PackageParser.Package childPkg = pkg.childPackages.get(i);
11619            ps = (PackageSetting) childPkg.mExtras;
11620            if (ps != null) {
11621                removePackageLI(ps, chatty);
11622            }
11623        }
11624    }
11625
11626    void removePackageLI(PackageSetting ps, boolean chatty) {
11627        if (DEBUG_INSTALL) {
11628            if (chatty)
11629                Log.d(TAG, "Removing package " + ps.name);
11630        }
11631
11632        // writer
11633        synchronized (mPackages) {
11634            mPackages.remove(ps.name);
11635            final PackageParser.Package pkg = ps.pkg;
11636            if (pkg != null) {
11637                cleanPackageDataStructuresLILPw(pkg, chatty);
11638            }
11639        }
11640    }
11641
11642    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11643        if (DEBUG_INSTALL) {
11644            if (chatty)
11645                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11646        }
11647
11648        // writer
11649        synchronized (mPackages) {
11650            // Remove the parent package
11651            mPackages.remove(pkg.applicationInfo.packageName);
11652            cleanPackageDataStructuresLILPw(pkg, chatty);
11653
11654            // Remove the child packages
11655            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11656            for (int i = 0; i < childCount; i++) {
11657                PackageParser.Package childPkg = pkg.childPackages.get(i);
11658                mPackages.remove(childPkg.applicationInfo.packageName);
11659                cleanPackageDataStructuresLILPw(childPkg, chatty);
11660            }
11661        }
11662    }
11663
11664    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11665        int N = pkg.providers.size();
11666        StringBuilder r = null;
11667        int i;
11668        for (i=0; i<N; i++) {
11669            PackageParser.Provider p = pkg.providers.get(i);
11670            mProviders.removeProvider(p);
11671            if (p.info.authority == null) {
11672
11673                /* There was another ContentProvider with this authority when
11674                 * this app was installed so this authority is null,
11675                 * Ignore it as we don't have to unregister the provider.
11676                 */
11677                continue;
11678            }
11679            String names[] = p.info.authority.split(";");
11680            for (int j = 0; j < names.length; j++) {
11681                if (mProvidersByAuthority.get(names[j]) == p) {
11682                    mProvidersByAuthority.remove(names[j]);
11683                    if (DEBUG_REMOVE) {
11684                        if (chatty)
11685                            Log.d(TAG, "Unregistered content provider: " + names[j]
11686                                    + ", className = " + p.info.name + ", isSyncable = "
11687                                    + p.info.isSyncable);
11688                    }
11689                }
11690            }
11691            if (DEBUG_REMOVE && chatty) {
11692                if (r == null) {
11693                    r = new StringBuilder(256);
11694                } else {
11695                    r.append(' ');
11696                }
11697                r.append(p.info.name);
11698            }
11699        }
11700        if (r != null) {
11701            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11702        }
11703
11704        N = pkg.services.size();
11705        r = null;
11706        for (i=0; i<N; i++) {
11707            PackageParser.Service s = pkg.services.get(i);
11708            mServices.removeService(s);
11709            if (chatty) {
11710                if (r == null) {
11711                    r = new StringBuilder(256);
11712                } else {
11713                    r.append(' ');
11714                }
11715                r.append(s.info.name);
11716            }
11717        }
11718        if (r != null) {
11719            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11720        }
11721
11722        N = pkg.receivers.size();
11723        r = null;
11724        for (i=0; i<N; i++) {
11725            PackageParser.Activity a = pkg.receivers.get(i);
11726            mReceivers.removeActivity(a, "receiver");
11727            if (DEBUG_REMOVE && chatty) {
11728                if (r == null) {
11729                    r = new StringBuilder(256);
11730                } else {
11731                    r.append(' ');
11732                }
11733                r.append(a.info.name);
11734            }
11735        }
11736        if (r != null) {
11737            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11738        }
11739
11740        N = pkg.activities.size();
11741        r = null;
11742        for (i=0; i<N; i++) {
11743            PackageParser.Activity a = pkg.activities.get(i);
11744            mActivities.removeActivity(a, "activity");
11745            if (DEBUG_REMOVE && chatty) {
11746                if (r == null) {
11747                    r = new StringBuilder(256);
11748                } else {
11749                    r.append(' ');
11750                }
11751                r.append(a.info.name);
11752            }
11753        }
11754        if (r != null) {
11755            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11756        }
11757
11758        mPermissionManager.removeAllPermissions(pkg, chatty);
11759
11760        N = pkg.instrumentation.size();
11761        r = null;
11762        for (i=0; i<N; i++) {
11763            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11764            mInstrumentation.remove(a.getComponentName());
11765            if (DEBUG_REMOVE && chatty) {
11766                if (r == null) {
11767                    r = new StringBuilder(256);
11768                } else {
11769                    r.append(' ');
11770                }
11771                r.append(a.info.name);
11772            }
11773        }
11774        if (r != null) {
11775            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11776        }
11777
11778        r = null;
11779        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11780            // Only system apps can hold shared libraries.
11781            if (pkg.libraryNames != null) {
11782                for (i = 0; i < pkg.libraryNames.size(); i++) {
11783                    String name = pkg.libraryNames.get(i);
11784                    if (removeSharedLibraryLPw(name, 0)) {
11785                        if (DEBUG_REMOVE && chatty) {
11786                            if (r == null) {
11787                                r = new StringBuilder(256);
11788                            } else {
11789                                r.append(' ');
11790                            }
11791                            r.append(name);
11792                        }
11793                    }
11794                }
11795            }
11796        }
11797
11798        r = null;
11799
11800        // Any package can hold static shared libraries.
11801        if (pkg.staticSharedLibName != null) {
11802            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11803                if (DEBUG_REMOVE && chatty) {
11804                    if (r == null) {
11805                        r = new StringBuilder(256);
11806                    } else {
11807                        r.append(' ');
11808                    }
11809                    r.append(pkg.staticSharedLibName);
11810                }
11811            }
11812        }
11813
11814        if (r != null) {
11815            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11816        }
11817    }
11818
11819
11820    final class ActivityIntentResolver
11821            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11822        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11823                boolean defaultOnly, int userId) {
11824            if (!sUserManager.exists(userId)) return null;
11825            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11826            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11827        }
11828
11829        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11830                int userId) {
11831            if (!sUserManager.exists(userId)) return null;
11832            mFlags = flags;
11833            return super.queryIntent(intent, resolvedType,
11834                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11835                    userId);
11836        }
11837
11838        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11839                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11840            if (!sUserManager.exists(userId)) return null;
11841            if (packageActivities == null) {
11842                return null;
11843            }
11844            mFlags = flags;
11845            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11846            final int N = packageActivities.size();
11847            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11848                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11849
11850            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11851            for (int i = 0; i < N; ++i) {
11852                intentFilters = packageActivities.get(i).intents;
11853                if (intentFilters != null && intentFilters.size() > 0) {
11854                    PackageParser.ActivityIntentInfo[] array =
11855                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
11856                    intentFilters.toArray(array);
11857                    listCut.add(array);
11858                }
11859            }
11860            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11861        }
11862
11863        /**
11864         * Finds a privileged activity that matches the specified activity names.
11865         */
11866        private PackageParser.Activity findMatchingActivity(
11867                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
11868            for (PackageParser.Activity sysActivity : activityList) {
11869                if (sysActivity.info.name.equals(activityInfo.name)) {
11870                    return sysActivity;
11871                }
11872                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
11873                    return sysActivity;
11874                }
11875                if (sysActivity.info.targetActivity != null) {
11876                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
11877                        return sysActivity;
11878                    }
11879                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
11880                        return sysActivity;
11881                    }
11882                }
11883            }
11884            return null;
11885        }
11886
11887        public class IterGenerator<E> {
11888            public Iterator<E> generate(ActivityIntentInfo info) {
11889                return null;
11890            }
11891        }
11892
11893        public class ActionIterGenerator extends IterGenerator<String> {
11894            @Override
11895            public Iterator<String> generate(ActivityIntentInfo info) {
11896                return info.actionsIterator();
11897            }
11898        }
11899
11900        public class CategoriesIterGenerator extends IterGenerator<String> {
11901            @Override
11902            public Iterator<String> generate(ActivityIntentInfo info) {
11903                return info.categoriesIterator();
11904            }
11905        }
11906
11907        public class SchemesIterGenerator extends IterGenerator<String> {
11908            @Override
11909            public Iterator<String> generate(ActivityIntentInfo info) {
11910                return info.schemesIterator();
11911            }
11912        }
11913
11914        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
11915            @Override
11916            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
11917                return info.authoritiesIterator();
11918            }
11919        }
11920
11921        /**
11922         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
11923         * MODIFIED. Do not pass in a list that should not be changed.
11924         */
11925        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
11926                IterGenerator<T> generator, Iterator<T> searchIterator) {
11927            // loop through the set of actions; every one must be found in the intent filter
11928            while (searchIterator.hasNext()) {
11929                // we must have at least one filter in the list to consider a match
11930                if (intentList.size() == 0) {
11931                    break;
11932                }
11933
11934                final T searchAction = searchIterator.next();
11935
11936                // loop through the set of intent filters
11937                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
11938                while (intentIter.hasNext()) {
11939                    final ActivityIntentInfo intentInfo = intentIter.next();
11940                    boolean selectionFound = false;
11941
11942                    // loop through the intent filter's selection criteria; at least one
11943                    // of them must match the searched criteria
11944                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
11945                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
11946                        final T intentSelection = intentSelectionIter.next();
11947                        if (intentSelection != null && intentSelection.equals(searchAction)) {
11948                            selectionFound = true;
11949                            break;
11950                        }
11951                    }
11952
11953                    // the selection criteria wasn't found in this filter's set; this filter
11954                    // is not a potential match
11955                    if (!selectionFound) {
11956                        intentIter.remove();
11957                    }
11958                }
11959            }
11960        }
11961
11962        private boolean isProtectedAction(ActivityIntentInfo filter) {
11963            final Iterator<String> actionsIter = filter.actionsIterator();
11964            while (actionsIter != null && actionsIter.hasNext()) {
11965                final String filterAction = actionsIter.next();
11966                if (PROTECTED_ACTIONS.contains(filterAction)) {
11967                    return true;
11968                }
11969            }
11970            return false;
11971        }
11972
11973        /**
11974         * Adjusts the priority of the given intent filter according to policy.
11975         * <p>
11976         * <ul>
11977         * <li>The priority for non privileged applications is capped to '0'</li>
11978         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
11979         * <li>The priority for unbundled updates to privileged applications is capped to the
11980         *      priority defined on the system partition</li>
11981         * </ul>
11982         * <p>
11983         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
11984         * allowed to obtain any priority on any action.
11985         */
11986        private void adjustPriority(
11987                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
11988            // nothing to do; priority is fine as-is
11989            if (intent.getPriority() <= 0) {
11990                return;
11991            }
11992
11993            final ActivityInfo activityInfo = intent.activity.info;
11994            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
11995
11996            final boolean privilegedApp =
11997                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
11998            if (!privilegedApp) {
11999                // non-privileged applications can never define a priority >0
12000                if (DEBUG_FILTERS) {
12001                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12002                            + " package: " + applicationInfo.packageName
12003                            + " activity: " + intent.activity.className
12004                            + " origPrio: " + intent.getPriority());
12005                }
12006                intent.setPriority(0);
12007                return;
12008            }
12009
12010            if (systemActivities == null) {
12011                // the system package is not disabled; we're parsing the system partition
12012                if (isProtectedAction(intent)) {
12013                    if (mDeferProtectedFilters) {
12014                        // We can't deal with these just yet. No component should ever obtain a
12015                        // >0 priority for a protected actions, with ONE exception -- the setup
12016                        // wizard. The setup wizard, however, cannot be known until we're able to
12017                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12018                        // until all intent filters have been processed. Chicken, meet egg.
12019                        // Let the filter temporarily have a high priority and rectify the
12020                        // priorities after all system packages have been scanned.
12021                        mProtectedFilters.add(intent);
12022                        if (DEBUG_FILTERS) {
12023                            Slog.i(TAG, "Protected action; save for later;"
12024                                    + " package: " + applicationInfo.packageName
12025                                    + " activity: " + intent.activity.className
12026                                    + " origPrio: " + intent.getPriority());
12027                        }
12028                        return;
12029                    } else {
12030                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12031                            Slog.i(TAG, "No setup wizard;"
12032                                + " All protected intents capped to priority 0");
12033                        }
12034                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12035                            if (DEBUG_FILTERS) {
12036                                Slog.i(TAG, "Found setup wizard;"
12037                                    + " allow priority " + intent.getPriority() + ";"
12038                                    + " package: " + intent.activity.info.packageName
12039                                    + " activity: " + intent.activity.className
12040                                    + " priority: " + intent.getPriority());
12041                            }
12042                            // setup wizard gets whatever it wants
12043                            return;
12044                        }
12045                        if (DEBUG_FILTERS) {
12046                            Slog.i(TAG, "Protected action; cap priority to 0;"
12047                                    + " package: " + intent.activity.info.packageName
12048                                    + " activity: " + intent.activity.className
12049                                    + " origPrio: " + intent.getPriority());
12050                        }
12051                        intent.setPriority(0);
12052                        return;
12053                    }
12054                }
12055                // privileged apps on the system image get whatever priority they request
12056                return;
12057            }
12058
12059            // privileged app unbundled update ... try to find the same activity
12060            final PackageParser.Activity foundActivity =
12061                    findMatchingActivity(systemActivities, activityInfo);
12062            if (foundActivity == null) {
12063                // this is a new activity; it cannot obtain >0 priority
12064                if (DEBUG_FILTERS) {
12065                    Slog.i(TAG, "New activity; cap priority to 0;"
12066                            + " package: " + applicationInfo.packageName
12067                            + " activity: " + intent.activity.className
12068                            + " origPrio: " + intent.getPriority());
12069                }
12070                intent.setPriority(0);
12071                return;
12072            }
12073
12074            // found activity, now check for filter equivalence
12075
12076            // a shallow copy is enough; we modify the list, not its contents
12077            final List<ActivityIntentInfo> intentListCopy =
12078                    new ArrayList<>(foundActivity.intents);
12079            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12080
12081            // find matching action subsets
12082            final Iterator<String> actionsIterator = intent.actionsIterator();
12083            if (actionsIterator != null) {
12084                getIntentListSubset(
12085                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12086                if (intentListCopy.size() == 0) {
12087                    // no more intents to match; we're not equivalent
12088                    if (DEBUG_FILTERS) {
12089                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12090                                + " package: " + applicationInfo.packageName
12091                                + " activity: " + intent.activity.className
12092                                + " origPrio: " + intent.getPriority());
12093                    }
12094                    intent.setPriority(0);
12095                    return;
12096                }
12097            }
12098
12099            // find matching category subsets
12100            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12101            if (categoriesIterator != null) {
12102                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12103                        categoriesIterator);
12104                if (intentListCopy.size() == 0) {
12105                    // no more intents to match; we're not equivalent
12106                    if (DEBUG_FILTERS) {
12107                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12108                                + " package: " + applicationInfo.packageName
12109                                + " activity: " + intent.activity.className
12110                                + " origPrio: " + intent.getPriority());
12111                    }
12112                    intent.setPriority(0);
12113                    return;
12114                }
12115            }
12116
12117            // find matching schemes subsets
12118            final Iterator<String> schemesIterator = intent.schemesIterator();
12119            if (schemesIterator != null) {
12120                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12121                        schemesIterator);
12122                if (intentListCopy.size() == 0) {
12123                    // no more intents to match; we're not equivalent
12124                    if (DEBUG_FILTERS) {
12125                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12126                                + " package: " + applicationInfo.packageName
12127                                + " activity: " + intent.activity.className
12128                                + " origPrio: " + intent.getPriority());
12129                    }
12130                    intent.setPriority(0);
12131                    return;
12132                }
12133            }
12134
12135            // find matching authorities subsets
12136            final Iterator<IntentFilter.AuthorityEntry>
12137                    authoritiesIterator = intent.authoritiesIterator();
12138            if (authoritiesIterator != null) {
12139                getIntentListSubset(intentListCopy,
12140                        new AuthoritiesIterGenerator(),
12141                        authoritiesIterator);
12142                if (intentListCopy.size() == 0) {
12143                    // no more intents to match; we're not equivalent
12144                    if (DEBUG_FILTERS) {
12145                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12146                                + " package: " + applicationInfo.packageName
12147                                + " activity: " + intent.activity.className
12148                                + " origPrio: " + intent.getPriority());
12149                    }
12150                    intent.setPriority(0);
12151                    return;
12152                }
12153            }
12154
12155            // we found matching filter(s); app gets the max priority of all intents
12156            int cappedPriority = 0;
12157            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12158                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12159            }
12160            if (intent.getPriority() > cappedPriority) {
12161                if (DEBUG_FILTERS) {
12162                    Slog.i(TAG, "Found matching filter(s);"
12163                            + " cap priority to " + cappedPriority + ";"
12164                            + " package: " + applicationInfo.packageName
12165                            + " activity: " + intent.activity.className
12166                            + " origPrio: " + intent.getPriority());
12167                }
12168                intent.setPriority(cappedPriority);
12169                return;
12170            }
12171            // all this for nothing; the requested priority was <= what was on the system
12172        }
12173
12174        public final void addActivity(PackageParser.Activity a, String type) {
12175            mActivities.put(a.getComponentName(), a);
12176            if (DEBUG_SHOW_INFO)
12177                Log.v(
12178                TAG, "  " + type + " " +
12179                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12180            if (DEBUG_SHOW_INFO)
12181                Log.v(TAG, "    Class=" + a.info.name);
12182            final int NI = a.intents.size();
12183            for (int j=0; j<NI; j++) {
12184                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12185                if ("activity".equals(type)) {
12186                    final PackageSetting ps =
12187                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12188                    final List<PackageParser.Activity> systemActivities =
12189                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12190                    adjustPriority(systemActivities, intent);
12191                }
12192                if (DEBUG_SHOW_INFO) {
12193                    Log.v(TAG, "    IntentFilter:");
12194                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12195                }
12196                if (!intent.debugCheck()) {
12197                    Log.w(TAG, "==> For Activity " + a.info.name);
12198                }
12199                addFilter(intent);
12200            }
12201        }
12202
12203        public final void removeActivity(PackageParser.Activity a, String type) {
12204            mActivities.remove(a.getComponentName());
12205            if (DEBUG_SHOW_INFO) {
12206                Log.v(TAG, "  " + type + " "
12207                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12208                                : a.info.name) + ":");
12209                Log.v(TAG, "    Class=" + a.info.name);
12210            }
12211            final int NI = a.intents.size();
12212            for (int j=0; j<NI; j++) {
12213                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12214                if (DEBUG_SHOW_INFO) {
12215                    Log.v(TAG, "    IntentFilter:");
12216                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12217                }
12218                removeFilter(intent);
12219            }
12220        }
12221
12222        @Override
12223        protected boolean allowFilterResult(
12224                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12225            ActivityInfo filterAi = filter.activity.info;
12226            for (int i=dest.size()-1; i>=0; i--) {
12227                ActivityInfo destAi = dest.get(i).activityInfo;
12228                if (destAi.name == filterAi.name
12229                        && destAi.packageName == filterAi.packageName) {
12230                    return false;
12231                }
12232            }
12233            return true;
12234        }
12235
12236        @Override
12237        protected ActivityIntentInfo[] newArray(int size) {
12238            return new ActivityIntentInfo[size];
12239        }
12240
12241        @Override
12242        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12243            if (!sUserManager.exists(userId)) return true;
12244            PackageParser.Package p = filter.activity.owner;
12245            if (p != null) {
12246                PackageSetting ps = (PackageSetting)p.mExtras;
12247                if (ps != null) {
12248                    // System apps are never considered stopped for purposes of
12249                    // filtering, because there may be no way for the user to
12250                    // actually re-launch them.
12251                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12252                            && ps.getStopped(userId);
12253                }
12254            }
12255            return false;
12256        }
12257
12258        @Override
12259        protected boolean isPackageForFilter(String packageName,
12260                PackageParser.ActivityIntentInfo info) {
12261            return packageName.equals(info.activity.owner.packageName);
12262        }
12263
12264        @Override
12265        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12266                int match, int userId) {
12267            if (!sUserManager.exists(userId)) return null;
12268            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12269                return null;
12270            }
12271            final PackageParser.Activity activity = info.activity;
12272            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12273            if (ps == null) {
12274                return null;
12275            }
12276            final PackageUserState userState = ps.readUserState(userId);
12277            ActivityInfo ai =
12278                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12279            if (ai == null) {
12280                return null;
12281            }
12282            final boolean matchExplicitlyVisibleOnly =
12283                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12284            final boolean matchVisibleToInstantApp =
12285                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12286            final boolean componentVisible =
12287                    matchVisibleToInstantApp
12288                    && info.isVisibleToInstantApp()
12289                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12290            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12291            // throw out filters that aren't visible to ephemeral apps
12292            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12293                return null;
12294            }
12295            // throw out instant app filters if we're not explicitly requesting them
12296            if (!matchInstantApp && userState.instantApp) {
12297                return null;
12298            }
12299            // throw out instant app filters if updates are available; will trigger
12300            // instant app resolution
12301            if (userState.instantApp && ps.isUpdateAvailable()) {
12302                return null;
12303            }
12304            final ResolveInfo res = new ResolveInfo();
12305            res.activityInfo = ai;
12306            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12307                res.filter = info;
12308            }
12309            if (info != null) {
12310                res.handleAllWebDataURI = info.handleAllWebDataURI();
12311            }
12312            res.priority = info.getPriority();
12313            res.preferredOrder = activity.owner.mPreferredOrder;
12314            //System.out.println("Result: " + res.activityInfo.className +
12315            //                   " = " + res.priority);
12316            res.match = match;
12317            res.isDefault = info.hasDefault;
12318            res.labelRes = info.labelRes;
12319            res.nonLocalizedLabel = info.nonLocalizedLabel;
12320            if (userNeedsBadging(userId)) {
12321                res.noResourceId = true;
12322            } else {
12323                res.icon = info.icon;
12324            }
12325            res.iconResourceId = info.icon;
12326            res.system = res.activityInfo.applicationInfo.isSystemApp();
12327            res.isInstantAppAvailable = userState.instantApp;
12328            return res;
12329        }
12330
12331        @Override
12332        protected void sortResults(List<ResolveInfo> results) {
12333            Collections.sort(results, mResolvePrioritySorter);
12334        }
12335
12336        @Override
12337        protected void dumpFilter(PrintWriter out, String prefix,
12338                PackageParser.ActivityIntentInfo filter) {
12339            out.print(prefix); out.print(
12340                    Integer.toHexString(System.identityHashCode(filter.activity)));
12341                    out.print(' ');
12342                    filter.activity.printComponentShortName(out);
12343                    out.print(" filter ");
12344                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12345        }
12346
12347        @Override
12348        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12349            return filter.activity;
12350        }
12351
12352        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12353            PackageParser.Activity activity = (PackageParser.Activity)label;
12354            out.print(prefix); out.print(
12355                    Integer.toHexString(System.identityHashCode(activity)));
12356                    out.print(' ');
12357                    activity.printComponentShortName(out);
12358            if (count > 1) {
12359                out.print(" ("); out.print(count); out.print(" filters)");
12360            }
12361            out.println();
12362        }
12363
12364        // Keys are String (activity class name), values are Activity.
12365        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12366                = new ArrayMap<ComponentName, PackageParser.Activity>();
12367        private int mFlags;
12368    }
12369
12370    private final class ServiceIntentResolver
12371            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12372        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12373                boolean defaultOnly, int userId) {
12374            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12375            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12376        }
12377
12378        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12379                int userId) {
12380            if (!sUserManager.exists(userId)) return null;
12381            mFlags = flags;
12382            return super.queryIntent(intent, resolvedType,
12383                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12384                    userId);
12385        }
12386
12387        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12388                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12389            if (!sUserManager.exists(userId)) return null;
12390            if (packageServices == null) {
12391                return null;
12392            }
12393            mFlags = flags;
12394            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12395            final int N = packageServices.size();
12396            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12397                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12398
12399            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12400            for (int i = 0; i < N; ++i) {
12401                intentFilters = packageServices.get(i).intents;
12402                if (intentFilters != null && intentFilters.size() > 0) {
12403                    PackageParser.ServiceIntentInfo[] array =
12404                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12405                    intentFilters.toArray(array);
12406                    listCut.add(array);
12407                }
12408            }
12409            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12410        }
12411
12412        public final void addService(PackageParser.Service s) {
12413            mServices.put(s.getComponentName(), s);
12414            if (DEBUG_SHOW_INFO) {
12415                Log.v(TAG, "  "
12416                        + (s.info.nonLocalizedLabel != null
12417                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12418                Log.v(TAG, "    Class=" + s.info.name);
12419            }
12420            final int NI = s.intents.size();
12421            int j;
12422            for (j=0; j<NI; j++) {
12423                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12424                if (DEBUG_SHOW_INFO) {
12425                    Log.v(TAG, "    IntentFilter:");
12426                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12427                }
12428                if (!intent.debugCheck()) {
12429                    Log.w(TAG, "==> For Service " + s.info.name);
12430                }
12431                addFilter(intent);
12432            }
12433        }
12434
12435        public final void removeService(PackageParser.Service s) {
12436            mServices.remove(s.getComponentName());
12437            if (DEBUG_SHOW_INFO) {
12438                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12439                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12440                Log.v(TAG, "    Class=" + s.info.name);
12441            }
12442            final int NI = s.intents.size();
12443            int j;
12444            for (j=0; j<NI; j++) {
12445                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12446                if (DEBUG_SHOW_INFO) {
12447                    Log.v(TAG, "    IntentFilter:");
12448                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12449                }
12450                removeFilter(intent);
12451            }
12452        }
12453
12454        @Override
12455        protected boolean allowFilterResult(
12456                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12457            ServiceInfo filterSi = filter.service.info;
12458            for (int i=dest.size()-1; i>=0; i--) {
12459                ServiceInfo destAi = dest.get(i).serviceInfo;
12460                if (destAi.name == filterSi.name
12461                        && destAi.packageName == filterSi.packageName) {
12462                    return false;
12463                }
12464            }
12465            return true;
12466        }
12467
12468        @Override
12469        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12470            return new PackageParser.ServiceIntentInfo[size];
12471        }
12472
12473        @Override
12474        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12475            if (!sUserManager.exists(userId)) return true;
12476            PackageParser.Package p = filter.service.owner;
12477            if (p != null) {
12478                PackageSetting ps = (PackageSetting)p.mExtras;
12479                if (ps != null) {
12480                    // System apps are never considered stopped for purposes of
12481                    // filtering, because there may be no way for the user to
12482                    // actually re-launch them.
12483                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12484                            && ps.getStopped(userId);
12485                }
12486            }
12487            return false;
12488        }
12489
12490        @Override
12491        protected boolean isPackageForFilter(String packageName,
12492                PackageParser.ServiceIntentInfo info) {
12493            return packageName.equals(info.service.owner.packageName);
12494        }
12495
12496        @Override
12497        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12498                int match, int userId) {
12499            if (!sUserManager.exists(userId)) return null;
12500            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12501            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12502                return null;
12503            }
12504            final PackageParser.Service service = info.service;
12505            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12506            if (ps == null) {
12507                return null;
12508            }
12509            final PackageUserState userState = ps.readUserState(userId);
12510            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12511                    userState, userId);
12512            if (si == null) {
12513                return null;
12514            }
12515            final boolean matchVisibleToInstantApp =
12516                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12517            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12518            // throw out filters that aren't visible to ephemeral apps
12519            if (matchVisibleToInstantApp
12520                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12521                return null;
12522            }
12523            // throw out ephemeral filters if we're not explicitly requesting them
12524            if (!isInstantApp && userState.instantApp) {
12525                return null;
12526            }
12527            // throw out instant app filters if updates are available; will trigger
12528            // instant app resolution
12529            if (userState.instantApp && ps.isUpdateAvailable()) {
12530                return null;
12531            }
12532            final ResolveInfo res = new ResolveInfo();
12533            res.serviceInfo = si;
12534            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12535                res.filter = filter;
12536            }
12537            res.priority = info.getPriority();
12538            res.preferredOrder = service.owner.mPreferredOrder;
12539            res.match = match;
12540            res.isDefault = info.hasDefault;
12541            res.labelRes = info.labelRes;
12542            res.nonLocalizedLabel = info.nonLocalizedLabel;
12543            res.icon = info.icon;
12544            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12545            return res;
12546        }
12547
12548        @Override
12549        protected void sortResults(List<ResolveInfo> results) {
12550            Collections.sort(results, mResolvePrioritySorter);
12551        }
12552
12553        @Override
12554        protected void dumpFilter(PrintWriter out, String prefix,
12555                PackageParser.ServiceIntentInfo filter) {
12556            out.print(prefix); out.print(
12557                    Integer.toHexString(System.identityHashCode(filter.service)));
12558                    out.print(' ');
12559                    filter.service.printComponentShortName(out);
12560                    out.print(" filter ");
12561                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12562        }
12563
12564        @Override
12565        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12566            return filter.service;
12567        }
12568
12569        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12570            PackageParser.Service service = (PackageParser.Service)label;
12571            out.print(prefix); out.print(
12572                    Integer.toHexString(System.identityHashCode(service)));
12573                    out.print(' ');
12574                    service.printComponentShortName(out);
12575            if (count > 1) {
12576                out.print(" ("); out.print(count); out.print(" filters)");
12577            }
12578            out.println();
12579        }
12580
12581//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12582//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12583//            final List<ResolveInfo> retList = Lists.newArrayList();
12584//            while (i.hasNext()) {
12585//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12586//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12587//                    retList.add(resolveInfo);
12588//                }
12589//            }
12590//            return retList;
12591//        }
12592
12593        // Keys are String (activity class name), values are Activity.
12594        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12595                = new ArrayMap<ComponentName, PackageParser.Service>();
12596        private int mFlags;
12597    }
12598
12599    private final class ProviderIntentResolver
12600            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12601        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12602                boolean defaultOnly, int userId) {
12603            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12604            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12605        }
12606
12607        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12608                int userId) {
12609            if (!sUserManager.exists(userId))
12610                return null;
12611            mFlags = flags;
12612            return super.queryIntent(intent, resolvedType,
12613                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12614                    userId);
12615        }
12616
12617        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12618                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12619            if (!sUserManager.exists(userId))
12620                return null;
12621            if (packageProviders == null) {
12622                return null;
12623            }
12624            mFlags = flags;
12625            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12626            final int N = packageProviders.size();
12627            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12628                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12629
12630            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12631            for (int i = 0; i < N; ++i) {
12632                intentFilters = packageProviders.get(i).intents;
12633                if (intentFilters != null && intentFilters.size() > 0) {
12634                    PackageParser.ProviderIntentInfo[] array =
12635                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12636                    intentFilters.toArray(array);
12637                    listCut.add(array);
12638                }
12639            }
12640            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12641        }
12642
12643        public final void addProvider(PackageParser.Provider p) {
12644            if (mProviders.containsKey(p.getComponentName())) {
12645                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12646                return;
12647            }
12648
12649            mProviders.put(p.getComponentName(), p);
12650            if (DEBUG_SHOW_INFO) {
12651                Log.v(TAG, "  "
12652                        + (p.info.nonLocalizedLabel != null
12653                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12654                Log.v(TAG, "    Class=" + p.info.name);
12655            }
12656            final int NI = p.intents.size();
12657            int j;
12658            for (j = 0; j < NI; j++) {
12659                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12660                if (DEBUG_SHOW_INFO) {
12661                    Log.v(TAG, "    IntentFilter:");
12662                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12663                }
12664                if (!intent.debugCheck()) {
12665                    Log.w(TAG, "==> For Provider " + p.info.name);
12666                }
12667                addFilter(intent);
12668            }
12669        }
12670
12671        public final void removeProvider(PackageParser.Provider p) {
12672            mProviders.remove(p.getComponentName());
12673            if (DEBUG_SHOW_INFO) {
12674                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12675                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12676                Log.v(TAG, "    Class=" + p.info.name);
12677            }
12678            final int NI = p.intents.size();
12679            int j;
12680            for (j = 0; j < NI; j++) {
12681                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12682                if (DEBUG_SHOW_INFO) {
12683                    Log.v(TAG, "    IntentFilter:");
12684                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12685                }
12686                removeFilter(intent);
12687            }
12688        }
12689
12690        @Override
12691        protected boolean allowFilterResult(
12692                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12693            ProviderInfo filterPi = filter.provider.info;
12694            for (int i = dest.size() - 1; i >= 0; i--) {
12695                ProviderInfo destPi = dest.get(i).providerInfo;
12696                if (destPi.name == filterPi.name
12697                        && destPi.packageName == filterPi.packageName) {
12698                    return false;
12699                }
12700            }
12701            return true;
12702        }
12703
12704        @Override
12705        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12706            return new PackageParser.ProviderIntentInfo[size];
12707        }
12708
12709        @Override
12710        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12711            if (!sUserManager.exists(userId))
12712                return true;
12713            PackageParser.Package p = filter.provider.owner;
12714            if (p != null) {
12715                PackageSetting ps = (PackageSetting) p.mExtras;
12716                if (ps != null) {
12717                    // System apps are never considered stopped for purposes of
12718                    // filtering, because there may be no way for the user to
12719                    // actually re-launch them.
12720                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12721                            && ps.getStopped(userId);
12722                }
12723            }
12724            return false;
12725        }
12726
12727        @Override
12728        protected boolean isPackageForFilter(String packageName,
12729                PackageParser.ProviderIntentInfo info) {
12730            return packageName.equals(info.provider.owner.packageName);
12731        }
12732
12733        @Override
12734        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12735                int match, int userId) {
12736            if (!sUserManager.exists(userId))
12737                return null;
12738            final PackageParser.ProviderIntentInfo info = filter;
12739            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12740                return null;
12741            }
12742            final PackageParser.Provider provider = info.provider;
12743            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12744            if (ps == null) {
12745                return null;
12746            }
12747            final PackageUserState userState = ps.readUserState(userId);
12748            final boolean matchVisibleToInstantApp =
12749                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12750            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12751            // throw out filters that aren't visible to instant applications
12752            if (matchVisibleToInstantApp
12753                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12754                return null;
12755            }
12756            // throw out instant application filters if we're not explicitly requesting them
12757            if (!isInstantApp && userState.instantApp) {
12758                return null;
12759            }
12760            // throw out instant application filters if updates are available; will trigger
12761            // instant application resolution
12762            if (userState.instantApp && ps.isUpdateAvailable()) {
12763                return null;
12764            }
12765            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12766                    userState, userId);
12767            if (pi == null) {
12768                return null;
12769            }
12770            final ResolveInfo res = new ResolveInfo();
12771            res.providerInfo = pi;
12772            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12773                res.filter = filter;
12774            }
12775            res.priority = info.getPriority();
12776            res.preferredOrder = provider.owner.mPreferredOrder;
12777            res.match = match;
12778            res.isDefault = info.hasDefault;
12779            res.labelRes = info.labelRes;
12780            res.nonLocalizedLabel = info.nonLocalizedLabel;
12781            res.icon = info.icon;
12782            res.system = res.providerInfo.applicationInfo.isSystemApp();
12783            return res;
12784        }
12785
12786        @Override
12787        protected void sortResults(List<ResolveInfo> results) {
12788            Collections.sort(results, mResolvePrioritySorter);
12789        }
12790
12791        @Override
12792        protected void dumpFilter(PrintWriter out, String prefix,
12793                PackageParser.ProviderIntentInfo filter) {
12794            out.print(prefix);
12795            out.print(
12796                    Integer.toHexString(System.identityHashCode(filter.provider)));
12797            out.print(' ');
12798            filter.provider.printComponentShortName(out);
12799            out.print(" filter ");
12800            out.println(Integer.toHexString(System.identityHashCode(filter)));
12801        }
12802
12803        @Override
12804        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12805            return filter.provider;
12806        }
12807
12808        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12809            PackageParser.Provider provider = (PackageParser.Provider)label;
12810            out.print(prefix); out.print(
12811                    Integer.toHexString(System.identityHashCode(provider)));
12812                    out.print(' ');
12813                    provider.printComponentShortName(out);
12814            if (count > 1) {
12815                out.print(" ("); out.print(count); out.print(" filters)");
12816            }
12817            out.println();
12818        }
12819
12820        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12821                = new ArrayMap<ComponentName, PackageParser.Provider>();
12822        private int mFlags;
12823    }
12824
12825    static final class EphemeralIntentResolver
12826            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12827        /**
12828         * The result that has the highest defined order. Ordering applies on a
12829         * per-package basis. Mapping is from package name to Pair of order and
12830         * EphemeralResolveInfo.
12831         * <p>
12832         * NOTE: This is implemented as a field variable for convenience and efficiency.
12833         * By having a field variable, we're able to track filter ordering as soon as
12834         * a non-zero order is defined. Otherwise, multiple loops across the result set
12835         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12836         * this needs to be contained entirely within {@link #filterResults}.
12837         */
12838        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12839
12840        @Override
12841        protected AuxiliaryResolveInfo[] newArray(int size) {
12842            return new AuxiliaryResolveInfo[size];
12843        }
12844
12845        @Override
12846        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12847            return true;
12848        }
12849
12850        @Override
12851        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12852                int userId) {
12853            if (!sUserManager.exists(userId)) {
12854                return null;
12855            }
12856            final String packageName = responseObj.resolveInfo.getPackageName();
12857            final Integer order = responseObj.getOrder();
12858            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12859                    mOrderResult.get(packageName);
12860            // ordering is enabled and this item's order isn't high enough
12861            if (lastOrderResult != null && lastOrderResult.first >= order) {
12862                return null;
12863            }
12864            final InstantAppResolveInfo res = responseObj.resolveInfo;
12865            if (order > 0) {
12866                // non-zero order, enable ordering
12867                mOrderResult.put(packageName, new Pair<>(order, res));
12868            }
12869            return responseObj;
12870        }
12871
12872        @Override
12873        protected void filterResults(List<AuxiliaryResolveInfo> results) {
12874            // only do work if ordering is enabled [most of the time it won't be]
12875            if (mOrderResult.size() == 0) {
12876                return;
12877            }
12878            int resultSize = results.size();
12879            for (int i = 0; i < resultSize; i++) {
12880                final InstantAppResolveInfo info = results.get(i).resolveInfo;
12881                final String packageName = info.getPackageName();
12882                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
12883                if (savedInfo == null) {
12884                    // package doesn't having ordering
12885                    continue;
12886                }
12887                if (savedInfo.second == info) {
12888                    // circled back to the highest ordered item; remove from order list
12889                    mOrderResult.remove(packageName);
12890                    if (mOrderResult.size() == 0) {
12891                        // no more ordered items
12892                        break;
12893                    }
12894                    continue;
12895                }
12896                // item has a worse order, remove it from the result list
12897                results.remove(i);
12898                resultSize--;
12899                i--;
12900            }
12901        }
12902    }
12903
12904    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
12905            new Comparator<ResolveInfo>() {
12906        public int compare(ResolveInfo r1, ResolveInfo r2) {
12907            int v1 = r1.priority;
12908            int v2 = r2.priority;
12909            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
12910            if (v1 != v2) {
12911                return (v1 > v2) ? -1 : 1;
12912            }
12913            v1 = r1.preferredOrder;
12914            v2 = r2.preferredOrder;
12915            if (v1 != v2) {
12916                return (v1 > v2) ? -1 : 1;
12917            }
12918            if (r1.isDefault != r2.isDefault) {
12919                return r1.isDefault ? -1 : 1;
12920            }
12921            v1 = r1.match;
12922            v2 = r2.match;
12923            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
12924            if (v1 != v2) {
12925                return (v1 > v2) ? -1 : 1;
12926            }
12927            if (r1.system != r2.system) {
12928                return r1.system ? -1 : 1;
12929            }
12930            if (r1.activityInfo != null) {
12931                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
12932            }
12933            if (r1.serviceInfo != null) {
12934                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
12935            }
12936            if (r1.providerInfo != null) {
12937                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
12938            }
12939            return 0;
12940        }
12941    };
12942
12943    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
12944            new Comparator<ProviderInfo>() {
12945        public int compare(ProviderInfo p1, ProviderInfo p2) {
12946            final int v1 = p1.initOrder;
12947            final int v2 = p2.initOrder;
12948            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12949        }
12950    };
12951
12952    @Override
12953    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12954            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12955            final int[] userIds, int[] instantUserIds) {
12956        mHandler.post(new Runnable() {
12957            @Override
12958            public void run() {
12959                try {
12960                    final IActivityManager am = ActivityManager.getService();
12961                    if (am == null) return;
12962                    final int[] resolvedUserIds;
12963                    if (userIds == null) {
12964                        resolvedUserIds = am.getRunningUserIds();
12965                    } else {
12966                        resolvedUserIds = userIds;
12967                    }
12968                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12969                            resolvedUserIds, false);
12970                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12971                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12972                                instantUserIds, true);
12973                    }
12974                } catch (RemoteException ex) {
12975                }
12976            }
12977        });
12978    }
12979
12980    /**
12981     * Sends a broadcast for the given action.
12982     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
12983     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
12984     * the system and applications allowed to see instant applications to receive package
12985     * lifecycle events for instant applications.
12986     */
12987    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
12988            int flags, String targetPkg, IIntentReceiver finishedReceiver,
12989            int[] userIds, boolean isInstantApp)
12990                    throws RemoteException {
12991        for (int id : userIds) {
12992            final Intent intent = new Intent(action,
12993                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12994            final String[] requiredPermissions =
12995                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
12996            if (extras != null) {
12997                intent.putExtras(extras);
12998            }
12999            if (targetPkg != null) {
13000                intent.setPackage(targetPkg);
13001            }
13002            // Modify the UID when posting to other users
13003            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13004            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13005                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13006                intent.putExtra(Intent.EXTRA_UID, uid);
13007            }
13008            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13009            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13010            if (DEBUG_BROADCASTS) {
13011                RuntimeException here = new RuntimeException("here");
13012                here.fillInStackTrace();
13013                Slog.d(TAG, "Sending to user " + id + ": "
13014                        + intent.toShortString(false, true, false, false)
13015                        + " " + intent.getExtras(), here);
13016            }
13017            am.broadcastIntent(null, intent, null, finishedReceiver,
13018                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13019                    null, finishedReceiver != null, false, id);
13020        }
13021    }
13022
13023    /**
13024     * Check if the external storage media is available. This is true if there
13025     * is a mounted external storage medium or if the external storage is
13026     * emulated.
13027     */
13028    private boolean isExternalMediaAvailable() {
13029        return mMediaMounted || Environment.isExternalStorageEmulated();
13030    }
13031
13032    @Override
13033    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13034        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13035            return null;
13036        }
13037        if (!isExternalMediaAvailable()) {
13038                // If the external storage is no longer mounted at this point,
13039                // the caller may not have been able to delete all of this
13040                // packages files and can not delete any more.  Bail.
13041            return null;
13042        }
13043        synchronized (mPackages) {
13044            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13045            if (lastPackage != null) {
13046                pkgs.remove(lastPackage);
13047            }
13048            if (pkgs.size() > 0) {
13049                return pkgs.get(0);
13050            }
13051        }
13052        return null;
13053    }
13054
13055    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13056        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13057                userId, andCode ? 1 : 0, packageName);
13058        if (mSystemReady) {
13059            msg.sendToTarget();
13060        } else {
13061            if (mPostSystemReadyMessages == null) {
13062                mPostSystemReadyMessages = new ArrayList<>();
13063            }
13064            mPostSystemReadyMessages.add(msg);
13065        }
13066    }
13067
13068    void startCleaningPackages() {
13069        // reader
13070        if (!isExternalMediaAvailable()) {
13071            return;
13072        }
13073        synchronized (mPackages) {
13074            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13075                return;
13076            }
13077        }
13078        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13079        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13080        IActivityManager am = ActivityManager.getService();
13081        if (am != null) {
13082            int dcsUid = -1;
13083            synchronized (mPackages) {
13084                if (!mDefaultContainerWhitelisted) {
13085                    mDefaultContainerWhitelisted = true;
13086                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13087                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13088                }
13089            }
13090            try {
13091                if (dcsUid > 0) {
13092                    am.backgroundWhitelistUid(dcsUid);
13093                }
13094                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13095                        UserHandle.USER_SYSTEM);
13096            } catch (RemoteException e) {
13097            }
13098        }
13099    }
13100
13101    @Override
13102    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13103            int installFlags, String installerPackageName, int userId) {
13104        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13105
13106        final int callingUid = Binder.getCallingUid();
13107        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13108                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13109
13110        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13111            try {
13112                if (observer != null) {
13113                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13114                }
13115            } catch (RemoteException re) {
13116            }
13117            return;
13118        }
13119
13120        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13121            installFlags |= PackageManager.INSTALL_FROM_ADB;
13122
13123        } else {
13124            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13125            // about installerPackageName.
13126
13127            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13128            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13129        }
13130
13131        UserHandle user;
13132        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13133            user = UserHandle.ALL;
13134        } else {
13135            user = new UserHandle(userId);
13136        }
13137
13138        // Only system components can circumvent runtime permissions when installing.
13139        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13140                && mContext.checkCallingOrSelfPermission(Manifest.permission
13141                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13142            throw new SecurityException("You need the "
13143                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13144                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13145        }
13146
13147        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13148                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13149            throw new IllegalArgumentException(
13150                    "New installs into ASEC containers no longer supported");
13151        }
13152
13153        final File originFile = new File(originPath);
13154        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13155
13156        final Message msg = mHandler.obtainMessage(INIT_COPY);
13157        final VerificationInfo verificationInfo = new VerificationInfo(
13158                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13159        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13160                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13161                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13162                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13163        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13164        msg.obj = params;
13165
13166        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13167                System.identityHashCode(msg.obj));
13168        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13169                System.identityHashCode(msg.obj));
13170
13171        mHandler.sendMessage(msg);
13172    }
13173
13174
13175    /**
13176     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13177     * it is acting on behalf on an enterprise or the user).
13178     *
13179     * Note that the ordering of the conditionals in this method is important. The checks we perform
13180     * are as follows, in this order:
13181     *
13182     * 1) If the install is being performed by a system app, we can trust the app to have set the
13183     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13184     *    what it is.
13185     * 2) If the install is being performed by a device or profile owner app, the install reason
13186     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13187     *    set the install reason correctly. If the app targets an older SDK version where install
13188     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13189     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13190     * 3) In all other cases, the install is being performed by a regular app that is neither part
13191     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13192     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13193     *    set to enterprise policy and if so, change it to unknown instead.
13194     */
13195    private int fixUpInstallReason(String installerPackageName, int installerUid,
13196            int installReason) {
13197        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13198                == PERMISSION_GRANTED) {
13199            // If the install is being performed by a system app, we trust that app to have set the
13200            // install reason correctly.
13201            return installReason;
13202        }
13203
13204        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13205            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13206        if (dpm != null) {
13207            ComponentName owner = null;
13208            try {
13209                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13210                if (owner == null) {
13211                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13212                }
13213            } catch (RemoteException e) {
13214            }
13215            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13216                // If the install is being performed by a device or profile owner, the install
13217                // reason should be enterprise policy.
13218                return PackageManager.INSTALL_REASON_POLICY;
13219            }
13220        }
13221
13222        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13223            // If the install is being performed by a regular app (i.e. neither system app nor
13224            // device or profile owner), we have no reason to believe that the app is acting on
13225            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13226            // change it to unknown instead.
13227            return PackageManager.INSTALL_REASON_UNKNOWN;
13228        }
13229
13230        // If the install is being performed by a regular app and the install reason was set to any
13231        // value but enterprise policy, leave the install reason unchanged.
13232        return installReason;
13233    }
13234
13235    void installStage(String packageName, File stagedDir,
13236            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13237            String installerPackageName, int installerUid, UserHandle user,
13238            Certificate[][] certificates) {
13239        if (DEBUG_EPHEMERAL) {
13240            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13241                Slog.d(TAG, "Ephemeral install of " + packageName);
13242            }
13243        }
13244        final VerificationInfo verificationInfo = new VerificationInfo(
13245                sessionParams.originatingUri, sessionParams.referrerUri,
13246                sessionParams.originatingUid, installerUid);
13247
13248        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13249
13250        final Message msg = mHandler.obtainMessage(INIT_COPY);
13251        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13252                sessionParams.installReason);
13253        final InstallParams params = new InstallParams(origin, null, observer,
13254                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13255                verificationInfo, user, sessionParams.abiOverride,
13256                sessionParams.grantedRuntimePermissions, certificates, installReason);
13257        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13258        msg.obj = params;
13259
13260        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13261                System.identityHashCode(msg.obj));
13262        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13263                System.identityHashCode(msg.obj));
13264
13265        mHandler.sendMessage(msg);
13266    }
13267
13268    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13269            int userId) {
13270        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13271        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13272        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13273        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13274        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13275                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13276
13277        // Send a session commit broadcast
13278        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13279        info.installReason = pkgSetting.getInstallReason(userId);
13280        info.appPackageName = packageName;
13281        sendSessionCommitBroadcast(info, userId);
13282    }
13283
13284    @Override
13285    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13286            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13287        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13288            return;
13289        }
13290        Bundle extras = new Bundle(1);
13291        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13292        final int uid = UserHandle.getUid(
13293                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13294        extras.putInt(Intent.EXTRA_UID, uid);
13295
13296        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13297                packageName, extras, 0, null, null, userIds, instantUserIds);
13298        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13299            mHandler.post(() -> {
13300                        for (int userId : userIds) {
13301                            sendBootCompletedBroadcastToSystemApp(
13302                                    packageName, includeStopped, userId);
13303                        }
13304                    }
13305            );
13306        }
13307    }
13308
13309    /**
13310     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13311     * automatically without needing an explicit launch.
13312     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13313     */
13314    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13315            int userId) {
13316        // If user is not running, the app didn't miss any broadcast
13317        if (!mUserManagerInternal.isUserRunning(userId)) {
13318            return;
13319        }
13320        final IActivityManager am = ActivityManager.getService();
13321        try {
13322            // Deliver LOCKED_BOOT_COMPLETED first
13323            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13324                    .setPackage(packageName);
13325            if (includeStopped) {
13326                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13327            }
13328            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13329            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13330                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13331
13332            // Deliver BOOT_COMPLETED only if user is unlocked
13333            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13334                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13335                if (includeStopped) {
13336                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13337                }
13338                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13339                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13340            }
13341        } catch (RemoteException e) {
13342            throw e.rethrowFromSystemServer();
13343        }
13344    }
13345
13346    @Override
13347    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13348            int userId) {
13349        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13350        PackageSetting pkgSetting;
13351        final int callingUid = Binder.getCallingUid();
13352        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13353                true /* requireFullPermission */, true /* checkShell */,
13354                "setApplicationHiddenSetting for user " + userId);
13355
13356        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13357            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13358            return false;
13359        }
13360
13361        long callingId = Binder.clearCallingIdentity();
13362        try {
13363            boolean sendAdded = false;
13364            boolean sendRemoved = false;
13365            // writer
13366            synchronized (mPackages) {
13367                pkgSetting = mSettings.mPackages.get(packageName);
13368                if (pkgSetting == null) {
13369                    return false;
13370                }
13371                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13372                    return false;
13373                }
13374                // Do not allow "android" is being disabled
13375                if ("android".equals(packageName)) {
13376                    Slog.w(TAG, "Cannot hide package: android");
13377                    return false;
13378                }
13379                // Cannot hide static shared libs as they are considered
13380                // a part of the using app (emulating static linking). Also
13381                // static libs are installed always on internal storage.
13382                PackageParser.Package pkg = mPackages.get(packageName);
13383                if (pkg != null && pkg.staticSharedLibName != null) {
13384                    Slog.w(TAG, "Cannot hide package: " + packageName
13385                            + " providing static shared library: "
13386                            + pkg.staticSharedLibName);
13387                    return false;
13388                }
13389                // Only allow protected packages to hide themselves.
13390                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13391                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13392                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13393                    return false;
13394                }
13395
13396                if (pkgSetting.getHidden(userId) != hidden) {
13397                    pkgSetting.setHidden(hidden, userId);
13398                    mSettings.writePackageRestrictionsLPr(userId);
13399                    if (hidden) {
13400                        sendRemoved = true;
13401                    } else {
13402                        sendAdded = true;
13403                    }
13404                }
13405            }
13406            if (sendAdded) {
13407                sendPackageAddedForUser(packageName, pkgSetting, userId);
13408                return true;
13409            }
13410            if (sendRemoved) {
13411                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13412                        "hiding pkg");
13413                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13414                return true;
13415            }
13416        } finally {
13417            Binder.restoreCallingIdentity(callingId);
13418        }
13419        return false;
13420    }
13421
13422    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13423            int userId) {
13424        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13425        info.removedPackage = packageName;
13426        info.installerPackageName = pkgSetting.installerPackageName;
13427        info.removedUsers = new int[] {userId};
13428        info.broadcastUsers = new int[] {userId};
13429        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13430        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13431    }
13432
13433    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13434        if (pkgList.length > 0) {
13435            Bundle extras = new Bundle(1);
13436            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13437
13438            sendPackageBroadcast(
13439                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13440                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13441                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13442                    new int[] {userId}, null);
13443        }
13444    }
13445
13446    /**
13447     * Returns true if application is not found or there was an error. Otherwise it returns
13448     * the hidden state of the package for the given user.
13449     */
13450    @Override
13451    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13452        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13453        final int callingUid = Binder.getCallingUid();
13454        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13455                true /* requireFullPermission */, false /* checkShell */,
13456                "getApplicationHidden for user " + userId);
13457        PackageSetting ps;
13458        long callingId = Binder.clearCallingIdentity();
13459        try {
13460            // writer
13461            synchronized (mPackages) {
13462                ps = mSettings.mPackages.get(packageName);
13463                if (ps == null) {
13464                    return true;
13465                }
13466                if (filterAppAccessLPr(ps, callingUid, userId)) {
13467                    return true;
13468                }
13469                return ps.getHidden(userId);
13470            }
13471        } finally {
13472            Binder.restoreCallingIdentity(callingId);
13473        }
13474    }
13475
13476    /**
13477     * @hide
13478     */
13479    @Override
13480    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13481            int installReason) {
13482        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13483                null);
13484        PackageSetting pkgSetting;
13485        final int callingUid = Binder.getCallingUid();
13486        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13487                true /* requireFullPermission */, true /* checkShell */,
13488                "installExistingPackage for user " + userId);
13489        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13490            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13491        }
13492
13493        long callingId = Binder.clearCallingIdentity();
13494        try {
13495            boolean installed = false;
13496            final boolean instantApp =
13497                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13498            final boolean fullApp =
13499                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13500
13501            // writer
13502            synchronized (mPackages) {
13503                pkgSetting = mSettings.mPackages.get(packageName);
13504                if (pkgSetting == null) {
13505                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13506                }
13507                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13508                    // only allow the existing package to be used if it's installed as a full
13509                    // application for at least one user
13510                    boolean installAllowed = false;
13511                    for (int checkUserId : sUserManager.getUserIds()) {
13512                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13513                        if (installAllowed) {
13514                            break;
13515                        }
13516                    }
13517                    if (!installAllowed) {
13518                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13519                    }
13520                }
13521                if (!pkgSetting.getInstalled(userId)) {
13522                    pkgSetting.setInstalled(true, userId);
13523                    pkgSetting.setHidden(false, userId);
13524                    pkgSetting.setInstallReason(installReason, userId);
13525                    mSettings.writePackageRestrictionsLPr(userId);
13526                    mSettings.writeKernelMappingLPr(pkgSetting);
13527                    installed = true;
13528                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13529                    // upgrade app from instant to full; we don't allow app downgrade
13530                    installed = true;
13531                }
13532                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13533            }
13534
13535            if (installed) {
13536                if (pkgSetting.pkg != null) {
13537                    synchronized (mInstallLock) {
13538                        // We don't need to freeze for a brand new install
13539                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13540                    }
13541                }
13542                sendPackageAddedForUser(packageName, pkgSetting, userId);
13543                synchronized (mPackages) {
13544                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13545                }
13546            }
13547        } finally {
13548            Binder.restoreCallingIdentity(callingId);
13549        }
13550
13551        return PackageManager.INSTALL_SUCCEEDED;
13552    }
13553
13554    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13555            boolean instantApp, boolean fullApp) {
13556        // no state specified; do nothing
13557        if (!instantApp && !fullApp) {
13558            return;
13559        }
13560        if (userId != UserHandle.USER_ALL) {
13561            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13562                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13563            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13564                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13565            }
13566        } else {
13567            for (int currentUserId : sUserManager.getUserIds()) {
13568                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13569                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13570                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13571                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13572                }
13573            }
13574        }
13575    }
13576
13577    boolean isUserRestricted(int userId, String restrictionKey) {
13578        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13579        if (restrictions.getBoolean(restrictionKey, false)) {
13580            Log.w(TAG, "User is restricted: " + restrictionKey);
13581            return true;
13582        }
13583        return false;
13584    }
13585
13586    @Override
13587    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13588            int userId) {
13589        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13590        final int callingUid = Binder.getCallingUid();
13591        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13592                true /* requireFullPermission */, true /* checkShell */,
13593                "setPackagesSuspended for user " + userId);
13594
13595        if (ArrayUtils.isEmpty(packageNames)) {
13596            return packageNames;
13597        }
13598
13599        // List of package names for whom the suspended state has changed.
13600        List<String> changedPackages = new ArrayList<>(packageNames.length);
13601        // List of package names for whom the suspended state is not set as requested in this
13602        // method.
13603        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13604        long callingId = Binder.clearCallingIdentity();
13605        try {
13606            for (int i = 0; i < packageNames.length; i++) {
13607                String packageName = packageNames[i];
13608                boolean changed = false;
13609                final int appId;
13610                synchronized (mPackages) {
13611                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13612                    if (pkgSetting == null
13613                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13614                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13615                                + "\". Skipping suspending/un-suspending.");
13616                        unactionedPackages.add(packageName);
13617                        continue;
13618                    }
13619                    appId = pkgSetting.appId;
13620                    if (pkgSetting.getSuspended(userId) != suspended) {
13621                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13622                            unactionedPackages.add(packageName);
13623                            continue;
13624                        }
13625                        pkgSetting.setSuspended(suspended, userId);
13626                        mSettings.writePackageRestrictionsLPr(userId);
13627                        changed = true;
13628                        changedPackages.add(packageName);
13629                    }
13630                }
13631
13632                if (changed && suspended) {
13633                    killApplication(packageName, UserHandle.getUid(userId, appId),
13634                            "suspending package");
13635                }
13636            }
13637        } finally {
13638            Binder.restoreCallingIdentity(callingId);
13639        }
13640
13641        if (!changedPackages.isEmpty()) {
13642            sendPackagesSuspendedForUser(changedPackages.toArray(
13643                    new String[changedPackages.size()]), userId, suspended);
13644        }
13645
13646        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13647    }
13648
13649    @Override
13650    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13651        final int callingUid = Binder.getCallingUid();
13652        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13653                true /* requireFullPermission */, false /* checkShell */,
13654                "isPackageSuspendedForUser for user " + userId);
13655        synchronized (mPackages) {
13656            final PackageSetting ps = mSettings.mPackages.get(packageName);
13657            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13658                throw new IllegalArgumentException("Unknown target package: " + packageName);
13659            }
13660            return ps.getSuspended(userId);
13661        }
13662    }
13663
13664    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13665        if (isPackageDeviceAdmin(packageName, userId)) {
13666            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13667                    + "\": has an active device admin");
13668            return false;
13669        }
13670
13671        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13672        if (packageName.equals(activeLauncherPackageName)) {
13673            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13674                    + "\": contains the active launcher");
13675            return false;
13676        }
13677
13678        if (packageName.equals(mRequiredInstallerPackage)) {
13679            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13680                    + "\": required for package installation");
13681            return false;
13682        }
13683
13684        if (packageName.equals(mRequiredUninstallerPackage)) {
13685            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13686                    + "\": required for package uninstallation");
13687            return false;
13688        }
13689
13690        if (packageName.equals(mRequiredVerifierPackage)) {
13691            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13692                    + "\": required for package verification");
13693            return false;
13694        }
13695
13696        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13697            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13698                    + "\": is the default dialer");
13699            return false;
13700        }
13701
13702        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13703            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13704                    + "\": protected package");
13705            return false;
13706        }
13707
13708        // Cannot suspend static shared libs as they are considered
13709        // a part of the using app (emulating static linking). Also
13710        // static libs are installed always on internal storage.
13711        PackageParser.Package pkg = mPackages.get(packageName);
13712        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13713            Slog.w(TAG, "Cannot suspend package: " + packageName
13714                    + " providing static shared library: "
13715                    + pkg.staticSharedLibName);
13716            return false;
13717        }
13718
13719        return true;
13720    }
13721
13722    private String getActiveLauncherPackageName(int userId) {
13723        Intent intent = new Intent(Intent.ACTION_MAIN);
13724        intent.addCategory(Intent.CATEGORY_HOME);
13725        ResolveInfo resolveInfo = resolveIntent(
13726                intent,
13727                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13728                PackageManager.MATCH_DEFAULT_ONLY,
13729                userId);
13730
13731        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13732    }
13733
13734    private String getDefaultDialerPackageName(int userId) {
13735        synchronized (mPackages) {
13736            return mSettings.getDefaultDialerPackageNameLPw(userId);
13737        }
13738    }
13739
13740    @Override
13741    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13742        mContext.enforceCallingOrSelfPermission(
13743                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13744                "Only package verification agents can verify applications");
13745
13746        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13747        final PackageVerificationResponse response = new PackageVerificationResponse(
13748                verificationCode, Binder.getCallingUid());
13749        msg.arg1 = id;
13750        msg.obj = response;
13751        mHandler.sendMessage(msg);
13752    }
13753
13754    @Override
13755    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13756            long millisecondsToDelay) {
13757        mContext.enforceCallingOrSelfPermission(
13758                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13759                "Only package verification agents can extend verification timeouts");
13760
13761        final PackageVerificationState state = mPendingVerification.get(id);
13762        final PackageVerificationResponse response = new PackageVerificationResponse(
13763                verificationCodeAtTimeout, Binder.getCallingUid());
13764
13765        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13766            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13767        }
13768        if (millisecondsToDelay < 0) {
13769            millisecondsToDelay = 0;
13770        }
13771        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13772                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13773            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13774        }
13775
13776        if ((state != null) && !state.timeoutExtended()) {
13777            state.extendTimeout();
13778
13779            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13780            msg.arg1 = id;
13781            msg.obj = response;
13782            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13783        }
13784    }
13785
13786    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13787            int verificationCode, UserHandle user) {
13788        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13789        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13790        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13791        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13792        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13793
13794        mContext.sendBroadcastAsUser(intent, user,
13795                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13796    }
13797
13798    private ComponentName matchComponentForVerifier(String packageName,
13799            List<ResolveInfo> receivers) {
13800        ActivityInfo targetReceiver = null;
13801
13802        final int NR = receivers.size();
13803        for (int i = 0; i < NR; i++) {
13804            final ResolveInfo info = receivers.get(i);
13805            if (info.activityInfo == null) {
13806                continue;
13807            }
13808
13809            if (packageName.equals(info.activityInfo.packageName)) {
13810                targetReceiver = info.activityInfo;
13811                break;
13812            }
13813        }
13814
13815        if (targetReceiver == null) {
13816            return null;
13817        }
13818
13819        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13820    }
13821
13822    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13823            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13824        if (pkgInfo.verifiers.length == 0) {
13825            return null;
13826        }
13827
13828        final int N = pkgInfo.verifiers.length;
13829        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13830        for (int i = 0; i < N; i++) {
13831            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13832
13833            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13834                    receivers);
13835            if (comp == null) {
13836                continue;
13837            }
13838
13839            final int verifierUid = getUidForVerifier(verifierInfo);
13840            if (verifierUid == -1) {
13841                continue;
13842            }
13843
13844            if (DEBUG_VERIFY) {
13845                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13846                        + " with the correct signature");
13847            }
13848            sufficientVerifiers.add(comp);
13849            verificationState.addSufficientVerifier(verifierUid);
13850        }
13851
13852        return sufficientVerifiers;
13853    }
13854
13855    private int getUidForVerifier(VerifierInfo verifierInfo) {
13856        synchronized (mPackages) {
13857            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13858            if (pkg == null) {
13859                return -1;
13860            } else if (pkg.mSignatures.length != 1) {
13861                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13862                        + " has more than one signature; ignoring");
13863                return -1;
13864            }
13865
13866            /*
13867             * If the public key of the package's signature does not match
13868             * our expected public key, then this is a different package and
13869             * we should skip.
13870             */
13871
13872            final byte[] expectedPublicKey;
13873            try {
13874                final Signature verifierSig = pkg.mSignatures[0];
13875                final PublicKey publicKey = verifierSig.getPublicKey();
13876                expectedPublicKey = publicKey.getEncoded();
13877            } catch (CertificateException e) {
13878                return -1;
13879            }
13880
13881            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13882
13883            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13884                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13885                        + " does not have the expected public key; ignoring");
13886                return -1;
13887            }
13888
13889            return pkg.applicationInfo.uid;
13890        }
13891    }
13892
13893    @Override
13894    public void finishPackageInstall(int token, boolean didLaunch) {
13895        enforceSystemOrRoot("Only the system is allowed to finish installs");
13896
13897        if (DEBUG_INSTALL) {
13898            Slog.v(TAG, "BM finishing package install for " + token);
13899        }
13900        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13901
13902        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13903        mHandler.sendMessage(msg);
13904    }
13905
13906    /**
13907     * Get the verification agent timeout.  Used for both the APK verifier and the
13908     * intent filter verifier.
13909     *
13910     * @return verification timeout in milliseconds
13911     */
13912    private long getVerificationTimeout() {
13913        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13914                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13915                DEFAULT_VERIFICATION_TIMEOUT);
13916    }
13917
13918    /**
13919     * Get the default verification agent response code.
13920     *
13921     * @return default verification response code
13922     */
13923    private int getDefaultVerificationResponse(UserHandle user) {
13924        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13925            return PackageManager.VERIFICATION_REJECT;
13926        }
13927        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13928                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13929                DEFAULT_VERIFICATION_RESPONSE);
13930    }
13931
13932    /**
13933     * Check whether or not package verification has been enabled.
13934     *
13935     * @return true if verification should be performed
13936     */
13937    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
13938        if (!DEFAULT_VERIFY_ENABLE) {
13939            return false;
13940        }
13941
13942        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
13943
13944        // Check if installing from ADB
13945        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13946            // Do not run verification in a test harness environment
13947            if (ActivityManager.isRunningInTestHarness()) {
13948                return false;
13949            }
13950            if (ensureVerifyAppsEnabled) {
13951                return true;
13952            }
13953            // Check if the developer does not want package verification for ADB installs
13954            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13955                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
13956                return false;
13957            }
13958        } else {
13959            // only when not installed from ADB, skip verification for instant apps when
13960            // the installer and verifier are the same.
13961            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13962                if (mInstantAppInstallerActivity != null
13963                        && mInstantAppInstallerActivity.packageName.equals(
13964                                mRequiredVerifierPackage)) {
13965                    try {
13966                        mContext.getSystemService(AppOpsManager.class)
13967                                .checkPackage(installerUid, mRequiredVerifierPackage);
13968                        if (DEBUG_VERIFY) {
13969                            Slog.i(TAG, "disable verification for instant app");
13970                        }
13971                        return false;
13972                    } catch (SecurityException ignore) { }
13973                }
13974            }
13975        }
13976
13977        if (ensureVerifyAppsEnabled) {
13978            return true;
13979        }
13980
13981        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13982                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
13983    }
13984
13985    @Override
13986    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13987            throws RemoteException {
13988        mContext.enforceCallingOrSelfPermission(
13989                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13990                "Only intentfilter verification agents can verify applications");
13991
13992        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13993        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13994                Binder.getCallingUid(), verificationCode, failedDomains);
13995        msg.arg1 = id;
13996        msg.obj = response;
13997        mHandler.sendMessage(msg);
13998    }
13999
14000    @Override
14001    public int getIntentVerificationStatus(String packageName, int userId) {
14002        final int callingUid = Binder.getCallingUid();
14003        if (UserHandle.getUserId(callingUid) != userId) {
14004            mContext.enforceCallingOrSelfPermission(
14005                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14006                    "getIntentVerificationStatus" + userId);
14007        }
14008        if (getInstantAppPackageName(callingUid) != null) {
14009            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14010        }
14011        synchronized (mPackages) {
14012            final PackageSetting ps = mSettings.mPackages.get(packageName);
14013            if (ps == null
14014                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14015                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14016            }
14017            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14018        }
14019    }
14020
14021    @Override
14022    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14023        mContext.enforceCallingOrSelfPermission(
14024                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14025
14026        boolean result = false;
14027        synchronized (mPackages) {
14028            final PackageSetting ps = mSettings.mPackages.get(packageName);
14029            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14030                return false;
14031            }
14032            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14033        }
14034        if (result) {
14035            scheduleWritePackageRestrictionsLocked(userId);
14036        }
14037        return result;
14038    }
14039
14040    @Override
14041    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14042            String packageName) {
14043        final int callingUid = Binder.getCallingUid();
14044        if (getInstantAppPackageName(callingUid) != null) {
14045            return ParceledListSlice.emptyList();
14046        }
14047        synchronized (mPackages) {
14048            final PackageSetting ps = mSettings.mPackages.get(packageName);
14049            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14050                return ParceledListSlice.emptyList();
14051            }
14052            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14053        }
14054    }
14055
14056    @Override
14057    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14058        if (TextUtils.isEmpty(packageName)) {
14059            return ParceledListSlice.emptyList();
14060        }
14061        final int callingUid = Binder.getCallingUid();
14062        final int callingUserId = UserHandle.getUserId(callingUid);
14063        synchronized (mPackages) {
14064            PackageParser.Package pkg = mPackages.get(packageName);
14065            if (pkg == null || pkg.activities == null) {
14066                return ParceledListSlice.emptyList();
14067            }
14068            if (pkg.mExtras == null) {
14069                return ParceledListSlice.emptyList();
14070            }
14071            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14072            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14073                return ParceledListSlice.emptyList();
14074            }
14075            final int count = pkg.activities.size();
14076            ArrayList<IntentFilter> result = new ArrayList<>();
14077            for (int n=0; n<count; n++) {
14078                PackageParser.Activity activity = pkg.activities.get(n);
14079                if (activity.intents != null && activity.intents.size() > 0) {
14080                    result.addAll(activity.intents);
14081                }
14082            }
14083            return new ParceledListSlice<>(result);
14084        }
14085    }
14086
14087    @Override
14088    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14089        mContext.enforceCallingOrSelfPermission(
14090                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14091        if (UserHandle.getCallingUserId() != userId) {
14092            mContext.enforceCallingOrSelfPermission(
14093                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14094        }
14095
14096        synchronized (mPackages) {
14097            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14098            if (packageName != null) {
14099                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14100                        packageName, userId);
14101            }
14102            return result;
14103        }
14104    }
14105
14106    @Override
14107    public String getDefaultBrowserPackageName(int userId) {
14108        if (UserHandle.getCallingUserId() != userId) {
14109            mContext.enforceCallingOrSelfPermission(
14110                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14111        }
14112        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14113            return null;
14114        }
14115        synchronized (mPackages) {
14116            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14117        }
14118    }
14119
14120    /**
14121     * Get the "allow unknown sources" setting.
14122     *
14123     * @return the current "allow unknown sources" setting
14124     */
14125    private int getUnknownSourcesSettings() {
14126        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14127                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14128                -1);
14129    }
14130
14131    @Override
14132    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14133        final int callingUid = Binder.getCallingUid();
14134        if (getInstantAppPackageName(callingUid) != null) {
14135            return;
14136        }
14137        // writer
14138        synchronized (mPackages) {
14139            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14140            if (targetPackageSetting == null
14141                    || filterAppAccessLPr(
14142                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14143                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14144            }
14145
14146            PackageSetting installerPackageSetting;
14147            if (installerPackageName != null) {
14148                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14149                if (installerPackageSetting == null) {
14150                    throw new IllegalArgumentException("Unknown installer package: "
14151                            + installerPackageName);
14152                }
14153            } else {
14154                installerPackageSetting = null;
14155            }
14156
14157            Signature[] callerSignature;
14158            Object obj = mSettings.getUserIdLPr(callingUid);
14159            if (obj != null) {
14160                if (obj instanceof SharedUserSetting) {
14161                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14162                } else if (obj instanceof PackageSetting) {
14163                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14164                } else {
14165                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14166                }
14167            } else {
14168                throw new SecurityException("Unknown calling UID: " + callingUid);
14169            }
14170
14171            // Verify: can't set installerPackageName to a package that is
14172            // not signed with the same cert as the caller.
14173            if (installerPackageSetting != null) {
14174                if (compareSignatures(callerSignature,
14175                        installerPackageSetting.signatures.mSignatures)
14176                        != PackageManager.SIGNATURE_MATCH) {
14177                    throw new SecurityException(
14178                            "Caller does not have same cert as new installer package "
14179                            + installerPackageName);
14180                }
14181            }
14182
14183            // Verify: if target already has an installer package, it must
14184            // be signed with the same cert as the caller.
14185            if (targetPackageSetting.installerPackageName != null) {
14186                PackageSetting setting = mSettings.mPackages.get(
14187                        targetPackageSetting.installerPackageName);
14188                // If the currently set package isn't valid, then it's always
14189                // okay to change it.
14190                if (setting != null) {
14191                    if (compareSignatures(callerSignature,
14192                            setting.signatures.mSignatures)
14193                            != PackageManager.SIGNATURE_MATCH) {
14194                        throw new SecurityException(
14195                                "Caller does not have same cert as old installer package "
14196                                + targetPackageSetting.installerPackageName);
14197                    }
14198                }
14199            }
14200
14201            // Okay!
14202            targetPackageSetting.installerPackageName = installerPackageName;
14203            if (installerPackageName != null) {
14204                mSettings.mInstallerPackages.add(installerPackageName);
14205            }
14206            scheduleWriteSettingsLocked();
14207        }
14208    }
14209
14210    @Override
14211    public void setApplicationCategoryHint(String packageName, int categoryHint,
14212            String callerPackageName) {
14213        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14214            throw new SecurityException("Instant applications don't have access to this method");
14215        }
14216        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14217                callerPackageName);
14218        synchronized (mPackages) {
14219            PackageSetting ps = mSettings.mPackages.get(packageName);
14220            if (ps == null) {
14221                throw new IllegalArgumentException("Unknown target package " + packageName);
14222            }
14223            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14224                throw new IllegalArgumentException("Unknown target package " + packageName);
14225            }
14226            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14227                throw new IllegalArgumentException("Calling package " + callerPackageName
14228                        + " is not installer for " + packageName);
14229            }
14230
14231            if (ps.categoryHint != categoryHint) {
14232                ps.categoryHint = categoryHint;
14233                scheduleWriteSettingsLocked();
14234            }
14235        }
14236    }
14237
14238    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14239        // Queue up an async operation since the package installation may take a little while.
14240        mHandler.post(new Runnable() {
14241            public void run() {
14242                mHandler.removeCallbacks(this);
14243                 // Result object to be returned
14244                PackageInstalledInfo res = new PackageInstalledInfo();
14245                res.setReturnCode(currentStatus);
14246                res.uid = -1;
14247                res.pkg = null;
14248                res.removedInfo = null;
14249                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14250                    args.doPreInstall(res.returnCode);
14251                    synchronized (mInstallLock) {
14252                        installPackageTracedLI(args, res);
14253                    }
14254                    args.doPostInstall(res.returnCode, res.uid);
14255                }
14256
14257                // A restore should be performed at this point if (a) the install
14258                // succeeded, (b) the operation is not an update, and (c) the new
14259                // package has not opted out of backup participation.
14260                final boolean update = res.removedInfo != null
14261                        && res.removedInfo.removedPackage != null;
14262                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14263                boolean doRestore = !update
14264                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14265
14266                // Set up the post-install work request bookkeeping.  This will be used
14267                // and cleaned up by the post-install event handling regardless of whether
14268                // there's a restore pass performed.  Token values are >= 1.
14269                int token;
14270                if (mNextInstallToken < 0) mNextInstallToken = 1;
14271                token = mNextInstallToken++;
14272
14273                PostInstallData data = new PostInstallData(args, res);
14274                mRunningInstalls.put(token, data);
14275                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14276
14277                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14278                    // Pass responsibility to the Backup Manager.  It will perform a
14279                    // restore if appropriate, then pass responsibility back to the
14280                    // Package Manager to run the post-install observer callbacks
14281                    // and broadcasts.
14282                    IBackupManager bm = IBackupManager.Stub.asInterface(
14283                            ServiceManager.getService(Context.BACKUP_SERVICE));
14284                    if (bm != null) {
14285                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14286                                + " to BM for possible restore");
14287                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14288                        try {
14289                            // TODO: http://b/22388012
14290                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14291                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14292                            } else {
14293                                doRestore = false;
14294                            }
14295                        } catch (RemoteException e) {
14296                            // can't happen; the backup manager is local
14297                        } catch (Exception e) {
14298                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14299                            doRestore = false;
14300                        }
14301                    } else {
14302                        Slog.e(TAG, "Backup Manager not found!");
14303                        doRestore = false;
14304                    }
14305                }
14306
14307                if (!doRestore) {
14308                    // No restore possible, or the Backup Manager was mysteriously not
14309                    // available -- just fire the post-install work request directly.
14310                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14311
14312                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14313
14314                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14315                    mHandler.sendMessage(msg);
14316                }
14317            }
14318        });
14319    }
14320
14321    /**
14322     * Callback from PackageSettings whenever an app is first transitioned out of the
14323     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14324     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14325     * here whether the app is the target of an ongoing install, and only send the
14326     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14327     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14328     * handling.
14329     */
14330    void notifyFirstLaunch(final String packageName, final String installerPackage,
14331            final int userId) {
14332        // Serialize this with the rest of the install-process message chain.  In the
14333        // restore-at-install case, this Runnable will necessarily run before the
14334        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14335        // are coherent.  In the non-restore case, the app has already completed install
14336        // and been launched through some other means, so it is not in a problematic
14337        // state for observers to see the FIRST_LAUNCH signal.
14338        mHandler.post(new Runnable() {
14339            @Override
14340            public void run() {
14341                for (int i = 0; i < mRunningInstalls.size(); i++) {
14342                    final PostInstallData data = mRunningInstalls.valueAt(i);
14343                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14344                        continue;
14345                    }
14346                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14347                        // right package; but is it for the right user?
14348                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14349                            if (userId == data.res.newUsers[uIndex]) {
14350                                if (DEBUG_BACKUP) {
14351                                    Slog.i(TAG, "Package " + packageName
14352                                            + " being restored so deferring FIRST_LAUNCH");
14353                                }
14354                                return;
14355                            }
14356                        }
14357                    }
14358                }
14359                // didn't find it, so not being restored
14360                if (DEBUG_BACKUP) {
14361                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14362                }
14363                final boolean isInstantApp = isInstantApp(packageName, userId);
14364                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14365                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14366                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14367            }
14368        });
14369    }
14370
14371    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14372            int[] userIds, int[] instantUserIds) {
14373        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14374                installerPkg, null, userIds, instantUserIds);
14375    }
14376
14377    private abstract class HandlerParams {
14378        private static final int MAX_RETRIES = 4;
14379
14380        /**
14381         * Number of times startCopy() has been attempted and had a non-fatal
14382         * error.
14383         */
14384        private int mRetries = 0;
14385
14386        /** User handle for the user requesting the information or installation. */
14387        private final UserHandle mUser;
14388        String traceMethod;
14389        int traceCookie;
14390
14391        HandlerParams(UserHandle user) {
14392            mUser = user;
14393        }
14394
14395        UserHandle getUser() {
14396            return mUser;
14397        }
14398
14399        HandlerParams setTraceMethod(String traceMethod) {
14400            this.traceMethod = traceMethod;
14401            return this;
14402        }
14403
14404        HandlerParams setTraceCookie(int traceCookie) {
14405            this.traceCookie = traceCookie;
14406            return this;
14407        }
14408
14409        final boolean startCopy() {
14410            boolean res;
14411            try {
14412                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14413
14414                if (++mRetries > MAX_RETRIES) {
14415                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14416                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14417                    handleServiceError();
14418                    return false;
14419                } else {
14420                    handleStartCopy();
14421                    res = true;
14422                }
14423            } catch (RemoteException e) {
14424                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14425                mHandler.sendEmptyMessage(MCS_RECONNECT);
14426                res = false;
14427            }
14428            handleReturnCode();
14429            return res;
14430        }
14431
14432        final void serviceError() {
14433            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14434            handleServiceError();
14435            handleReturnCode();
14436        }
14437
14438        abstract void handleStartCopy() throws RemoteException;
14439        abstract void handleServiceError();
14440        abstract void handleReturnCode();
14441    }
14442
14443    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14444        for (File path : paths) {
14445            try {
14446                mcs.clearDirectory(path.getAbsolutePath());
14447            } catch (RemoteException e) {
14448            }
14449        }
14450    }
14451
14452    static class OriginInfo {
14453        /**
14454         * Location where install is coming from, before it has been
14455         * copied/renamed into place. This could be a single monolithic APK
14456         * file, or a cluster directory. This location may be untrusted.
14457         */
14458        final File file;
14459
14460        /**
14461         * Flag indicating that {@link #file} or {@link #cid} has already been
14462         * staged, meaning downstream users don't need to defensively copy the
14463         * contents.
14464         */
14465        final boolean staged;
14466
14467        /**
14468         * Flag indicating that {@link #file} or {@link #cid} is an already
14469         * installed app that is being moved.
14470         */
14471        final boolean existing;
14472
14473        final String resolvedPath;
14474        final File resolvedFile;
14475
14476        static OriginInfo fromNothing() {
14477            return new OriginInfo(null, false, false);
14478        }
14479
14480        static OriginInfo fromUntrustedFile(File file) {
14481            return new OriginInfo(file, false, false);
14482        }
14483
14484        static OriginInfo fromExistingFile(File file) {
14485            return new OriginInfo(file, false, true);
14486        }
14487
14488        static OriginInfo fromStagedFile(File file) {
14489            return new OriginInfo(file, true, false);
14490        }
14491
14492        private OriginInfo(File file, boolean staged, boolean existing) {
14493            this.file = file;
14494            this.staged = staged;
14495            this.existing = existing;
14496
14497            if (file != null) {
14498                resolvedPath = file.getAbsolutePath();
14499                resolvedFile = file;
14500            } else {
14501                resolvedPath = null;
14502                resolvedFile = null;
14503            }
14504        }
14505    }
14506
14507    static class MoveInfo {
14508        final int moveId;
14509        final String fromUuid;
14510        final String toUuid;
14511        final String packageName;
14512        final String dataAppName;
14513        final int appId;
14514        final String seinfo;
14515        final int targetSdkVersion;
14516
14517        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14518                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14519            this.moveId = moveId;
14520            this.fromUuid = fromUuid;
14521            this.toUuid = toUuid;
14522            this.packageName = packageName;
14523            this.dataAppName = dataAppName;
14524            this.appId = appId;
14525            this.seinfo = seinfo;
14526            this.targetSdkVersion = targetSdkVersion;
14527        }
14528    }
14529
14530    static class VerificationInfo {
14531        /** A constant used to indicate that a uid value is not present. */
14532        public static final int NO_UID = -1;
14533
14534        /** URI referencing where the package was downloaded from. */
14535        final Uri originatingUri;
14536
14537        /** HTTP referrer URI associated with the originatingURI. */
14538        final Uri referrer;
14539
14540        /** UID of the application that the install request originated from. */
14541        final int originatingUid;
14542
14543        /** UID of application requesting the install */
14544        final int installerUid;
14545
14546        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14547            this.originatingUri = originatingUri;
14548            this.referrer = referrer;
14549            this.originatingUid = originatingUid;
14550            this.installerUid = installerUid;
14551        }
14552    }
14553
14554    class InstallParams extends HandlerParams {
14555        final OriginInfo origin;
14556        final MoveInfo move;
14557        final IPackageInstallObserver2 observer;
14558        int installFlags;
14559        final String installerPackageName;
14560        final String volumeUuid;
14561        private InstallArgs mArgs;
14562        private int mRet;
14563        final String packageAbiOverride;
14564        final String[] grantedRuntimePermissions;
14565        final VerificationInfo verificationInfo;
14566        final Certificate[][] certificates;
14567        final int installReason;
14568
14569        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14570                int installFlags, String installerPackageName, String volumeUuid,
14571                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14572                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14573            super(user);
14574            this.origin = origin;
14575            this.move = move;
14576            this.observer = observer;
14577            this.installFlags = installFlags;
14578            this.installerPackageName = installerPackageName;
14579            this.volumeUuid = volumeUuid;
14580            this.verificationInfo = verificationInfo;
14581            this.packageAbiOverride = packageAbiOverride;
14582            this.grantedRuntimePermissions = grantedPermissions;
14583            this.certificates = certificates;
14584            this.installReason = installReason;
14585        }
14586
14587        @Override
14588        public String toString() {
14589            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14590                    + " file=" + origin.file + "}";
14591        }
14592
14593        private int installLocationPolicy(PackageInfoLite pkgLite) {
14594            String packageName = pkgLite.packageName;
14595            int installLocation = pkgLite.installLocation;
14596            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14597            // reader
14598            synchronized (mPackages) {
14599                // Currently installed package which the new package is attempting to replace or
14600                // null if no such package is installed.
14601                PackageParser.Package installedPkg = mPackages.get(packageName);
14602                // Package which currently owns the data which the new package will own if installed.
14603                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14604                // will be null whereas dataOwnerPkg will contain information about the package
14605                // which was uninstalled while keeping its data.
14606                PackageParser.Package dataOwnerPkg = installedPkg;
14607                if (dataOwnerPkg  == null) {
14608                    PackageSetting ps = mSettings.mPackages.get(packageName);
14609                    if (ps != null) {
14610                        dataOwnerPkg = ps.pkg;
14611                    }
14612                }
14613
14614                if (dataOwnerPkg != null) {
14615                    // If installed, the package will get access to data left on the device by its
14616                    // predecessor. As a security measure, this is permited only if this is not a
14617                    // version downgrade or if the predecessor package is marked as debuggable and
14618                    // a downgrade is explicitly requested.
14619                    //
14620                    // On debuggable platform builds, downgrades are permitted even for
14621                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14622                    // not offer security guarantees and thus it's OK to disable some security
14623                    // mechanisms to make debugging/testing easier on those builds. However, even on
14624                    // debuggable builds downgrades of packages are permitted only if requested via
14625                    // installFlags. This is because we aim to keep the behavior of debuggable
14626                    // platform builds as close as possible to the behavior of non-debuggable
14627                    // platform builds.
14628                    final boolean downgradeRequested =
14629                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14630                    final boolean packageDebuggable =
14631                                (dataOwnerPkg.applicationInfo.flags
14632                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14633                    final boolean downgradePermitted =
14634                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14635                    if (!downgradePermitted) {
14636                        try {
14637                            checkDowngrade(dataOwnerPkg, pkgLite);
14638                        } catch (PackageManagerException e) {
14639                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14640                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14641                        }
14642                    }
14643                }
14644
14645                if (installedPkg != null) {
14646                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14647                        // Check for updated system application.
14648                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14649                            if (onSd) {
14650                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14651                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14652                            }
14653                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14654                        } else {
14655                            if (onSd) {
14656                                // Install flag overrides everything.
14657                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14658                            }
14659                            // If current upgrade specifies particular preference
14660                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14661                                // Application explicitly specified internal.
14662                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14663                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14664                                // App explictly prefers external. Let policy decide
14665                            } else {
14666                                // Prefer previous location
14667                                if (isExternal(installedPkg)) {
14668                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14669                                }
14670                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14671                            }
14672                        }
14673                    } else {
14674                        // Invalid install. Return error code
14675                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14676                    }
14677                }
14678            }
14679            // All the special cases have been taken care of.
14680            // Return result based on recommended install location.
14681            if (onSd) {
14682                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14683            }
14684            return pkgLite.recommendedInstallLocation;
14685        }
14686
14687        /*
14688         * Invoke remote method to get package information and install
14689         * location values. Override install location based on default
14690         * policy if needed and then create install arguments based
14691         * on the install location.
14692         */
14693        public void handleStartCopy() throws RemoteException {
14694            int ret = PackageManager.INSTALL_SUCCEEDED;
14695
14696            // If we're already staged, we've firmly committed to an install location
14697            if (origin.staged) {
14698                if (origin.file != null) {
14699                    installFlags |= PackageManager.INSTALL_INTERNAL;
14700                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14701                } else {
14702                    throw new IllegalStateException("Invalid stage location");
14703                }
14704            }
14705
14706            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14707            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14708            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14709            PackageInfoLite pkgLite = null;
14710
14711            if (onInt && onSd) {
14712                // Check if both bits are set.
14713                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14714                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14715            } else if (onSd && ephemeral) {
14716                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14717                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14718            } else {
14719                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14720                        packageAbiOverride);
14721
14722                if (DEBUG_EPHEMERAL && ephemeral) {
14723                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14724                }
14725
14726                /*
14727                 * If we have too little free space, try to free cache
14728                 * before giving up.
14729                 */
14730                if (!origin.staged && pkgLite.recommendedInstallLocation
14731                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14732                    // TODO: focus freeing disk space on the target device
14733                    final StorageManager storage = StorageManager.from(mContext);
14734                    final long lowThreshold = storage.getStorageLowBytes(
14735                            Environment.getDataDirectory());
14736
14737                    final long sizeBytes = mContainerService.calculateInstalledSize(
14738                            origin.resolvedPath, packageAbiOverride);
14739
14740                    try {
14741                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14742                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14743                                installFlags, packageAbiOverride);
14744                    } catch (InstallerException e) {
14745                        Slog.w(TAG, "Failed to free cache", e);
14746                    }
14747
14748                    /*
14749                     * The cache free must have deleted the file we
14750                     * downloaded to install.
14751                     *
14752                     * TODO: fix the "freeCache" call to not delete
14753                     *       the file we care about.
14754                     */
14755                    if (pkgLite.recommendedInstallLocation
14756                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14757                        pkgLite.recommendedInstallLocation
14758                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14759                    }
14760                }
14761            }
14762
14763            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14764                int loc = pkgLite.recommendedInstallLocation;
14765                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14766                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14767                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14768                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14769                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14770                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14771                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14772                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14773                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14774                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14775                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14776                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14777                } else {
14778                    // Override with defaults if needed.
14779                    loc = installLocationPolicy(pkgLite);
14780                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14781                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14782                    } else if (!onSd && !onInt) {
14783                        // Override install location with flags
14784                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14785                            // Set the flag to install on external media.
14786                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14787                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14788                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14789                            if (DEBUG_EPHEMERAL) {
14790                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14791                            }
14792                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14793                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14794                                    |PackageManager.INSTALL_INTERNAL);
14795                        } else {
14796                            // Make sure the flag for installing on external
14797                            // media is unset
14798                            installFlags |= PackageManager.INSTALL_INTERNAL;
14799                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14800                        }
14801                    }
14802                }
14803            }
14804
14805            final InstallArgs args = createInstallArgs(this);
14806            mArgs = args;
14807
14808            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14809                // TODO: http://b/22976637
14810                // Apps installed for "all" users use the device owner to verify the app
14811                UserHandle verifierUser = getUser();
14812                if (verifierUser == UserHandle.ALL) {
14813                    verifierUser = UserHandle.SYSTEM;
14814                }
14815
14816                /*
14817                 * Determine if we have any installed package verifiers. If we
14818                 * do, then we'll defer to them to verify the packages.
14819                 */
14820                final int requiredUid = mRequiredVerifierPackage == null ? -1
14821                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14822                                verifierUser.getIdentifier());
14823                final int installerUid =
14824                        verificationInfo == null ? -1 : verificationInfo.installerUid;
14825                if (!origin.existing && requiredUid != -1
14826                        && isVerificationEnabled(
14827                                verifierUser.getIdentifier(), installFlags, installerUid)) {
14828                    final Intent verification = new Intent(
14829                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14830                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14831                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14832                            PACKAGE_MIME_TYPE);
14833                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14834
14835                    // Query all live verifiers based on current user state
14836                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14837                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14838                            false /*allowDynamicSplits*/);
14839
14840                    if (DEBUG_VERIFY) {
14841                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14842                                + verification.toString() + " with " + pkgLite.verifiers.length
14843                                + " optional verifiers");
14844                    }
14845
14846                    final int verificationId = mPendingVerificationToken++;
14847
14848                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14849
14850                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14851                            installerPackageName);
14852
14853                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14854                            installFlags);
14855
14856                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14857                            pkgLite.packageName);
14858
14859                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14860                            pkgLite.versionCode);
14861
14862                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14863                            pkgLite.getLongVersionCode());
14864
14865                    if (verificationInfo != null) {
14866                        if (verificationInfo.originatingUri != null) {
14867                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14868                                    verificationInfo.originatingUri);
14869                        }
14870                        if (verificationInfo.referrer != null) {
14871                            verification.putExtra(Intent.EXTRA_REFERRER,
14872                                    verificationInfo.referrer);
14873                        }
14874                        if (verificationInfo.originatingUid >= 0) {
14875                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14876                                    verificationInfo.originatingUid);
14877                        }
14878                        if (verificationInfo.installerUid >= 0) {
14879                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14880                                    verificationInfo.installerUid);
14881                        }
14882                    }
14883
14884                    final PackageVerificationState verificationState = new PackageVerificationState(
14885                            requiredUid, args);
14886
14887                    mPendingVerification.append(verificationId, verificationState);
14888
14889                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14890                            receivers, verificationState);
14891
14892                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14893                    final long idleDuration = getVerificationTimeout();
14894
14895                    /*
14896                     * If any sufficient verifiers were listed in the package
14897                     * manifest, attempt to ask them.
14898                     */
14899                    if (sufficientVerifiers != null) {
14900                        final int N = sufficientVerifiers.size();
14901                        if (N == 0) {
14902                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14903                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14904                        } else {
14905                            for (int i = 0; i < N; i++) {
14906                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14907                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14908                                        verifierComponent.getPackageName(), idleDuration,
14909                                        verifierUser.getIdentifier(), false, "package verifier");
14910
14911                                final Intent sufficientIntent = new Intent(verification);
14912                                sufficientIntent.setComponent(verifierComponent);
14913                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14914                            }
14915                        }
14916                    }
14917
14918                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14919                            mRequiredVerifierPackage, receivers);
14920                    if (ret == PackageManager.INSTALL_SUCCEEDED
14921                            && mRequiredVerifierPackage != null) {
14922                        Trace.asyncTraceBegin(
14923                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14924                        /*
14925                         * Send the intent to the required verification agent,
14926                         * but only start the verification timeout after the
14927                         * target BroadcastReceivers have run.
14928                         */
14929                        verification.setComponent(requiredVerifierComponent);
14930                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14931                                mRequiredVerifierPackage, idleDuration,
14932                                verifierUser.getIdentifier(), false, "package verifier");
14933                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14934                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14935                                new BroadcastReceiver() {
14936                                    @Override
14937                                    public void onReceive(Context context, Intent intent) {
14938                                        final Message msg = mHandler
14939                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14940                                        msg.arg1 = verificationId;
14941                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14942                                    }
14943                                }, null, 0, null, null);
14944
14945                        /*
14946                         * We don't want the copy to proceed until verification
14947                         * succeeds, so null out this field.
14948                         */
14949                        mArgs = null;
14950                    }
14951                } else {
14952                    /*
14953                     * No package verification is enabled, so immediately start
14954                     * the remote call to initiate copy using temporary file.
14955                     */
14956                    ret = args.copyApk(mContainerService, true);
14957                }
14958            }
14959
14960            mRet = ret;
14961        }
14962
14963        @Override
14964        void handleReturnCode() {
14965            // If mArgs is null, then MCS couldn't be reached. When it
14966            // reconnects, it will try again to install. At that point, this
14967            // will succeed.
14968            if (mArgs != null) {
14969                processPendingInstall(mArgs, mRet);
14970            }
14971        }
14972
14973        @Override
14974        void handleServiceError() {
14975            mArgs = createInstallArgs(this);
14976            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14977        }
14978    }
14979
14980    private InstallArgs createInstallArgs(InstallParams params) {
14981        if (params.move != null) {
14982            return new MoveInstallArgs(params);
14983        } else {
14984            return new FileInstallArgs(params);
14985        }
14986    }
14987
14988    /**
14989     * Create args that describe an existing installed package. Typically used
14990     * when cleaning up old installs, or used as a move source.
14991     */
14992    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
14993            String resourcePath, String[] instructionSets) {
14994        return new FileInstallArgs(codePath, resourcePath, instructionSets);
14995    }
14996
14997    static abstract class InstallArgs {
14998        /** @see InstallParams#origin */
14999        final OriginInfo origin;
15000        /** @see InstallParams#move */
15001        final MoveInfo move;
15002
15003        final IPackageInstallObserver2 observer;
15004        // Always refers to PackageManager flags only
15005        final int installFlags;
15006        final String installerPackageName;
15007        final String volumeUuid;
15008        final UserHandle user;
15009        final String abiOverride;
15010        final String[] installGrantPermissions;
15011        /** If non-null, drop an async trace when the install completes */
15012        final String traceMethod;
15013        final int traceCookie;
15014        final Certificate[][] certificates;
15015        final int installReason;
15016
15017        // The list of instruction sets supported by this app. This is currently
15018        // only used during the rmdex() phase to clean up resources. We can get rid of this
15019        // if we move dex files under the common app path.
15020        /* nullable */ String[] instructionSets;
15021
15022        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15023                int installFlags, String installerPackageName, String volumeUuid,
15024                UserHandle user, String[] instructionSets,
15025                String abiOverride, String[] installGrantPermissions,
15026                String traceMethod, int traceCookie, Certificate[][] certificates,
15027                int installReason) {
15028            this.origin = origin;
15029            this.move = move;
15030            this.installFlags = installFlags;
15031            this.observer = observer;
15032            this.installerPackageName = installerPackageName;
15033            this.volumeUuid = volumeUuid;
15034            this.user = user;
15035            this.instructionSets = instructionSets;
15036            this.abiOverride = abiOverride;
15037            this.installGrantPermissions = installGrantPermissions;
15038            this.traceMethod = traceMethod;
15039            this.traceCookie = traceCookie;
15040            this.certificates = certificates;
15041            this.installReason = installReason;
15042        }
15043
15044        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15045        abstract int doPreInstall(int status);
15046
15047        /**
15048         * Rename package into final resting place. All paths on the given
15049         * scanned package should be updated to reflect the rename.
15050         */
15051        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15052        abstract int doPostInstall(int status, int uid);
15053
15054        /** @see PackageSettingBase#codePathString */
15055        abstract String getCodePath();
15056        /** @see PackageSettingBase#resourcePathString */
15057        abstract String getResourcePath();
15058
15059        // Need installer lock especially for dex file removal.
15060        abstract void cleanUpResourcesLI();
15061        abstract boolean doPostDeleteLI(boolean delete);
15062
15063        /**
15064         * Called before the source arguments are copied. This is used mostly
15065         * for MoveParams when it needs to read the source file to put it in the
15066         * destination.
15067         */
15068        int doPreCopy() {
15069            return PackageManager.INSTALL_SUCCEEDED;
15070        }
15071
15072        /**
15073         * Called after the source arguments are copied. This is used mostly for
15074         * MoveParams when it needs to read the source file to put it in the
15075         * destination.
15076         */
15077        int doPostCopy(int uid) {
15078            return PackageManager.INSTALL_SUCCEEDED;
15079        }
15080
15081        protected boolean isFwdLocked() {
15082            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15083        }
15084
15085        protected boolean isExternalAsec() {
15086            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15087        }
15088
15089        protected boolean isEphemeral() {
15090            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15091        }
15092
15093        UserHandle getUser() {
15094            return user;
15095        }
15096    }
15097
15098    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15099        if (!allCodePaths.isEmpty()) {
15100            if (instructionSets == null) {
15101                throw new IllegalStateException("instructionSet == null");
15102            }
15103            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15104            for (String codePath : allCodePaths) {
15105                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15106                    try {
15107                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15108                    } catch (InstallerException ignored) {
15109                    }
15110                }
15111            }
15112        }
15113    }
15114
15115    /**
15116     * Logic to handle installation of non-ASEC applications, including copying
15117     * and renaming logic.
15118     */
15119    class FileInstallArgs extends InstallArgs {
15120        private File codeFile;
15121        private File resourceFile;
15122
15123        // Example topology:
15124        // /data/app/com.example/base.apk
15125        // /data/app/com.example/split_foo.apk
15126        // /data/app/com.example/lib/arm/libfoo.so
15127        // /data/app/com.example/lib/arm64/libfoo.so
15128        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15129
15130        /** New install */
15131        FileInstallArgs(InstallParams params) {
15132            super(params.origin, params.move, params.observer, params.installFlags,
15133                    params.installerPackageName, params.volumeUuid,
15134                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15135                    params.grantedRuntimePermissions,
15136                    params.traceMethod, params.traceCookie, params.certificates,
15137                    params.installReason);
15138            if (isFwdLocked()) {
15139                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15140            }
15141        }
15142
15143        /** Existing install */
15144        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15145            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15146                    null, null, null, 0, null /*certificates*/,
15147                    PackageManager.INSTALL_REASON_UNKNOWN);
15148            this.codeFile = (codePath != null) ? new File(codePath) : null;
15149            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15150        }
15151
15152        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15153            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15154            try {
15155                return doCopyApk(imcs, temp);
15156            } finally {
15157                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15158            }
15159        }
15160
15161        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15162            if (origin.staged) {
15163                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15164                codeFile = origin.file;
15165                resourceFile = origin.file;
15166                return PackageManager.INSTALL_SUCCEEDED;
15167            }
15168
15169            try {
15170                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15171                final File tempDir =
15172                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15173                codeFile = tempDir;
15174                resourceFile = tempDir;
15175            } catch (IOException e) {
15176                Slog.w(TAG, "Failed to create copy file: " + e);
15177                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15178            }
15179
15180            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15181                @Override
15182                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15183                    if (!FileUtils.isValidExtFilename(name)) {
15184                        throw new IllegalArgumentException("Invalid filename: " + name);
15185                    }
15186                    try {
15187                        final File file = new File(codeFile, name);
15188                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15189                                O_RDWR | O_CREAT, 0644);
15190                        Os.chmod(file.getAbsolutePath(), 0644);
15191                        return new ParcelFileDescriptor(fd);
15192                    } catch (ErrnoException e) {
15193                        throw new RemoteException("Failed to open: " + e.getMessage());
15194                    }
15195                }
15196            };
15197
15198            int ret = PackageManager.INSTALL_SUCCEEDED;
15199            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15200            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15201                Slog.e(TAG, "Failed to copy package");
15202                return ret;
15203            }
15204
15205            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15206            NativeLibraryHelper.Handle handle = null;
15207            try {
15208                handle = NativeLibraryHelper.Handle.create(codeFile);
15209                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15210                        abiOverride);
15211            } catch (IOException e) {
15212                Slog.e(TAG, "Copying native libraries failed", e);
15213                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15214            } finally {
15215                IoUtils.closeQuietly(handle);
15216            }
15217
15218            return ret;
15219        }
15220
15221        int doPreInstall(int status) {
15222            if (status != PackageManager.INSTALL_SUCCEEDED) {
15223                cleanUp();
15224            }
15225            return status;
15226        }
15227
15228        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15229            if (status != PackageManager.INSTALL_SUCCEEDED) {
15230                cleanUp();
15231                return false;
15232            }
15233
15234            final File targetDir = codeFile.getParentFile();
15235            final File beforeCodeFile = codeFile;
15236            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15237
15238            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15239            try {
15240                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15241            } catch (ErrnoException e) {
15242                Slog.w(TAG, "Failed to rename", e);
15243                return false;
15244            }
15245
15246            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15247                Slog.w(TAG, "Failed to restorecon");
15248                return false;
15249            }
15250
15251            // Reflect the rename internally
15252            codeFile = afterCodeFile;
15253            resourceFile = afterCodeFile;
15254
15255            // Reflect the rename in scanned details
15256            try {
15257                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15258            } catch (IOException e) {
15259                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15260                return false;
15261            }
15262            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15263                    afterCodeFile, pkg.baseCodePath));
15264            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15265                    afterCodeFile, pkg.splitCodePaths));
15266
15267            // Reflect the rename in app info
15268            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15269            pkg.setApplicationInfoCodePath(pkg.codePath);
15270            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15271            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15272            pkg.setApplicationInfoResourcePath(pkg.codePath);
15273            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15274            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15275
15276            return true;
15277        }
15278
15279        int doPostInstall(int status, int uid) {
15280            if (status != PackageManager.INSTALL_SUCCEEDED) {
15281                cleanUp();
15282            }
15283            return status;
15284        }
15285
15286        @Override
15287        String getCodePath() {
15288            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15289        }
15290
15291        @Override
15292        String getResourcePath() {
15293            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15294        }
15295
15296        private boolean cleanUp() {
15297            if (codeFile == null || !codeFile.exists()) {
15298                return false;
15299            }
15300
15301            removeCodePathLI(codeFile);
15302
15303            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15304                resourceFile.delete();
15305            }
15306
15307            return true;
15308        }
15309
15310        void cleanUpResourcesLI() {
15311            // Try enumerating all code paths before deleting
15312            List<String> allCodePaths = Collections.EMPTY_LIST;
15313            if (codeFile != null && codeFile.exists()) {
15314                try {
15315                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15316                    allCodePaths = pkg.getAllCodePaths();
15317                } catch (PackageParserException e) {
15318                    // Ignored; we tried our best
15319                }
15320            }
15321
15322            cleanUp();
15323            removeDexFiles(allCodePaths, instructionSets);
15324        }
15325
15326        boolean doPostDeleteLI(boolean delete) {
15327            // XXX err, shouldn't we respect the delete flag?
15328            cleanUpResourcesLI();
15329            return true;
15330        }
15331    }
15332
15333    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15334            PackageManagerException {
15335        if (copyRet < 0) {
15336            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15337                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15338                throw new PackageManagerException(copyRet, message);
15339            }
15340        }
15341    }
15342
15343    /**
15344     * Extract the StorageManagerService "container ID" from the full code path of an
15345     * .apk.
15346     */
15347    static String cidFromCodePath(String fullCodePath) {
15348        int eidx = fullCodePath.lastIndexOf("/");
15349        String subStr1 = fullCodePath.substring(0, eidx);
15350        int sidx = subStr1.lastIndexOf("/");
15351        return subStr1.substring(sidx+1, eidx);
15352    }
15353
15354    /**
15355     * Logic to handle movement of existing installed applications.
15356     */
15357    class MoveInstallArgs extends InstallArgs {
15358        private File codeFile;
15359        private File resourceFile;
15360
15361        /** New install */
15362        MoveInstallArgs(InstallParams params) {
15363            super(params.origin, params.move, params.observer, params.installFlags,
15364                    params.installerPackageName, params.volumeUuid,
15365                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15366                    params.grantedRuntimePermissions,
15367                    params.traceMethod, params.traceCookie, params.certificates,
15368                    params.installReason);
15369        }
15370
15371        int copyApk(IMediaContainerService imcs, boolean temp) {
15372            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15373                    + move.fromUuid + " to " + move.toUuid);
15374            synchronized (mInstaller) {
15375                try {
15376                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15377                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15378                } catch (InstallerException e) {
15379                    Slog.w(TAG, "Failed to move app", e);
15380                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15381                }
15382            }
15383
15384            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15385            resourceFile = codeFile;
15386            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15387
15388            return PackageManager.INSTALL_SUCCEEDED;
15389        }
15390
15391        int doPreInstall(int status) {
15392            if (status != PackageManager.INSTALL_SUCCEEDED) {
15393                cleanUp(move.toUuid);
15394            }
15395            return status;
15396        }
15397
15398        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15399            if (status != PackageManager.INSTALL_SUCCEEDED) {
15400                cleanUp(move.toUuid);
15401                return false;
15402            }
15403
15404            // Reflect the move in app info
15405            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15406            pkg.setApplicationInfoCodePath(pkg.codePath);
15407            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15408            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15409            pkg.setApplicationInfoResourcePath(pkg.codePath);
15410            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15411            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15412
15413            return true;
15414        }
15415
15416        int doPostInstall(int status, int uid) {
15417            if (status == PackageManager.INSTALL_SUCCEEDED) {
15418                cleanUp(move.fromUuid);
15419            } else {
15420                cleanUp(move.toUuid);
15421            }
15422            return status;
15423        }
15424
15425        @Override
15426        String getCodePath() {
15427            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15428        }
15429
15430        @Override
15431        String getResourcePath() {
15432            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15433        }
15434
15435        private boolean cleanUp(String volumeUuid) {
15436            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15437                    move.dataAppName);
15438            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15439            final int[] userIds = sUserManager.getUserIds();
15440            synchronized (mInstallLock) {
15441                // Clean up both app data and code
15442                // All package moves are frozen until finished
15443                for (int userId : userIds) {
15444                    try {
15445                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15446                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15447                    } catch (InstallerException e) {
15448                        Slog.w(TAG, String.valueOf(e));
15449                    }
15450                }
15451                removeCodePathLI(codeFile);
15452            }
15453            return true;
15454        }
15455
15456        void cleanUpResourcesLI() {
15457            throw new UnsupportedOperationException();
15458        }
15459
15460        boolean doPostDeleteLI(boolean delete) {
15461            throw new UnsupportedOperationException();
15462        }
15463    }
15464
15465    static String getAsecPackageName(String packageCid) {
15466        int idx = packageCid.lastIndexOf("-");
15467        if (idx == -1) {
15468            return packageCid;
15469        }
15470        return packageCid.substring(0, idx);
15471    }
15472
15473    // Utility method used to create code paths based on package name and available index.
15474    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15475        String idxStr = "";
15476        int idx = 1;
15477        // Fall back to default value of idx=1 if prefix is not
15478        // part of oldCodePath
15479        if (oldCodePath != null) {
15480            String subStr = oldCodePath;
15481            // Drop the suffix right away
15482            if (suffix != null && subStr.endsWith(suffix)) {
15483                subStr = subStr.substring(0, subStr.length() - suffix.length());
15484            }
15485            // If oldCodePath already contains prefix find out the
15486            // ending index to either increment or decrement.
15487            int sidx = subStr.lastIndexOf(prefix);
15488            if (sidx != -1) {
15489                subStr = subStr.substring(sidx + prefix.length());
15490                if (subStr != null) {
15491                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15492                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15493                    }
15494                    try {
15495                        idx = Integer.parseInt(subStr);
15496                        if (idx <= 1) {
15497                            idx++;
15498                        } else {
15499                            idx--;
15500                        }
15501                    } catch(NumberFormatException e) {
15502                    }
15503                }
15504            }
15505        }
15506        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15507        return prefix + idxStr;
15508    }
15509
15510    private File getNextCodePath(File targetDir, String packageName) {
15511        File result;
15512        SecureRandom random = new SecureRandom();
15513        byte[] bytes = new byte[16];
15514        do {
15515            random.nextBytes(bytes);
15516            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15517            result = new File(targetDir, packageName + "-" + suffix);
15518        } while (result.exists());
15519        return result;
15520    }
15521
15522    // Utility method that returns the relative package path with respect
15523    // to the installation directory. Like say for /data/data/com.test-1.apk
15524    // string com.test-1 is returned.
15525    static String deriveCodePathName(String codePath) {
15526        if (codePath == null) {
15527            return null;
15528        }
15529        final File codeFile = new File(codePath);
15530        final String name = codeFile.getName();
15531        if (codeFile.isDirectory()) {
15532            return name;
15533        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15534            final int lastDot = name.lastIndexOf('.');
15535            return name.substring(0, lastDot);
15536        } else {
15537            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15538            return null;
15539        }
15540    }
15541
15542    static class PackageInstalledInfo {
15543        String name;
15544        int uid;
15545        // The set of users that originally had this package installed.
15546        int[] origUsers;
15547        // The set of users that now have this package installed.
15548        int[] newUsers;
15549        PackageParser.Package pkg;
15550        int returnCode;
15551        String returnMsg;
15552        String installerPackageName;
15553        PackageRemovedInfo removedInfo;
15554        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15555
15556        public void setError(int code, String msg) {
15557            setReturnCode(code);
15558            setReturnMessage(msg);
15559            Slog.w(TAG, msg);
15560        }
15561
15562        public void setError(String msg, PackageParserException e) {
15563            setReturnCode(e.error);
15564            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15565            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15566            for (int i = 0; i < childCount; i++) {
15567                addedChildPackages.valueAt(i).setError(msg, e);
15568            }
15569            Slog.w(TAG, msg, e);
15570        }
15571
15572        public void setError(String msg, PackageManagerException e) {
15573            returnCode = e.error;
15574            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15575            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15576            for (int i = 0; i < childCount; i++) {
15577                addedChildPackages.valueAt(i).setError(msg, e);
15578            }
15579            Slog.w(TAG, msg, e);
15580        }
15581
15582        public void setReturnCode(int returnCode) {
15583            this.returnCode = returnCode;
15584            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15585            for (int i = 0; i < childCount; i++) {
15586                addedChildPackages.valueAt(i).returnCode = returnCode;
15587            }
15588        }
15589
15590        private void setReturnMessage(String returnMsg) {
15591            this.returnMsg = returnMsg;
15592            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15593            for (int i = 0; i < childCount; i++) {
15594                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15595            }
15596        }
15597
15598        // In some error cases we want to convey more info back to the observer
15599        String origPackage;
15600        String origPermission;
15601    }
15602
15603    /*
15604     * Install a non-existing package.
15605     */
15606    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15607            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15608            String volumeUuid, PackageInstalledInfo res, int installReason) {
15609        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15610
15611        // Remember this for later, in case we need to rollback this install
15612        String pkgName = pkg.packageName;
15613
15614        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15615
15616        synchronized(mPackages) {
15617            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15618            if (renamedPackage != null) {
15619                // A package with the same name is already installed, though
15620                // it has been renamed to an older name.  The package we
15621                // are trying to install should be installed as an update to
15622                // the existing one, but that has not been requested, so bail.
15623                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15624                        + " without first uninstalling package running as "
15625                        + renamedPackage);
15626                return;
15627            }
15628            if (mPackages.containsKey(pkgName)) {
15629                // Don't allow installation over an existing package with the same name.
15630                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15631                        + " without first uninstalling.");
15632                return;
15633            }
15634        }
15635
15636        try {
15637            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15638                    System.currentTimeMillis(), user);
15639
15640            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15641
15642            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15643                prepareAppDataAfterInstallLIF(newPackage);
15644
15645            } else {
15646                // Remove package from internal structures, but keep around any
15647                // data that might have already existed
15648                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15649                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15650            }
15651        } catch (PackageManagerException e) {
15652            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15653        }
15654
15655        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15656    }
15657
15658    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15659        try (DigestInputStream digestStream =
15660                new DigestInputStream(new FileInputStream(file), digest)) {
15661            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15662        }
15663    }
15664
15665    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15666            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15667            PackageInstalledInfo res, int installReason) {
15668        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15669
15670        final PackageParser.Package oldPackage;
15671        final PackageSetting ps;
15672        final String pkgName = pkg.packageName;
15673        final int[] allUsers;
15674        final int[] installedUsers;
15675
15676        synchronized(mPackages) {
15677            oldPackage = mPackages.get(pkgName);
15678            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15679
15680            // don't allow upgrade to target a release SDK from a pre-release SDK
15681            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15682                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15683            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15684                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15685            if (oldTargetsPreRelease
15686                    && !newTargetsPreRelease
15687                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15688                Slog.w(TAG, "Can't install package targeting released sdk");
15689                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15690                return;
15691            }
15692
15693            ps = mSettings.mPackages.get(pkgName);
15694
15695            // verify signatures are valid
15696            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
15697            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
15698                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
15699                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15700                            "New package not signed by keys specified by upgrade-keysets: "
15701                                    + pkgName);
15702                    return;
15703                }
15704            } else {
15705                // default to original signature matching
15706                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
15707                        != PackageManager.SIGNATURE_MATCH) {
15708                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15709                            "New package has a different signature: " + pkgName);
15710                    return;
15711                }
15712            }
15713
15714            // don't allow a system upgrade unless the upgrade hash matches
15715            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
15716                byte[] digestBytes = null;
15717                try {
15718                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15719                    updateDigest(digest, new File(pkg.baseCodePath));
15720                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15721                        for (String path : pkg.splitCodePaths) {
15722                            updateDigest(digest, new File(path));
15723                        }
15724                    }
15725                    digestBytes = digest.digest();
15726                } catch (NoSuchAlgorithmException | IOException e) {
15727                    res.setError(INSTALL_FAILED_INVALID_APK,
15728                            "Could not compute hash: " + pkgName);
15729                    return;
15730                }
15731                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15732                    res.setError(INSTALL_FAILED_INVALID_APK,
15733                            "New package fails restrict-update check: " + pkgName);
15734                    return;
15735                }
15736                // retain upgrade restriction
15737                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15738            }
15739
15740            // Check for shared user id changes
15741            String invalidPackageName =
15742                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15743            if (invalidPackageName != null) {
15744                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15745                        "Package " + invalidPackageName + " tried to change user "
15746                                + oldPackage.mSharedUserId);
15747                return;
15748            }
15749
15750            // check if the new package supports all of the abis which the old package supports
15751            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
15752            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
15753            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
15754                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15755                        "Update to package " + pkgName + " doesn't support multi arch");
15756                return;
15757            }
15758
15759            // In case of rollback, remember per-user/profile install state
15760            allUsers = sUserManager.getUserIds();
15761            installedUsers = ps.queryInstalledUsers(allUsers, true);
15762
15763            // don't allow an upgrade from full to ephemeral
15764            if (isInstantApp) {
15765                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
15766                    for (int currentUser : allUsers) {
15767                        if (!ps.getInstantApp(currentUser)) {
15768                            // can't downgrade from full to instant
15769                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15770                                    + " for user: " + currentUser);
15771                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15772                            return;
15773                        }
15774                    }
15775                } else if (!ps.getInstantApp(user.getIdentifier())) {
15776                    // can't downgrade from full to instant
15777                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15778                            + " for user: " + user.getIdentifier());
15779                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15780                    return;
15781                }
15782            }
15783        }
15784
15785        // Update what is removed
15786        res.removedInfo = new PackageRemovedInfo(this);
15787        res.removedInfo.uid = oldPackage.applicationInfo.uid;
15788        res.removedInfo.removedPackage = oldPackage.packageName;
15789        res.removedInfo.installerPackageName = ps.installerPackageName;
15790        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15791        res.removedInfo.isUpdate = true;
15792        res.removedInfo.origUsers = installedUsers;
15793        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15794        for (int i = 0; i < installedUsers.length; i++) {
15795            final int userId = installedUsers[i];
15796            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15797        }
15798
15799        final int childCount = (oldPackage.childPackages != null)
15800                ? oldPackage.childPackages.size() : 0;
15801        for (int i = 0; i < childCount; i++) {
15802            boolean childPackageUpdated = false;
15803            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15804            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15805            if (res.addedChildPackages != null) {
15806                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15807                if (childRes != null) {
15808                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15809                    childRes.removedInfo.removedPackage = childPkg.packageName;
15810                    if (childPs != null) {
15811                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
15812                    }
15813                    childRes.removedInfo.isUpdate = true;
15814                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15815                    childPackageUpdated = true;
15816                }
15817            }
15818            if (!childPackageUpdated) {
15819                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
15820                childRemovedRes.removedPackage = childPkg.packageName;
15821                if (childPs != null) {
15822                    childRemovedRes.installerPackageName = childPs.installerPackageName;
15823                }
15824                childRemovedRes.isUpdate = false;
15825                childRemovedRes.dataRemoved = true;
15826                synchronized (mPackages) {
15827                    if (childPs != null) {
15828                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15829                    }
15830                }
15831                if (res.removedInfo.removedChildPackages == null) {
15832                    res.removedInfo.removedChildPackages = new ArrayMap<>();
15833                }
15834                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15835            }
15836        }
15837
15838        boolean sysPkg = (isSystemApp(oldPackage));
15839        if (sysPkg) {
15840            // Set the system/privileged/oem/vendor flags as needed
15841            final boolean privileged =
15842                    (oldPackage.applicationInfo.privateFlags
15843                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15844            final boolean oem =
15845                    (oldPackage.applicationInfo.privateFlags
15846                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
15847            final boolean vendor =
15848                    (oldPackage.applicationInfo.privateFlags
15849                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
15850            final @ParseFlags int systemParseFlags = parseFlags;
15851            final @ScanFlags int systemScanFlags = scanFlags
15852                    | SCAN_AS_SYSTEM
15853                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
15854                    | (oem ? SCAN_AS_OEM : 0)
15855                    | (vendor ? SCAN_AS_VENDOR : 0);
15856
15857            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
15858                    user, allUsers, installerPackageName, res, installReason);
15859        } else {
15860            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
15861                    user, allUsers, installerPackageName, res, installReason);
15862        }
15863    }
15864
15865    @Override
15866    public List<String> getPreviousCodePaths(String packageName) {
15867        final int callingUid = Binder.getCallingUid();
15868        final List<String> result = new ArrayList<>();
15869        if (getInstantAppPackageName(callingUid) != null) {
15870            return result;
15871        }
15872        final PackageSetting ps = mSettings.mPackages.get(packageName);
15873        if (ps != null
15874                && ps.oldCodePaths != null
15875                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15876            result.addAll(ps.oldCodePaths);
15877        }
15878        return result;
15879    }
15880
15881    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15882            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15883            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
15884            String installerPackageName, PackageInstalledInfo res, int installReason) {
15885        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15886                + deletedPackage);
15887
15888        String pkgName = deletedPackage.packageName;
15889        boolean deletedPkg = true;
15890        boolean addedPkg = false;
15891        boolean updatedSettings = false;
15892        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15893        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15894                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15895
15896        final long origUpdateTime = (pkg.mExtras != null)
15897                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15898
15899        // First delete the existing package while retaining the data directory
15900        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15901                res.removedInfo, true, pkg)) {
15902            // If the existing package wasn't successfully deleted
15903            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15904            deletedPkg = false;
15905        } else {
15906            // Successfully deleted the old package; proceed with replace.
15907
15908            // If deleted package lived in a container, give users a chance to
15909            // relinquish resources before killing.
15910            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
15911                if (DEBUG_INSTALL) {
15912                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
15913                }
15914                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
15915                final ArrayList<String> pkgList = new ArrayList<String>(1);
15916                pkgList.add(deletedPackage.applicationInfo.packageName);
15917                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
15918            }
15919
15920            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15921                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15922            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15923
15924            try {
15925                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
15926                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
15927                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15928                        installReason);
15929
15930                // Update the in-memory copy of the previous code paths.
15931                PackageSetting ps = mSettings.mPackages.get(pkgName);
15932                if (!killApp) {
15933                    if (ps.oldCodePaths == null) {
15934                        ps.oldCodePaths = new ArraySet<>();
15935                    }
15936                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
15937                    if (deletedPackage.splitCodePaths != null) {
15938                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
15939                    }
15940                } else {
15941                    ps.oldCodePaths = null;
15942                }
15943                if (ps.childPackageNames != null) {
15944                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
15945                        final String childPkgName = ps.childPackageNames.get(i);
15946                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
15947                        childPs.oldCodePaths = ps.oldCodePaths;
15948                    }
15949                }
15950                // set instant app status, but, only if it's explicitly specified
15951                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15952                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
15953                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
15954                prepareAppDataAfterInstallLIF(newPackage);
15955                addedPkg = true;
15956                mDexManager.notifyPackageUpdated(newPackage.packageName,
15957                        newPackage.baseCodePath, newPackage.splitCodePaths);
15958            } catch (PackageManagerException e) {
15959                res.setError("Package couldn't be installed in " + pkg.codePath, e);
15960            }
15961        }
15962
15963        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15964            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
15965
15966            // Revert all internal state mutations and added folders for the failed install
15967            if (addedPkg) {
15968                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15969                        res.removedInfo, true, null);
15970            }
15971
15972            // Restore the old package
15973            if (deletedPkg) {
15974                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
15975                File restoreFile = new File(deletedPackage.codePath);
15976                // Parse old package
15977                boolean oldExternal = isExternal(deletedPackage);
15978                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
15979                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
15980                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
15981                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
15982                try {
15983                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
15984                            null);
15985                } catch (PackageManagerException e) {
15986                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
15987                            + e.getMessage());
15988                    return;
15989                }
15990
15991                synchronized (mPackages) {
15992                    // Ensure the installer package name up to date
15993                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
15994
15995                    // Update permissions for restored package
15996                    mPermissionManager.updatePermissions(
15997                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
15998                            mPermissionCallback);
15999
16000                    mSettings.writeLPr();
16001                }
16002
16003                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16004            }
16005        } else {
16006            synchronized (mPackages) {
16007                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16008                if (ps != null) {
16009                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16010                    if (res.removedInfo.removedChildPackages != null) {
16011                        final int childCount = res.removedInfo.removedChildPackages.size();
16012                        // Iterate in reverse as we may modify the collection
16013                        for (int i = childCount - 1; i >= 0; i--) {
16014                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16015                            if (res.addedChildPackages.containsKey(childPackageName)) {
16016                                res.removedInfo.removedChildPackages.removeAt(i);
16017                            } else {
16018                                PackageRemovedInfo childInfo = res.removedInfo
16019                                        .removedChildPackages.valueAt(i);
16020                                childInfo.removedForAllUsers = mPackages.get(
16021                                        childInfo.removedPackage) == null;
16022                            }
16023                        }
16024                    }
16025                }
16026            }
16027        }
16028    }
16029
16030    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16031            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16032            final @ScanFlags int scanFlags, UserHandle user,
16033            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16034            int installReason) {
16035        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16036                + ", old=" + deletedPackage);
16037
16038        final boolean disabledSystem;
16039
16040        // Remove existing system package
16041        removePackageLI(deletedPackage, true);
16042
16043        synchronized (mPackages) {
16044            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16045        }
16046        if (!disabledSystem) {
16047            // We didn't need to disable the .apk as a current system package,
16048            // which means we are replacing another update that is already
16049            // installed.  We need to make sure to delete the older one's .apk.
16050            res.removedInfo.args = createInstallArgsForExisting(0,
16051                    deletedPackage.applicationInfo.getCodePath(),
16052                    deletedPackage.applicationInfo.getResourcePath(),
16053                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16054        } else {
16055            res.removedInfo.args = null;
16056        }
16057
16058        // Successfully disabled the old package. Now proceed with re-installation
16059        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16060                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16061        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16062
16063        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16064        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16065                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16066
16067        PackageParser.Package newPackage = null;
16068        try {
16069            // Add the package to the internal data structures
16070            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16071
16072            // Set the update and install times
16073            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16074            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16075                    System.currentTimeMillis());
16076
16077            // Update the package dynamic state if succeeded
16078            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16079                // Now that the install succeeded make sure we remove data
16080                // directories for any child package the update removed.
16081                final int deletedChildCount = (deletedPackage.childPackages != null)
16082                        ? deletedPackage.childPackages.size() : 0;
16083                final int newChildCount = (newPackage.childPackages != null)
16084                        ? newPackage.childPackages.size() : 0;
16085                for (int i = 0; i < deletedChildCount; i++) {
16086                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16087                    boolean childPackageDeleted = true;
16088                    for (int j = 0; j < newChildCount; j++) {
16089                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16090                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16091                            childPackageDeleted = false;
16092                            break;
16093                        }
16094                    }
16095                    if (childPackageDeleted) {
16096                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16097                                deletedChildPkg.packageName);
16098                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16099                            PackageRemovedInfo removedChildRes = res.removedInfo
16100                                    .removedChildPackages.get(deletedChildPkg.packageName);
16101                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16102                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16103                        }
16104                    }
16105                }
16106
16107                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16108                        installReason);
16109                prepareAppDataAfterInstallLIF(newPackage);
16110
16111                mDexManager.notifyPackageUpdated(newPackage.packageName,
16112                            newPackage.baseCodePath, newPackage.splitCodePaths);
16113            }
16114        } catch (PackageManagerException e) {
16115            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16116            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16117        }
16118
16119        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16120            // Re installation failed. Restore old information
16121            // Remove new pkg information
16122            if (newPackage != null) {
16123                removeInstalledPackageLI(newPackage, true);
16124            }
16125            // Add back the old system package
16126            try {
16127                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16128            } catch (PackageManagerException e) {
16129                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16130            }
16131
16132            synchronized (mPackages) {
16133                if (disabledSystem) {
16134                    enableSystemPackageLPw(deletedPackage);
16135                }
16136
16137                // Ensure the installer package name up to date
16138                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16139
16140                // Update permissions for restored package
16141                mPermissionManager.updatePermissions(
16142                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16143                        mPermissionCallback);
16144
16145                mSettings.writeLPr();
16146            }
16147
16148            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16149                    + " after failed upgrade");
16150        }
16151    }
16152
16153    /**
16154     * Checks whether the parent or any of the child packages have a change shared
16155     * user. For a package to be a valid update the shred users of the parent and
16156     * the children should match. We may later support changing child shared users.
16157     * @param oldPkg The updated package.
16158     * @param newPkg The update package.
16159     * @return The shared user that change between the versions.
16160     */
16161    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16162            PackageParser.Package newPkg) {
16163        // Check parent shared user
16164        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16165            return newPkg.packageName;
16166        }
16167        // Check child shared users
16168        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16169        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16170        for (int i = 0; i < newChildCount; i++) {
16171            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16172            // If this child was present, did it have the same shared user?
16173            for (int j = 0; j < oldChildCount; j++) {
16174                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16175                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16176                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16177                    return newChildPkg.packageName;
16178                }
16179            }
16180        }
16181        return null;
16182    }
16183
16184    private void removeNativeBinariesLI(PackageSetting ps) {
16185        // Remove the lib path for the parent package
16186        if (ps != null) {
16187            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16188            // Remove the lib path for the child packages
16189            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16190            for (int i = 0; i < childCount; i++) {
16191                PackageSetting childPs = null;
16192                synchronized (mPackages) {
16193                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16194                }
16195                if (childPs != null) {
16196                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16197                            .legacyNativeLibraryPathString);
16198                }
16199            }
16200        }
16201    }
16202
16203    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16204        // Enable the parent package
16205        mSettings.enableSystemPackageLPw(pkg.packageName);
16206        // Enable the child packages
16207        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16208        for (int i = 0; i < childCount; i++) {
16209            PackageParser.Package childPkg = pkg.childPackages.get(i);
16210            mSettings.enableSystemPackageLPw(childPkg.packageName);
16211        }
16212    }
16213
16214    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16215            PackageParser.Package newPkg) {
16216        // Disable the parent package (parent always replaced)
16217        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16218        // Disable the child packages
16219        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16220        for (int i = 0; i < childCount; i++) {
16221            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16222            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16223            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16224        }
16225        return disabled;
16226    }
16227
16228    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16229            String installerPackageName) {
16230        // Enable the parent package
16231        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16232        // Enable the child packages
16233        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16234        for (int i = 0; i < childCount; i++) {
16235            PackageParser.Package childPkg = pkg.childPackages.get(i);
16236            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16237        }
16238    }
16239
16240    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16241            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16242        // Update the parent package setting
16243        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16244                res, user, installReason);
16245        // Update the child packages setting
16246        final int childCount = (newPackage.childPackages != null)
16247                ? newPackage.childPackages.size() : 0;
16248        for (int i = 0; i < childCount; i++) {
16249            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16250            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16251            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16252                    childRes.origUsers, childRes, user, installReason);
16253        }
16254    }
16255
16256    private void updateSettingsInternalLI(PackageParser.Package pkg,
16257            String installerPackageName, int[] allUsers, int[] installedForUsers,
16258            PackageInstalledInfo res, UserHandle user, int installReason) {
16259        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16260
16261        String pkgName = pkg.packageName;
16262        synchronized (mPackages) {
16263            //write settings. the installStatus will be incomplete at this stage.
16264            //note that the new package setting would have already been
16265            //added to mPackages. It hasn't been persisted yet.
16266            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16267            // TODO: Remove this write? It's also written at the end of this method
16268            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16269            mSettings.writeLPr();
16270            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16271        }
16272
16273        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16274        synchronized (mPackages) {
16275// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16276            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16277                    mPermissionCallback);
16278            // For system-bundled packages, we assume that installing an upgraded version
16279            // of the package implies that the user actually wants to run that new code,
16280            // so we enable the package.
16281            PackageSetting ps = mSettings.mPackages.get(pkgName);
16282            final int userId = user.getIdentifier();
16283            if (ps != null) {
16284                if (isSystemApp(pkg)) {
16285                    if (DEBUG_INSTALL) {
16286                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16287                    }
16288                    // Enable system package for requested users
16289                    if (res.origUsers != null) {
16290                        for (int origUserId : res.origUsers) {
16291                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16292                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16293                                        origUserId, installerPackageName);
16294                            }
16295                        }
16296                    }
16297                    // Also convey the prior install/uninstall state
16298                    if (allUsers != null && installedForUsers != null) {
16299                        for (int currentUserId : allUsers) {
16300                            final boolean installed = ArrayUtils.contains(
16301                                    installedForUsers, currentUserId);
16302                            if (DEBUG_INSTALL) {
16303                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16304                            }
16305                            ps.setInstalled(installed, currentUserId);
16306                        }
16307                        // these install state changes will be persisted in the
16308                        // upcoming call to mSettings.writeLPr().
16309                    }
16310                }
16311                // It's implied that when a user requests installation, they want the app to be
16312                // installed and enabled.
16313                if (userId != UserHandle.USER_ALL) {
16314                    ps.setInstalled(true, userId);
16315                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16316                }
16317
16318                // When replacing an existing package, preserve the original install reason for all
16319                // users that had the package installed before.
16320                final Set<Integer> previousUserIds = new ArraySet<>();
16321                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16322                    final int installReasonCount = res.removedInfo.installReasons.size();
16323                    for (int i = 0; i < installReasonCount; i++) {
16324                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16325                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16326                        ps.setInstallReason(previousInstallReason, previousUserId);
16327                        previousUserIds.add(previousUserId);
16328                    }
16329                }
16330
16331                // Set install reason for users that are having the package newly installed.
16332                if (userId == UserHandle.USER_ALL) {
16333                    for (int currentUserId : sUserManager.getUserIds()) {
16334                        if (!previousUserIds.contains(currentUserId)) {
16335                            ps.setInstallReason(installReason, currentUserId);
16336                        }
16337                    }
16338                } else if (!previousUserIds.contains(userId)) {
16339                    ps.setInstallReason(installReason, userId);
16340                }
16341                mSettings.writeKernelMappingLPr(ps);
16342            }
16343            res.name = pkgName;
16344            res.uid = pkg.applicationInfo.uid;
16345            res.pkg = pkg;
16346            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16347            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16348            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16349            //to update install status
16350            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16351            mSettings.writeLPr();
16352            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16353        }
16354
16355        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16356    }
16357
16358    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16359        try {
16360            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16361            installPackageLI(args, res);
16362        } finally {
16363            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16364        }
16365    }
16366
16367    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16368        final int installFlags = args.installFlags;
16369        final String installerPackageName = args.installerPackageName;
16370        final String volumeUuid = args.volumeUuid;
16371        final File tmpPackageFile = new File(args.getCodePath());
16372        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16373        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16374                || (args.volumeUuid != null));
16375        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16376        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16377        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16378        final boolean virtualPreload =
16379                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16380        boolean replace = false;
16381        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16382        if (args.move != null) {
16383            // moving a complete application; perform an initial scan on the new install location
16384            scanFlags |= SCAN_INITIAL;
16385        }
16386        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16387            scanFlags |= SCAN_DONT_KILL_APP;
16388        }
16389        if (instantApp) {
16390            scanFlags |= SCAN_AS_INSTANT_APP;
16391        }
16392        if (fullApp) {
16393            scanFlags |= SCAN_AS_FULL_APP;
16394        }
16395        if (virtualPreload) {
16396            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16397        }
16398
16399        // Result object to be returned
16400        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16401        res.installerPackageName = installerPackageName;
16402
16403        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16404
16405        // Sanity check
16406        if (instantApp && (forwardLocked || onExternal)) {
16407            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16408                    + " external=" + onExternal);
16409            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16410            return;
16411        }
16412
16413        // Retrieve PackageSettings and parse package
16414        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16415                | PackageParser.PARSE_ENFORCE_CODE
16416                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16417                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16418                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16419                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16420        PackageParser pp = new PackageParser();
16421        pp.setSeparateProcesses(mSeparateProcesses);
16422        pp.setDisplayMetrics(mMetrics);
16423        pp.setCallback(mPackageParserCallback);
16424
16425        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16426        final PackageParser.Package pkg;
16427        try {
16428            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16429        } catch (PackageParserException e) {
16430            res.setError("Failed parse during installPackageLI", e);
16431            return;
16432        } finally {
16433            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16434        }
16435
16436        // App targetSdkVersion is below min supported version
16437        if (!forceSdk && pkg.applicationInfo.isTargetingDeprecatedSdkVersion()) {
16438            Slog.w(TAG, "App " + pkg.packageName + " targets deprecated sdk");
16439
16440            res.setError(INSTALL_FAILED_NEWER_SDK,
16441                    "App is targeting deprecated sdk (targetSdkVersion should be at least "
16442                    + Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT + ").");
16443            return;
16444        }
16445
16446        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16447        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16448            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
16449            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16450                    "Instant app package must target O");
16451            return;
16452        }
16453        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16454            Slog.w(TAG, "Instant app package " + pkg.packageName
16455                    + " does not target targetSandboxVersion 2");
16456            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16457                    "Instant app package must use targetSanboxVersion 2");
16458            return;
16459        }
16460
16461        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16462            // Static shared libraries have synthetic package names
16463            renameStaticSharedLibraryPackage(pkg);
16464
16465            // No static shared libs on external storage
16466            if (onExternal) {
16467                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16468                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16469                        "Packages declaring static-shared libs cannot be updated");
16470                return;
16471            }
16472        }
16473
16474        // If we are installing a clustered package add results for the children
16475        if (pkg.childPackages != null) {
16476            synchronized (mPackages) {
16477                final int childCount = pkg.childPackages.size();
16478                for (int i = 0; i < childCount; i++) {
16479                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16480                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16481                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16482                    childRes.pkg = childPkg;
16483                    childRes.name = childPkg.packageName;
16484                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16485                    if (childPs != null) {
16486                        childRes.origUsers = childPs.queryInstalledUsers(
16487                                sUserManager.getUserIds(), true);
16488                    }
16489                    if ((mPackages.containsKey(childPkg.packageName))) {
16490                        childRes.removedInfo = new PackageRemovedInfo(this);
16491                        childRes.removedInfo.removedPackage = childPkg.packageName;
16492                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16493                    }
16494                    if (res.addedChildPackages == null) {
16495                        res.addedChildPackages = new ArrayMap<>();
16496                    }
16497                    res.addedChildPackages.put(childPkg.packageName, childRes);
16498                }
16499            }
16500        }
16501
16502        // If package doesn't declare API override, mark that we have an install
16503        // time CPU ABI override.
16504        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16505            pkg.cpuAbiOverride = args.abiOverride;
16506        }
16507
16508        String pkgName = res.name = pkg.packageName;
16509        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16510            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16511                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16512                return;
16513            }
16514        }
16515
16516        try {
16517            // either use what we've been given or parse directly from the APK
16518            if (args.certificates != null) {
16519                try {
16520                    PackageParser.populateCertificates(pkg, args.certificates);
16521                } catch (PackageParserException e) {
16522                    // there was something wrong with the certificates we were given;
16523                    // try to pull them from the APK
16524                    PackageParser.collectCertificates(pkg, parseFlags);
16525                }
16526            } else {
16527                PackageParser.collectCertificates(pkg, parseFlags);
16528            }
16529        } catch (PackageParserException e) {
16530            res.setError("Failed collect during installPackageLI", e);
16531            return;
16532        }
16533
16534        // Get rid of all references to package scan path via parser.
16535        pp = null;
16536        String oldCodePath = null;
16537        boolean systemApp = false;
16538        synchronized (mPackages) {
16539            // Check if installing already existing package
16540            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16541                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16542                if (pkg.mOriginalPackages != null
16543                        && pkg.mOriginalPackages.contains(oldName)
16544                        && mPackages.containsKey(oldName)) {
16545                    // This package is derived from an original package,
16546                    // and this device has been updating from that original
16547                    // name.  We must continue using the original name, so
16548                    // rename the new package here.
16549                    pkg.setPackageName(oldName);
16550                    pkgName = pkg.packageName;
16551                    replace = true;
16552                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16553                            + oldName + " pkgName=" + pkgName);
16554                } else if (mPackages.containsKey(pkgName)) {
16555                    // This package, under its official name, already exists
16556                    // on the device; we should replace it.
16557                    replace = true;
16558                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16559                }
16560
16561                // Child packages are installed through the parent package
16562                if (pkg.parentPackage != null) {
16563                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16564                            "Package " + pkg.packageName + " is child of package "
16565                                    + pkg.parentPackage.parentPackage + ". Child packages "
16566                                    + "can be updated only through the parent package.");
16567                    return;
16568                }
16569
16570                if (replace) {
16571                    // Prevent apps opting out from runtime permissions
16572                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16573                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16574                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16575                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16576                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16577                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16578                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16579                                        + " doesn't support runtime permissions but the old"
16580                                        + " target SDK " + oldTargetSdk + " does.");
16581                        return;
16582                    }
16583                    // Prevent persistent apps from being updated
16584                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16585                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16586                                "Package " + oldPackage.packageName + " is a persistent app. "
16587                                        + "Persistent apps are not updateable.");
16588                        return;
16589                    }
16590                    // Prevent apps from downgrading their targetSandbox.
16591                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16592                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16593                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16594                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16595                                "Package " + pkg.packageName + " new target sandbox "
16596                                + newTargetSandbox + " is incompatible with the previous value of"
16597                                + oldTargetSandbox + ".");
16598                        return;
16599                    }
16600
16601                    // Prevent installing of child packages
16602                    if (oldPackage.parentPackage != null) {
16603                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16604                                "Package " + pkg.packageName + " is child of package "
16605                                        + oldPackage.parentPackage + ". Child packages "
16606                                        + "can be updated only through the parent package.");
16607                        return;
16608                    }
16609                }
16610            }
16611
16612            PackageSetting ps = mSettings.mPackages.get(pkgName);
16613            if (ps != null) {
16614                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16615
16616                // Static shared libs have same package with different versions where
16617                // we internally use a synthetic package name to allow multiple versions
16618                // of the same package, therefore we need to compare signatures against
16619                // the package setting for the latest library version.
16620                PackageSetting signatureCheckPs = ps;
16621                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16622                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16623                    if (libraryEntry != null) {
16624                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16625                    }
16626                }
16627
16628                // Quick sanity check that we're signed correctly if updating;
16629                // we'll check this again later when scanning, but we want to
16630                // bail early here before tripping over redefined permissions.
16631                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16632                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16633                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16634                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16635                                + pkg.packageName + " upgrade keys do not match the "
16636                                + "previously installed version");
16637                        return;
16638                    }
16639                } else {
16640                    try {
16641                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16642                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16643                        final boolean compatMatch = verifySignatures(
16644                                signatureCheckPs, pkg.mSignatures, compareCompat, compareRecover);
16645                        // The new KeySets will be re-added later in the scanning process.
16646                        if (compatMatch) {
16647                            synchronized (mPackages) {
16648                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16649                            }
16650                        }
16651                    } catch (PackageManagerException e) {
16652                        res.setError(e.error, e.getMessage());
16653                        return;
16654                    }
16655                }
16656
16657                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16658                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16659                    systemApp = (ps.pkg.applicationInfo.flags &
16660                            ApplicationInfo.FLAG_SYSTEM) != 0;
16661                }
16662                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16663            }
16664
16665            int N = pkg.permissions.size();
16666            for (int i = N-1; i >= 0; i--) {
16667                final PackageParser.Permission perm = pkg.permissions.get(i);
16668                final BasePermission bp =
16669                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
16670
16671                // Don't allow anyone but the system to define ephemeral permissions.
16672                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16673                        && !systemApp) {
16674                    Slog.w(TAG, "Non-System package " + pkg.packageName
16675                            + " attempting to delcare ephemeral permission "
16676                            + perm.info.name + "; Removing ephemeral.");
16677                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
16678                }
16679
16680                // Check whether the newly-scanned package wants to define an already-defined perm
16681                if (bp != null) {
16682                    // If the defining package is signed with our cert, it's okay.  This
16683                    // also includes the "updating the same package" case, of course.
16684                    // "updating same package" could also involve key-rotation.
16685                    final boolean sigsOk;
16686                    final String sourcePackageName = bp.getSourcePackageName();
16687                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16688                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16689                    if (sourcePackageName.equals(pkg.packageName)
16690                            && (ksms.shouldCheckUpgradeKeySetLocked(
16691                                    sourcePackageSetting, scanFlags))) {
16692                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
16693                    } else {
16694                        sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
16695                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
16696                    }
16697                    if (!sigsOk) {
16698                        // If the owning package is the system itself, we log but allow
16699                        // install to proceed; we fail the install on all other permission
16700                        // redefinitions.
16701                        if (!sourcePackageName.equals("android")) {
16702                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16703                                    + pkg.packageName + " attempting to redeclare permission "
16704                                    + perm.info.name + " already owned by " + sourcePackageName);
16705                            res.origPermission = perm.info.name;
16706                            res.origPackage = sourcePackageName;
16707                            return;
16708                        } else {
16709                            Slog.w(TAG, "Package " + pkg.packageName
16710                                    + " attempting to redeclare system permission "
16711                                    + perm.info.name + "; ignoring new declaration");
16712                            pkg.permissions.remove(i);
16713                        }
16714                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16715                        // Prevent apps to change protection level to dangerous from any other
16716                        // type as this would allow a privilege escalation where an app adds a
16717                        // normal/signature permission in other app's group and later redefines
16718                        // it as dangerous leading to the group auto-grant.
16719                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16720                                == PermissionInfo.PROTECTION_DANGEROUS) {
16721                            if (bp != null && !bp.isRuntime()) {
16722                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16723                                        + "non-runtime permission " + perm.info.name
16724                                        + " to runtime; keeping old protection level");
16725                                perm.info.protectionLevel = bp.getProtectionLevel();
16726                            }
16727                        }
16728                    }
16729                }
16730            }
16731        }
16732
16733        if (systemApp) {
16734            if (onExternal) {
16735                // Abort update; system app can't be replaced with app on sdcard
16736                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16737                        "Cannot install updates to system apps on sdcard");
16738                return;
16739            } else if (instantApp) {
16740                // Abort update; system app can't be replaced with an instant app
16741                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16742                        "Cannot update a system app with an instant app");
16743                return;
16744            }
16745        }
16746
16747        if (args.move != null) {
16748            // We did an in-place move, so dex is ready to roll
16749            scanFlags |= SCAN_NO_DEX;
16750            scanFlags |= SCAN_MOVE;
16751
16752            synchronized (mPackages) {
16753                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16754                if (ps == null) {
16755                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16756                            "Missing settings for moved package " + pkgName);
16757                }
16758
16759                // We moved the entire application as-is, so bring over the
16760                // previously derived ABI information.
16761                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16762                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16763            }
16764
16765        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16766            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16767            scanFlags |= SCAN_NO_DEX;
16768
16769            try {
16770                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16771                    args.abiOverride : pkg.cpuAbiOverride);
16772                final boolean extractNativeLibs = !pkg.isLibrary();
16773                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
16774            } catch (PackageManagerException pme) {
16775                Slog.e(TAG, "Error deriving application ABI", pme);
16776                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16777                return;
16778            }
16779
16780            // Shared libraries for the package need to be updated.
16781            synchronized (mPackages) {
16782                try {
16783                    updateSharedLibrariesLPr(pkg, null);
16784                } catch (PackageManagerException e) {
16785                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16786                }
16787            }
16788        }
16789
16790        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16791            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16792            return;
16793        }
16794
16795        if (!instantApp) {
16796            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16797        } else {
16798            if (DEBUG_DOMAIN_VERIFICATION) {
16799                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16800            }
16801        }
16802
16803        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16804                "installPackageLI")) {
16805            if (replace) {
16806                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16807                    // Static libs have a synthetic package name containing the version
16808                    // and cannot be updated as an update would get a new package name,
16809                    // unless this is the exact same version code which is useful for
16810                    // development.
16811                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16812                    if (existingPkg != null &&
16813                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
16814                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16815                                + "static-shared libs cannot be updated");
16816                        return;
16817                    }
16818                }
16819                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
16820                        installerPackageName, res, args.installReason);
16821            } else {
16822                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16823                        args.user, installerPackageName, volumeUuid, res, args.installReason);
16824            }
16825        }
16826
16827        // Check whether we need to dexopt the app.
16828        //
16829        // NOTE: it is IMPORTANT to call dexopt:
16830        //   - after doRename which will sync the package data from PackageParser.Package and its
16831        //     corresponding ApplicationInfo.
16832        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
16833        //     uid of the application (pkg.applicationInfo.uid).
16834        //     This update happens in place!
16835        //
16836        // We only need to dexopt if the package meets ALL of the following conditions:
16837        //   1) it is not forward locked.
16838        //   2) it is not on on an external ASEC container.
16839        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
16840        //
16841        // Note that we do not dexopt instant apps by default. dexopt can take some time to
16842        // complete, so we skip this step during installation. Instead, we'll take extra time
16843        // the first time the instant app starts. It's preferred to do it this way to provide
16844        // continuous progress to the useur instead of mysteriously blocking somewhere in the
16845        // middle of running an instant app. The default behaviour can be overridden
16846        // via gservices.
16847        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
16848                && !forwardLocked
16849                && !pkg.applicationInfo.isExternalAsec()
16850                && (!instantApp || Global.getInt(mContext.getContentResolver(),
16851                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
16852
16853        if (performDexopt) {
16854            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16855            // Do not run PackageDexOptimizer through the local performDexOpt
16856            // method because `pkg` may not be in `mPackages` yet.
16857            //
16858            // Also, don't fail application installs if the dexopt step fails.
16859            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
16860                    REASON_INSTALL,
16861                    DexoptOptions.DEXOPT_BOOT_COMPLETE);
16862            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16863                    null /* instructionSets */,
16864                    getOrCreateCompilerPackageStats(pkg),
16865                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
16866                    dexoptOptions);
16867            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16868        }
16869
16870        // Notify BackgroundDexOptService that the package has been changed.
16871        // If this is an update of a package which used to fail to compile,
16872        // BackgroundDexOptService will remove it from its blacklist.
16873        // TODO: Layering violation
16874        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
16875
16876        synchronized (mPackages) {
16877            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16878            if (ps != null) {
16879                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16880                ps.setUpdateAvailable(false /*updateAvailable*/);
16881            }
16882
16883            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16884            for (int i = 0; i < childCount; i++) {
16885                PackageParser.Package childPkg = pkg.childPackages.get(i);
16886                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16887                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16888                if (childPs != null) {
16889                    childRes.newUsers = childPs.queryInstalledUsers(
16890                            sUserManager.getUserIds(), true);
16891                }
16892            }
16893
16894            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16895                updateSequenceNumberLP(ps, res.newUsers);
16896                updateInstantAppInstallerLocked(pkgName);
16897            }
16898        }
16899    }
16900
16901    private void startIntentFilterVerifications(int userId, boolean replacing,
16902            PackageParser.Package pkg) {
16903        if (mIntentFilterVerifierComponent == null) {
16904            Slog.w(TAG, "No IntentFilter verification will not be done as "
16905                    + "there is no IntentFilterVerifier available!");
16906            return;
16907        }
16908
16909        final int verifierUid = getPackageUid(
16910                mIntentFilterVerifierComponent.getPackageName(),
16911                MATCH_DEBUG_TRIAGED_MISSING,
16912                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
16913
16914        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16915        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
16916        mHandler.sendMessage(msg);
16917
16918        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16919        for (int i = 0; i < childCount; i++) {
16920            PackageParser.Package childPkg = pkg.childPackages.get(i);
16921            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16922            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
16923            mHandler.sendMessage(msg);
16924        }
16925    }
16926
16927    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
16928            PackageParser.Package pkg) {
16929        int size = pkg.activities.size();
16930        if (size == 0) {
16931            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16932                    "No activity, so no need to verify any IntentFilter!");
16933            return;
16934        }
16935
16936        final boolean hasDomainURLs = hasDomainURLs(pkg);
16937        if (!hasDomainURLs) {
16938            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16939                    "No domain URLs, so no need to verify any IntentFilter!");
16940            return;
16941        }
16942
16943        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
16944                + " if any IntentFilter from the " + size
16945                + " Activities needs verification ...");
16946
16947        int count = 0;
16948        final String packageName = pkg.packageName;
16949
16950        synchronized (mPackages) {
16951            // If this is a new install and we see that we've already run verification for this
16952            // package, we have nothing to do: it means the state was restored from backup.
16953            if (!replacing) {
16954                IntentFilterVerificationInfo ivi =
16955                        mSettings.getIntentFilterVerificationLPr(packageName);
16956                if (ivi != null) {
16957                    if (DEBUG_DOMAIN_VERIFICATION) {
16958                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
16959                                + ivi.getStatusString());
16960                    }
16961                    return;
16962                }
16963            }
16964
16965            // If any filters need to be verified, then all need to be.
16966            boolean needToVerify = false;
16967            for (PackageParser.Activity a : pkg.activities) {
16968                for (ActivityIntentInfo filter : a.intents) {
16969                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
16970                        if (DEBUG_DOMAIN_VERIFICATION) {
16971                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
16972                        }
16973                        needToVerify = true;
16974                        break;
16975                    }
16976                }
16977            }
16978
16979            if (needToVerify) {
16980                final int verificationId = mIntentFilterVerificationToken++;
16981                for (PackageParser.Activity a : pkg.activities) {
16982                    for (ActivityIntentInfo filter : a.intents) {
16983                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
16984                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16985                                    "Verification needed for IntentFilter:" + filter.toString());
16986                            mIntentFilterVerifier.addOneIntentFilterVerification(
16987                                    verifierUid, userId, verificationId, filter, packageName);
16988                            count++;
16989                        }
16990                    }
16991                }
16992            }
16993        }
16994
16995        if (count > 0) {
16996            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
16997                    + " IntentFilter verification" + (count > 1 ? "s" : "")
16998                    +  " for userId:" + userId);
16999            mIntentFilterVerifier.startVerifications(userId);
17000        } else {
17001            if (DEBUG_DOMAIN_VERIFICATION) {
17002                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17003            }
17004        }
17005    }
17006
17007    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17008        final ComponentName cn  = filter.activity.getComponentName();
17009        final String packageName = cn.getPackageName();
17010
17011        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17012                packageName);
17013        if (ivi == null) {
17014            return true;
17015        }
17016        int status = ivi.getStatus();
17017        switch (status) {
17018            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17019            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17020                return true;
17021
17022            default:
17023                // Nothing to do
17024                return false;
17025        }
17026    }
17027
17028    private static boolean isMultiArch(ApplicationInfo info) {
17029        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17030    }
17031
17032    private static boolean isExternal(PackageParser.Package pkg) {
17033        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17034    }
17035
17036    private static boolean isExternal(PackageSetting ps) {
17037        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17038    }
17039
17040    private static boolean isSystemApp(PackageParser.Package pkg) {
17041        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17042    }
17043
17044    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17045        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17046    }
17047
17048    private static boolean isOemApp(PackageParser.Package pkg) {
17049        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17050    }
17051
17052    private static boolean isVendorApp(PackageParser.Package pkg) {
17053        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17054    }
17055
17056    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17057        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17058    }
17059
17060    private static boolean isSystemApp(PackageSetting ps) {
17061        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17062    }
17063
17064    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17065        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17066    }
17067
17068    private int packageFlagsToInstallFlags(PackageSetting ps) {
17069        int installFlags = 0;
17070        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17071            // This existing package was an external ASEC install when we have
17072            // the external flag without a UUID
17073            installFlags |= PackageManager.INSTALL_EXTERNAL;
17074        }
17075        if (ps.isForwardLocked()) {
17076            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17077        }
17078        return installFlags;
17079    }
17080
17081    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17082        if (isExternal(pkg)) {
17083            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17084                return mSettings.getExternalVersion();
17085            } else {
17086                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17087            }
17088        } else {
17089            return mSettings.getInternalVersion();
17090        }
17091    }
17092
17093    private void deleteTempPackageFiles() {
17094        final FilenameFilter filter = new FilenameFilter() {
17095            public boolean accept(File dir, String name) {
17096                return name.startsWith("vmdl") && name.endsWith(".tmp");
17097            }
17098        };
17099        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17100            file.delete();
17101        }
17102    }
17103
17104    @Override
17105    public void deletePackageAsUser(String packageName, int versionCode,
17106            IPackageDeleteObserver observer, int userId, int flags) {
17107        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17108                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17109    }
17110
17111    @Override
17112    public void deletePackageVersioned(VersionedPackage versionedPackage,
17113            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17114        final int callingUid = Binder.getCallingUid();
17115        mContext.enforceCallingOrSelfPermission(
17116                android.Manifest.permission.DELETE_PACKAGES, null);
17117        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17118        Preconditions.checkNotNull(versionedPackage);
17119        Preconditions.checkNotNull(observer);
17120        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17121                PackageManager.VERSION_CODE_HIGHEST,
17122                Long.MAX_VALUE, "versionCode must be >= -1");
17123
17124        final String packageName = versionedPackage.getPackageName();
17125        final long versionCode = versionedPackage.getLongVersionCode();
17126        final String internalPackageName;
17127        synchronized (mPackages) {
17128            // Normalize package name to handle renamed packages and static libs
17129            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17130        }
17131
17132        final int uid = Binder.getCallingUid();
17133        if (!isOrphaned(internalPackageName)
17134                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17135            try {
17136                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17137                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17138                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17139                observer.onUserActionRequired(intent);
17140            } catch (RemoteException re) {
17141            }
17142            return;
17143        }
17144        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17145        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17146        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17147            mContext.enforceCallingOrSelfPermission(
17148                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17149                    "deletePackage for user " + userId);
17150        }
17151
17152        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17153            try {
17154                observer.onPackageDeleted(packageName,
17155                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17156            } catch (RemoteException re) {
17157            }
17158            return;
17159        }
17160
17161        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17162            try {
17163                observer.onPackageDeleted(packageName,
17164                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17165            } catch (RemoteException re) {
17166            }
17167            return;
17168        }
17169
17170        if (DEBUG_REMOVE) {
17171            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17172                    + " deleteAllUsers: " + deleteAllUsers + " version="
17173                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17174                    ? "VERSION_CODE_HIGHEST" : versionCode));
17175        }
17176        // Queue up an async operation since the package deletion may take a little while.
17177        mHandler.post(new Runnable() {
17178            public void run() {
17179                mHandler.removeCallbacks(this);
17180                int returnCode;
17181                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17182                boolean doDeletePackage = true;
17183                if (ps != null) {
17184                    final boolean targetIsInstantApp =
17185                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17186                    doDeletePackage = !targetIsInstantApp
17187                            || canViewInstantApps;
17188                }
17189                if (doDeletePackage) {
17190                    if (!deleteAllUsers) {
17191                        returnCode = deletePackageX(internalPackageName, versionCode,
17192                                userId, deleteFlags);
17193                    } else {
17194                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17195                                internalPackageName, users);
17196                        // If nobody is blocking uninstall, proceed with delete for all users
17197                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17198                            returnCode = deletePackageX(internalPackageName, versionCode,
17199                                    userId, deleteFlags);
17200                        } else {
17201                            // Otherwise uninstall individually for users with blockUninstalls=false
17202                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17203                            for (int userId : users) {
17204                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17205                                    returnCode = deletePackageX(internalPackageName, versionCode,
17206                                            userId, userFlags);
17207                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17208                                        Slog.w(TAG, "Package delete failed for user " + userId
17209                                                + ", returnCode " + returnCode);
17210                                    }
17211                                }
17212                            }
17213                            // The app has only been marked uninstalled for certain users.
17214                            // We still need to report that delete was blocked
17215                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17216                        }
17217                    }
17218                } else {
17219                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17220                }
17221                try {
17222                    observer.onPackageDeleted(packageName, returnCode, null);
17223                } catch (RemoteException e) {
17224                    Log.i(TAG, "Observer no longer exists.");
17225                } //end catch
17226            } //end run
17227        });
17228    }
17229
17230    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17231        if (pkg.staticSharedLibName != null) {
17232            return pkg.manifestPackageName;
17233        }
17234        return pkg.packageName;
17235    }
17236
17237    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17238        // Handle renamed packages
17239        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17240        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17241
17242        // Is this a static library?
17243        LongSparseArray<SharedLibraryEntry> versionedLib =
17244                mStaticLibsByDeclaringPackage.get(packageName);
17245        if (versionedLib == null || versionedLib.size() <= 0) {
17246            return packageName;
17247        }
17248
17249        // Figure out which lib versions the caller can see
17250        LongSparseLongArray versionsCallerCanSee = null;
17251        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17252        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17253                && callingAppId != Process.ROOT_UID) {
17254            versionsCallerCanSee = new LongSparseLongArray();
17255            String libName = versionedLib.valueAt(0).info.getName();
17256            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17257            if (uidPackages != null) {
17258                for (String uidPackage : uidPackages) {
17259                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17260                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17261                    if (libIdx >= 0) {
17262                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17263                        versionsCallerCanSee.append(libVersion, libVersion);
17264                    }
17265                }
17266            }
17267        }
17268
17269        // Caller can see nothing - done
17270        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17271            return packageName;
17272        }
17273
17274        // Find the version the caller can see and the app version code
17275        SharedLibraryEntry highestVersion = null;
17276        final int versionCount = versionedLib.size();
17277        for (int i = 0; i < versionCount; i++) {
17278            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17279            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17280                    libEntry.info.getLongVersion()) < 0) {
17281                continue;
17282            }
17283            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17284            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17285                if (libVersionCode == versionCode) {
17286                    return libEntry.apk;
17287                }
17288            } else if (highestVersion == null) {
17289                highestVersion = libEntry;
17290            } else if (libVersionCode  > highestVersion.info
17291                    .getDeclaringPackage().getLongVersionCode()) {
17292                highestVersion = libEntry;
17293            }
17294        }
17295
17296        if (highestVersion != null) {
17297            return highestVersion.apk;
17298        }
17299
17300        return packageName;
17301    }
17302
17303    boolean isCallerVerifier(int callingUid) {
17304        final int callingUserId = UserHandle.getUserId(callingUid);
17305        return mRequiredVerifierPackage != null &&
17306                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17307    }
17308
17309    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17310        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17311              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17312            return true;
17313        }
17314        final int callingUserId = UserHandle.getUserId(callingUid);
17315        // If the caller installed the pkgName, then allow it to silently uninstall.
17316        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17317            return true;
17318        }
17319
17320        // Allow package verifier to silently uninstall.
17321        if (mRequiredVerifierPackage != null &&
17322                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17323            return true;
17324        }
17325
17326        // Allow package uninstaller to silently uninstall.
17327        if (mRequiredUninstallerPackage != null &&
17328                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17329            return true;
17330        }
17331
17332        // Allow storage manager to silently uninstall.
17333        if (mStorageManagerPackage != null &&
17334                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17335            return true;
17336        }
17337
17338        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17339        // uninstall for device owner provisioning.
17340        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17341                == PERMISSION_GRANTED) {
17342            return true;
17343        }
17344
17345        return false;
17346    }
17347
17348    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17349        int[] result = EMPTY_INT_ARRAY;
17350        for (int userId : userIds) {
17351            if (getBlockUninstallForUser(packageName, userId)) {
17352                result = ArrayUtils.appendInt(result, userId);
17353            }
17354        }
17355        return result;
17356    }
17357
17358    @Override
17359    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17360        final int callingUid = Binder.getCallingUid();
17361        if (getInstantAppPackageName(callingUid) != null
17362                && !isCallerSameApp(packageName, callingUid)) {
17363            return false;
17364        }
17365        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17366    }
17367
17368    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17369        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17370                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17371        try {
17372            if (dpm != null) {
17373                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17374                        /* callingUserOnly =*/ false);
17375                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17376                        : deviceOwnerComponentName.getPackageName();
17377                // Does the package contains the device owner?
17378                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17379                // this check is probably not needed, since DO should be registered as a device
17380                // admin on some user too. (Original bug for this: b/17657954)
17381                if (packageName.equals(deviceOwnerPackageName)) {
17382                    return true;
17383                }
17384                // Does it contain a device admin for any user?
17385                int[] users;
17386                if (userId == UserHandle.USER_ALL) {
17387                    users = sUserManager.getUserIds();
17388                } else {
17389                    users = new int[]{userId};
17390                }
17391                for (int i = 0; i < users.length; ++i) {
17392                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17393                        return true;
17394                    }
17395                }
17396            }
17397        } catch (RemoteException e) {
17398        }
17399        return false;
17400    }
17401
17402    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17403        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17404    }
17405
17406    /**
17407     *  This method is an internal method that could be get invoked either
17408     *  to delete an installed package or to clean up a failed installation.
17409     *  After deleting an installed package, a broadcast is sent to notify any
17410     *  listeners that the package has been removed. For cleaning up a failed
17411     *  installation, the broadcast is not necessary since the package's
17412     *  installation wouldn't have sent the initial broadcast either
17413     *  The key steps in deleting a package are
17414     *  deleting the package information in internal structures like mPackages,
17415     *  deleting the packages base directories through installd
17416     *  updating mSettings to reflect current status
17417     *  persisting settings for later use
17418     *  sending a broadcast if necessary
17419     */
17420    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17421        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17422        final boolean res;
17423
17424        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17425                ? UserHandle.USER_ALL : userId;
17426
17427        if (isPackageDeviceAdmin(packageName, removeUser)) {
17428            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17429            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17430        }
17431
17432        PackageSetting uninstalledPs = null;
17433        PackageParser.Package pkg = null;
17434
17435        // for the uninstall-updates case and restricted profiles, remember the per-
17436        // user handle installed state
17437        int[] allUsers;
17438        synchronized (mPackages) {
17439            uninstalledPs = mSettings.mPackages.get(packageName);
17440            if (uninstalledPs == null) {
17441                Slog.w(TAG, "Not removing non-existent package " + packageName);
17442                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17443            }
17444
17445            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17446                    && uninstalledPs.versionCode != versionCode) {
17447                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17448                        + uninstalledPs.versionCode + " != " + versionCode);
17449                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17450            }
17451
17452            // Static shared libs can be declared by any package, so let us not
17453            // allow removing a package if it provides a lib others depend on.
17454            pkg = mPackages.get(packageName);
17455
17456            allUsers = sUserManager.getUserIds();
17457
17458            if (pkg != null && pkg.staticSharedLibName != null) {
17459                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17460                        pkg.staticSharedLibVersion);
17461                if (libEntry != null) {
17462                    for (int currUserId : allUsers) {
17463                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17464                            continue;
17465                        }
17466                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17467                                libEntry.info, 0, currUserId);
17468                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17469                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17470                                    + " hosting lib " + libEntry.info.getName() + " version "
17471                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17472                                    + " for user " + currUserId);
17473                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17474                        }
17475                    }
17476                }
17477            }
17478
17479            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17480        }
17481
17482        final int freezeUser;
17483        if (isUpdatedSystemApp(uninstalledPs)
17484                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17485            // We're downgrading a system app, which will apply to all users, so
17486            // freeze them all during the downgrade
17487            freezeUser = UserHandle.USER_ALL;
17488        } else {
17489            freezeUser = removeUser;
17490        }
17491
17492        synchronized (mInstallLock) {
17493            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17494            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17495                    deleteFlags, "deletePackageX")) {
17496                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17497                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17498            }
17499            synchronized (mPackages) {
17500                if (res) {
17501                    if (pkg != null) {
17502                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17503                    }
17504                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17505                    updateInstantAppInstallerLocked(packageName);
17506                }
17507            }
17508        }
17509
17510        if (res) {
17511            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17512            info.sendPackageRemovedBroadcasts(killApp);
17513            info.sendSystemPackageUpdatedBroadcasts();
17514            info.sendSystemPackageAppearedBroadcasts();
17515        }
17516        // Force a gc here.
17517        Runtime.getRuntime().gc();
17518        // Delete the resources here after sending the broadcast to let
17519        // other processes clean up before deleting resources.
17520        if (info.args != null) {
17521            synchronized (mInstallLock) {
17522                info.args.doPostDeleteLI(true);
17523            }
17524        }
17525
17526        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17527    }
17528
17529    static class PackageRemovedInfo {
17530        final PackageSender packageSender;
17531        String removedPackage;
17532        String installerPackageName;
17533        int uid = -1;
17534        int removedAppId = -1;
17535        int[] origUsers;
17536        int[] removedUsers = null;
17537        int[] broadcastUsers = null;
17538        int[] instantUserIds = null;
17539        SparseArray<Integer> installReasons;
17540        boolean isRemovedPackageSystemUpdate = false;
17541        boolean isUpdate;
17542        boolean dataRemoved;
17543        boolean removedForAllUsers;
17544        boolean isStaticSharedLib;
17545        // Clean up resources deleted packages.
17546        InstallArgs args = null;
17547        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17548        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17549
17550        PackageRemovedInfo(PackageSender packageSender) {
17551            this.packageSender = packageSender;
17552        }
17553
17554        void sendPackageRemovedBroadcasts(boolean killApp) {
17555            sendPackageRemovedBroadcastInternal(killApp);
17556            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17557            for (int i = 0; i < childCount; i++) {
17558                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17559                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17560            }
17561        }
17562
17563        void sendSystemPackageUpdatedBroadcasts() {
17564            if (isRemovedPackageSystemUpdate) {
17565                sendSystemPackageUpdatedBroadcastsInternal();
17566                final int childCount = (removedChildPackages != null)
17567                        ? removedChildPackages.size() : 0;
17568                for (int i = 0; i < childCount; i++) {
17569                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17570                    if (childInfo.isRemovedPackageSystemUpdate) {
17571                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17572                    }
17573                }
17574            }
17575        }
17576
17577        void sendSystemPackageAppearedBroadcasts() {
17578            final int packageCount = (appearedChildPackages != null)
17579                    ? appearedChildPackages.size() : 0;
17580            for (int i = 0; i < packageCount; i++) {
17581                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17582                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17583                    true /*sendBootCompleted*/, false /*startReceiver*/,
17584                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17585            }
17586        }
17587
17588        private void sendSystemPackageUpdatedBroadcastsInternal() {
17589            Bundle extras = new Bundle(2);
17590            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17591            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17592            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17593                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17594            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17595                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17596            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17597                null, null, 0, removedPackage, null, null, null);
17598            if (installerPackageName != null) {
17599                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17600                        removedPackage, extras, 0 /*flags*/,
17601                        installerPackageName, null, null, null);
17602                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17603                        removedPackage, extras, 0 /*flags*/,
17604                        installerPackageName, null, null, null);
17605            }
17606        }
17607
17608        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17609            // Don't send static shared library removal broadcasts as these
17610            // libs are visible only the the apps that depend on them an one
17611            // cannot remove the library if it has a dependency.
17612            if (isStaticSharedLib) {
17613                return;
17614            }
17615            Bundle extras = new Bundle(2);
17616            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17617            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17618            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17619            if (isUpdate || isRemovedPackageSystemUpdate) {
17620                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17621            }
17622            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17623            if (removedPackage != null) {
17624                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17625                    removedPackage, extras, 0, null /*targetPackage*/, null,
17626                    broadcastUsers, instantUserIds);
17627                if (installerPackageName != null) {
17628                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17629                            removedPackage, extras, 0 /*flags*/,
17630                            installerPackageName, null, broadcastUsers, instantUserIds);
17631                }
17632                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17633                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17634                        removedPackage, extras,
17635                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17636                        null, null, broadcastUsers, instantUserIds);
17637                }
17638            }
17639            if (removedAppId >= 0) {
17640                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17641                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17642                    null, null, broadcastUsers, instantUserIds);
17643            }
17644        }
17645
17646        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17647            removedUsers = userIds;
17648            if (removedUsers == null) {
17649                broadcastUsers = null;
17650                return;
17651            }
17652
17653            broadcastUsers = EMPTY_INT_ARRAY;
17654            instantUserIds = EMPTY_INT_ARRAY;
17655            for (int i = userIds.length - 1; i >= 0; --i) {
17656                final int userId = userIds[i];
17657                if (deletedPackageSetting.getInstantApp(userId)) {
17658                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17659                } else {
17660                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17661                }
17662            }
17663        }
17664    }
17665
17666    /*
17667     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17668     * flag is not set, the data directory is removed as well.
17669     * make sure this flag is set for partially installed apps. If not its meaningless to
17670     * delete a partially installed application.
17671     */
17672    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17673            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17674        String packageName = ps.name;
17675        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17676        // Retrieve object to delete permissions for shared user later on
17677        final PackageParser.Package deletedPkg;
17678        final PackageSetting deletedPs;
17679        // reader
17680        synchronized (mPackages) {
17681            deletedPkg = mPackages.get(packageName);
17682            deletedPs = mSettings.mPackages.get(packageName);
17683            if (outInfo != null) {
17684                outInfo.removedPackage = packageName;
17685                outInfo.installerPackageName = ps.installerPackageName;
17686                outInfo.isStaticSharedLib = deletedPkg != null
17687                        && deletedPkg.staticSharedLibName != null;
17688                outInfo.populateUsers(deletedPs == null ? null
17689                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17690            }
17691        }
17692
17693        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
17694
17695        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17696            final PackageParser.Package resolvedPkg;
17697            if (deletedPkg != null) {
17698                resolvedPkg = deletedPkg;
17699            } else {
17700                // We don't have a parsed package when it lives on an ejected
17701                // adopted storage device, so fake something together
17702                resolvedPkg = new PackageParser.Package(ps.name);
17703                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17704            }
17705            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17706                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17707            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17708            if (outInfo != null) {
17709                outInfo.dataRemoved = true;
17710            }
17711            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17712        }
17713
17714        int removedAppId = -1;
17715
17716        // writer
17717        synchronized (mPackages) {
17718            boolean installedStateChanged = false;
17719            if (deletedPs != null) {
17720                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17721                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17722                    clearDefaultBrowserIfNeeded(packageName);
17723                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17724                    removedAppId = mSettings.removePackageLPw(packageName);
17725                    if (outInfo != null) {
17726                        outInfo.removedAppId = removedAppId;
17727                    }
17728                    mPermissionManager.updatePermissions(
17729                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
17730                    if (deletedPs.sharedUser != null) {
17731                        // Remove permissions associated with package. Since runtime
17732                        // permissions are per user we have to kill the removed package
17733                        // or packages running under the shared user of the removed
17734                        // package if revoking the permissions requested only by the removed
17735                        // package is successful and this causes a change in gids.
17736                        for (int userId : UserManagerService.getInstance().getUserIds()) {
17737                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17738                                    userId);
17739                            if (userIdToKill == UserHandle.USER_ALL
17740                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
17741                                // If gids changed for this user, kill all affected packages.
17742                                mHandler.post(new Runnable() {
17743                                    @Override
17744                                    public void run() {
17745                                        // This has to happen with no lock held.
17746                                        killApplication(deletedPs.name, deletedPs.appId,
17747                                                KILL_APP_REASON_GIDS_CHANGED);
17748                                    }
17749                                });
17750                                break;
17751                            }
17752                        }
17753                    }
17754                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17755                }
17756                // make sure to preserve per-user disabled state if this removal was just
17757                // a downgrade of a system app to the factory package
17758                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17759                    if (DEBUG_REMOVE) {
17760                        Slog.d(TAG, "Propagating install state across downgrade");
17761                    }
17762                    for (int userId : allUserHandles) {
17763                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17764                        if (DEBUG_REMOVE) {
17765                            Slog.d(TAG, "    user " + userId + " => " + installed);
17766                        }
17767                        if (installed != ps.getInstalled(userId)) {
17768                            installedStateChanged = true;
17769                        }
17770                        ps.setInstalled(installed, userId);
17771                    }
17772                }
17773            }
17774            // can downgrade to reader
17775            if (writeSettings) {
17776                // Save settings now
17777                mSettings.writeLPr();
17778            }
17779            if (installedStateChanged) {
17780                mSettings.writeKernelMappingLPr(ps);
17781            }
17782        }
17783        if (removedAppId != -1) {
17784            // A user ID was deleted here. Go through all users and remove it
17785            // from KeyStore.
17786            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17787        }
17788    }
17789
17790    static boolean locationIsPrivileged(String path) {
17791        try {
17792            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
17793            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
17794            return path.startsWith(privilegedAppDir.getCanonicalPath())
17795                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath());
17796        } catch (IOException e) {
17797            Slog.e(TAG, "Unable to access code path " + path);
17798        }
17799        return false;
17800    }
17801
17802    static boolean locationIsOem(String path) {
17803        try {
17804            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
17805        } catch (IOException e) {
17806            Slog.e(TAG, "Unable to access code path " + path);
17807        }
17808        return false;
17809    }
17810
17811    static boolean locationIsVendor(String path) {
17812        try {
17813            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
17814        } catch (IOException e) {
17815            Slog.e(TAG, "Unable to access code path " + path);
17816        }
17817        return false;
17818    }
17819
17820    /*
17821     * Tries to delete system package.
17822     */
17823    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17824            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17825            boolean writeSettings) {
17826        if (deletedPs.parentPackageName != null) {
17827            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17828            return false;
17829        }
17830
17831        final boolean applyUserRestrictions
17832                = (allUserHandles != null) && (outInfo.origUsers != null);
17833        final PackageSetting disabledPs;
17834        // Confirm if the system package has been updated
17835        // An updated system app can be deleted. This will also have to restore
17836        // the system pkg from system partition
17837        // reader
17838        synchronized (mPackages) {
17839            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17840        }
17841
17842        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17843                + " disabledPs=" + disabledPs);
17844
17845        if (disabledPs == null) {
17846            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17847            return false;
17848        } else if (DEBUG_REMOVE) {
17849            Slog.d(TAG, "Deleting system pkg from data partition");
17850        }
17851
17852        if (DEBUG_REMOVE) {
17853            if (applyUserRestrictions) {
17854                Slog.d(TAG, "Remembering install states:");
17855                for (int userId : allUserHandles) {
17856                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17857                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
17858                }
17859            }
17860        }
17861
17862        // Delete the updated package
17863        outInfo.isRemovedPackageSystemUpdate = true;
17864        if (outInfo.removedChildPackages != null) {
17865            final int childCount = (deletedPs.childPackageNames != null)
17866                    ? deletedPs.childPackageNames.size() : 0;
17867            for (int i = 0; i < childCount; i++) {
17868                String childPackageName = deletedPs.childPackageNames.get(i);
17869                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17870                        .contains(childPackageName)) {
17871                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17872                            childPackageName);
17873                    if (childInfo != null) {
17874                        childInfo.isRemovedPackageSystemUpdate = true;
17875                    }
17876                }
17877            }
17878        }
17879
17880        if (disabledPs.versionCode < deletedPs.versionCode) {
17881            // Delete data for downgrades
17882            flags &= ~PackageManager.DELETE_KEEP_DATA;
17883        } else {
17884            // Preserve data by setting flag
17885            flags |= PackageManager.DELETE_KEEP_DATA;
17886        }
17887
17888        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17889                outInfo, writeSettings, disabledPs.pkg);
17890        if (!ret) {
17891            return false;
17892        }
17893
17894        // writer
17895        synchronized (mPackages) {
17896            // NOTE: The system package always needs to be enabled; even if it's for
17897            // a compressed stub. If we don't, installing the system package fails
17898            // during scan [scanning checks the disabled packages]. We will reverse
17899            // this later, after we've "installed" the stub.
17900            // Reinstate the old system package
17901            enableSystemPackageLPw(disabledPs.pkg);
17902            // Remove any native libraries from the upgraded package.
17903            removeNativeBinariesLI(deletedPs);
17904        }
17905
17906        // Install the system package
17907        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
17908        try {
17909            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
17910                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
17911        } catch (PackageManagerException e) {
17912            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
17913                    + e.getMessage());
17914            return false;
17915        } finally {
17916            if (disabledPs.pkg.isStub) {
17917                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
17918            }
17919        }
17920        return true;
17921    }
17922
17923    /**
17924     * Installs a package that's already on the system partition.
17925     */
17926    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
17927            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
17928            @Nullable PermissionsState origPermissionState, boolean writeSettings)
17929                    throws PackageManagerException {
17930        @ParseFlags int parseFlags =
17931                mDefParseFlags
17932                | PackageParser.PARSE_MUST_BE_APK
17933                | PackageParser.PARSE_IS_SYSTEM_DIR;
17934        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
17935        if (isPrivileged || locationIsPrivileged(codePathString)) {
17936            scanFlags |= SCAN_AS_PRIVILEGED;
17937        }
17938        if (locationIsOem(codePathString)) {
17939            scanFlags |= SCAN_AS_OEM;
17940        }
17941        if (locationIsVendor(codePathString)) {
17942            scanFlags |= SCAN_AS_VENDOR;
17943        }
17944
17945        final File codePath = new File(codePathString);
17946        final PackageParser.Package pkg =
17947                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
17948
17949        try {
17950            // update shared libraries for the newly re-installed system package
17951            updateSharedLibrariesLPr(pkg, null);
17952        } catch (PackageManagerException e) {
17953            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17954        }
17955
17956        prepareAppDataAfterInstallLIF(pkg);
17957
17958        // writer
17959        synchronized (mPackages) {
17960            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
17961
17962            // Propagate the permissions state as we do not want to drop on the floor
17963            // runtime permissions. The update permissions method below will take
17964            // care of removing obsolete permissions and grant install permissions.
17965            if (origPermissionState != null) {
17966                ps.getPermissionsState().copyFrom(origPermissionState);
17967            }
17968            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
17969                    mPermissionCallback);
17970
17971            final boolean applyUserRestrictions
17972                    = (allUserHandles != null) && (origUserHandles != null);
17973            if (applyUserRestrictions) {
17974                boolean installedStateChanged = false;
17975                if (DEBUG_REMOVE) {
17976                    Slog.d(TAG, "Propagating install state across reinstall");
17977                }
17978                for (int userId : allUserHandles) {
17979                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
17980                    if (DEBUG_REMOVE) {
17981                        Slog.d(TAG, "    user " + userId + " => " + installed);
17982                    }
17983                    if (installed != ps.getInstalled(userId)) {
17984                        installedStateChanged = true;
17985                    }
17986                    ps.setInstalled(installed, userId);
17987
17988                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17989                }
17990                // Regardless of writeSettings we need to ensure that this restriction
17991                // state propagation is persisted
17992                mSettings.writeAllUsersPackageRestrictionsLPr();
17993                if (installedStateChanged) {
17994                    mSettings.writeKernelMappingLPr(ps);
17995                }
17996            }
17997            // can downgrade to reader here
17998            if (writeSettings) {
17999                mSettings.writeLPr();
18000            }
18001        }
18002        return pkg;
18003    }
18004
18005    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18006            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18007            PackageRemovedInfo outInfo, boolean writeSettings,
18008            PackageParser.Package replacingPackage) {
18009        synchronized (mPackages) {
18010            if (outInfo != null) {
18011                outInfo.uid = ps.appId;
18012            }
18013
18014            if (outInfo != null && outInfo.removedChildPackages != null) {
18015                final int childCount = (ps.childPackageNames != null)
18016                        ? ps.childPackageNames.size() : 0;
18017                for (int i = 0; i < childCount; i++) {
18018                    String childPackageName = ps.childPackageNames.get(i);
18019                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18020                    if (childPs == null) {
18021                        return false;
18022                    }
18023                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18024                            childPackageName);
18025                    if (childInfo != null) {
18026                        childInfo.uid = childPs.appId;
18027                    }
18028                }
18029            }
18030        }
18031
18032        // Delete package data from internal structures and also remove data if flag is set
18033        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18034
18035        // Delete the child packages data
18036        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18037        for (int i = 0; i < childCount; i++) {
18038            PackageSetting childPs;
18039            synchronized (mPackages) {
18040                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18041            }
18042            if (childPs != null) {
18043                PackageRemovedInfo childOutInfo = (outInfo != null
18044                        && outInfo.removedChildPackages != null)
18045                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18046                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18047                        && (replacingPackage != null
18048                        && !replacingPackage.hasChildPackage(childPs.name))
18049                        ? flags & ~DELETE_KEEP_DATA : flags;
18050                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18051                        deleteFlags, writeSettings);
18052            }
18053        }
18054
18055        // Delete application code and resources only for parent packages
18056        if (ps.parentPackageName == null) {
18057            if (deleteCodeAndResources && (outInfo != null)) {
18058                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18059                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18060                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18061            }
18062        }
18063
18064        return true;
18065    }
18066
18067    @Override
18068    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18069            int userId) {
18070        mContext.enforceCallingOrSelfPermission(
18071                android.Manifest.permission.DELETE_PACKAGES, null);
18072        synchronized (mPackages) {
18073            // Cannot block uninstall of static shared libs as they are
18074            // considered a part of the using app (emulating static linking).
18075            // Also static libs are installed always on internal storage.
18076            PackageParser.Package pkg = mPackages.get(packageName);
18077            if (pkg != null && pkg.staticSharedLibName != null) {
18078                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18079                        + " providing static shared library: " + pkg.staticSharedLibName);
18080                return false;
18081            }
18082            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18083            mSettings.writePackageRestrictionsLPr(userId);
18084        }
18085        return true;
18086    }
18087
18088    @Override
18089    public boolean getBlockUninstallForUser(String packageName, int userId) {
18090        synchronized (mPackages) {
18091            final PackageSetting ps = mSettings.mPackages.get(packageName);
18092            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18093                return false;
18094            }
18095            return mSettings.getBlockUninstallLPr(userId, packageName);
18096        }
18097    }
18098
18099    @Override
18100    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18101        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18102        synchronized (mPackages) {
18103            PackageSetting ps = mSettings.mPackages.get(packageName);
18104            if (ps == null) {
18105                Log.w(TAG, "Package doesn't exist: " + packageName);
18106                return false;
18107            }
18108            if (systemUserApp) {
18109                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18110            } else {
18111                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18112            }
18113            mSettings.writeLPr();
18114        }
18115        return true;
18116    }
18117
18118    /*
18119     * This method handles package deletion in general
18120     */
18121    private boolean deletePackageLIF(String packageName, UserHandle user,
18122            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18123            PackageRemovedInfo outInfo, boolean writeSettings,
18124            PackageParser.Package replacingPackage) {
18125        if (packageName == null) {
18126            Slog.w(TAG, "Attempt to delete null packageName.");
18127            return false;
18128        }
18129
18130        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18131
18132        PackageSetting ps;
18133        synchronized (mPackages) {
18134            ps = mSettings.mPackages.get(packageName);
18135            if (ps == null) {
18136                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18137                return false;
18138            }
18139
18140            if (ps.parentPackageName != null && (!isSystemApp(ps)
18141                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18142                if (DEBUG_REMOVE) {
18143                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18144                            + ((user == null) ? UserHandle.USER_ALL : user));
18145                }
18146                final int removedUserId = (user != null) ? user.getIdentifier()
18147                        : UserHandle.USER_ALL;
18148                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18149                    return false;
18150                }
18151                markPackageUninstalledForUserLPw(ps, user);
18152                scheduleWritePackageRestrictionsLocked(user);
18153                return true;
18154            }
18155        }
18156
18157        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18158                && user.getIdentifier() != UserHandle.USER_ALL)) {
18159            // The caller is asking that the package only be deleted for a single
18160            // user.  To do this, we just mark its uninstalled state and delete
18161            // its data. If this is a system app, we only allow this to happen if
18162            // they have set the special DELETE_SYSTEM_APP which requests different
18163            // semantics than normal for uninstalling system apps.
18164            markPackageUninstalledForUserLPw(ps, user);
18165
18166            if (!isSystemApp(ps)) {
18167                // Do not uninstall the APK if an app should be cached
18168                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18169                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18170                    // Other user still have this package installed, so all
18171                    // we need to do is clear this user's data and save that
18172                    // it is uninstalled.
18173                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18174                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18175                        return false;
18176                    }
18177                    scheduleWritePackageRestrictionsLocked(user);
18178                    return true;
18179                } else {
18180                    // We need to set it back to 'installed' so the uninstall
18181                    // broadcasts will be sent correctly.
18182                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18183                    ps.setInstalled(true, user.getIdentifier());
18184                    mSettings.writeKernelMappingLPr(ps);
18185                }
18186            } else {
18187                // This is a system app, so we assume that the
18188                // other users still have this package installed, so all
18189                // we need to do is clear this user's data and save that
18190                // it is uninstalled.
18191                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18192                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18193                    return false;
18194                }
18195                scheduleWritePackageRestrictionsLocked(user);
18196                return true;
18197            }
18198        }
18199
18200        // If we are deleting a composite package for all users, keep track
18201        // of result for each child.
18202        if (ps.childPackageNames != null && outInfo != null) {
18203            synchronized (mPackages) {
18204                final int childCount = ps.childPackageNames.size();
18205                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18206                for (int i = 0; i < childCount; i++) {
18207                    String childPackageName = ps.childPackageNames.get(i);
18208                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18209                    childInfo.removedPackage = childPackageName;
18210                    childInfo.installerPackageName = ps.installerPackageName;
18211                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18212                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18213                    if (childPs != null) {
18214                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18215                    }
18216                }
18217            }
18218        }
18219
18220        boolean ret = false;
18221        if (isSystemApp(ps)) {
18222            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18223            // When an updated system application is deleted we delete the existing resources
18224            // as well and fall back to existing code in system partition
18225            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18226        } else {
18227            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18228            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18229                    outInfo, writeSettings, replacingPackage);
18230        }
18231
18232        // Take a note whether we deleted the package for all users
18233        if (outInfo != null) {
18234            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18235            if (outInfo.removedChildPackages != null) {
18236                synchronized (mPackages) {
18237                    final int childCount = outInfo.removedChildPackages.size();
18238                    for (int i = 0; i < childCount; i++) {
18239                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18240                        if (childInfo != null) {
18241                            childInfo.removedForAllUsers = mPackages.get(
18242                                    childInfo.removedPackage) == null;
18243                        }
18244                    }
18245                }
18246            }
18247            // If we uninstalled an update to a system app there may be some
18248            // child packages that appeared as they are declared in the system
18249            // app but were not declared in the update.
18250            if (isSystemApp(ps)) {
18251                synchronized (mPackages) {
18252                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18253                    final int childCount = (updatedPs.childPackageNames != null)
18254                            ? updatedPs.childPackageNames.size() : 0;
18255                    for (int i = 0; i < childCount; i++) {
18256                        String childPackageName = updatedPs.childPackageNames.get(i);
18257                        if (outInfo.removedChildPackages == null
18258                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18259                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18260                            if (childPs == null) {
18261                                continue;
18262                            }
18263                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18264                            installRes.name = childPackageName;
18265                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18266                            installRes.pkg = mPackages.get(childPackageName);
18267                            installRes.uid = childPs.pkg.applicationInfo.uid;
18268                            if (outInfo.appearedChildPackages == null) {
18269                                outInfo.appearedChildPackages = new ArrayMap<>();
18270                            }
18271                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18272                        }
18273                    }
18274                }
18275            }
18276        }
18277
18278        return ret;
18279    }
18280
18281    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18282        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18283                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18284        for (int nextUserId : userIds) {
18285            if (DEBUG_REMOVE) {
18286                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18287            }
18288            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18289                    false /*installed*/,
18290                    true /*stopped*/,
18291                    true /*notLaunched*/,
18292                    false /*hidden*/,
18293                    false /*suspended*/,
18294                    false /*instantApp*/,
18295                    false /*virtualPreload*/,
18296                    null /*lastDisableAppCaller*/,
18297                    null /*enabledComponents*/,
18298                    null /*disabledComponents*/,
18299                    ps.readUserState(nextUserId).domainVerificationStatus,
18300                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18301        }
18302        mSettings.writeKernelMappingLPr(ps);
18303    }
18304
18305    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18306            PackageRemovedInfo outInfo) {
18307        final PackageParser.Package pkg;
18308        synchronized (mPackages) {
18309            pkg = mPackages.get(ps.name);
18310        }
18311
18312        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18313                : new int[] {userId};
18314        for (int nextUserId : userIds) {
18315            if (DEBUG_REMOVE) {
18316                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18317                        + nextUserId);
18318            }
18319
18320            destroyAppDataLIF(pkg, userId,
18321                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18322            destroyAppProfilesLIF(pkg, userId);
18323            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18324            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18325            schedulePackageCleaning(ps.name, nextUserId, false);
18326            synchronized (mPackages) {
18327                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18328                    scheduleWritePackageRestrictionsLocked(nextUserId);
18329                }
18330                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18331            }
18332        }
18333
18334        if (outInfo != null) {
18335            outInfo.removedPackage = ps.name;
18336            outInfo.installerPackageName = ps.installerPackageName;
18337            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18338            outInfo.removedAppId = ps.appId;
18339            outInfo.removedUsers = userIds;
18340            outInfo.broadcastUsers = userIds;
18341        }
18342
18343        return true;
18344    }
18345
18346    private final class ClearStorageConnection implements ServiceConnection {
18347        IMediaContainerService mContainerService;
18348
18349        @Override
18350        public void onServiceConnected(ComponentName name, IBinder service) {
18351            synchronized (this) {
18352                mContainerService = IMediaContainerService.Stub
18353                        .asInterface(Binder.allowBlocking(service));
18354                notifyAll();
18355            }
18356        }
18357
18358        @Override
18359        public void onServiceDisconnected(ComponentName name) {
18360        }
18361    }
18362
18363    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18364        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18365
18366        final boolean mounted;
18367        if (Environment.isExternalStorageEmulated()) {
18368            mounted = true;
18369        } else {
18370            final String status = Environment.getExternalStorageState();
18371
18372            mounted = status.equals(Environment.MEDIA_MOUNTED)
18373                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18374        }
18375
18376        if (!mounted) {
18377            return;
18378        }
18379
18380        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18381        int[] users;
18382        if (userId == UserHandle.USER_ALL) {
18383            users = sUserManager.getUserIds();
18384        } else {
18385            users = new int[] { userId };
18386        }
18387        final ClearStorageConnection conn = new ClearStorageConnection();
18388        if (mContext.bindServiceAsUser(
18389                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18390            try {
18391                for (int curUser : users) {
18392                    long timeout = SystemClock.uptimeMillis() + 5000;
18393                    synchronized (conn) {
18394                        long now;
18395                        while (conn.mContainerService == null &&
18396                                (now = SystemClock.uptimeMillis()) < timeout) {
18397                            try {
18398                                conn.wait(timeout - now);
18399                            } catch (InterruptedException e) {
18400                            }
18401                        }
18402                    }
18403                    if (conn.mContainerService == null) {
18404                        return;
18405                    }
18406
18407                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18408                    clearDirectory(conn.mContainerService,
18409                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18410                    if (allData) {
18411                        clearDirectory(conn.mContainerService,
18412                                userEnv.buildExternalStorageAppDataDirs(packageName));
18413                        clearDirectory(conn.mContainerService,
18414                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18415                    }
18416                }
18417            } finally {
18418                mContext.unbindService(conn);
18419            }
18420        }
18421    }
18422
18423    @Override
18424    public void clearApplicationProfileData(String packageName) {
18425        enforceSystemOrRoot("Only the system can clear all profile data");
18426
18427        final PackageParser.Package pkg;
18428        synchronized (mPackages) {
18429            pkg = mPackages.get(packageName);
18430        }
18431
18432        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18433            synchronized (mInstallLock) {
18434                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18435            }
18436        }
18437    }
18438
18439    @Override
18440    public void clearApplicationUserData(final String packageName,
18441            final IPackageDataObserver observer, final int userId) {
18442        mContext.enforceCallingOrSelfPermission(
18443                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18444
18445        final int callingUid = Binder.getCallingUid();
18446        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18447                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18448
18449        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18450        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18451        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18452            throw new SecurityException("Cannot clear data for a protected package: "
18453                    + packageName);
18454        }
18455        // Queue up an async operation since the package deletion may take a little while.
18456        mHandler.post(new Runnable() {
18457            public void run() {
18458                mHandler.removeCallbacks(this);
18459                final boolean succeeded;
18460                if (!filterApp) {
18461                    try (PackageFreezer freezer = freezePackage(packageName,
18462                            "clearApplicationUserData")) {
18463                        synchronized (mInstallLock) {
18464                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18465                        }
18466                        clearExternalStorageDataSync(packageName, userId, true);
18467                        synchronized (mPackages) {
18468                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18469                                    packageName, userId);
18470                        }
18471                    }
18472                    if (succeeded) {
18473                        // invoke DeviceStorageMonitor's update method to clear any notifications
18474                        DeviceStorageMonitorInternal dsm = LocalServices
18475                                .getService(DeviceStorageMonitorInternal.class);
18476                        if (dsm != null) {
18477                            dsm.checkMemory();
18478                        }
18479                    }
18480                } else {
18481                    succeeded = false;
18482                }
18483                if (observer != null) {
18484                    try {
18485                        observer.onRemoveCompleted(packageName, succeeded);
18486                    } catch (RemoteException e) {
18487                        Log.i(TAG, "Observer no longer exists.");
18488                    }
18489                } //end if observer
18490            } //end run
18491        });
18492    }
18493
18494    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18495        if (packageName == null) {
18496            Slog.w(TAG, "Attempt to delete null packageName.");
18497            return false;
18498        }
18499
18500        // Try finding details about the requested package
18501        PackageParser.Package pkg;
18502        synchronized (mPackages) {
18503            pkg = mPackages.get(packageName);
18504            if (pkg == null) {
18505                final PackageSetting ps = mSettings.mPackages.get(packageName);
18506                if (ps != null) {
18507                    pkg = ps.pkg;
18508                }
18509            }
18510
18511            if (pkg == null) {
18512                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18513                return false;
18514            }
18515
18516            PackageSetting ps = (PackageSetting) pkg.mExtras;
18517            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18518        }
18519
18520        clearAppDataLIF(pkg, userId,
18521                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18522
18523        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18524        removeKeystoreDataIfNeeded(userId, appId);
18525
18526        UserManagerInternal umInternal = getUserManagerInternal();
18527        final int flags;
18528        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18529            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18530        } else if (umInternal.isUserRunning(userId)) {
18531            flags = StorageManager.FLAG_STORAGE_DE;
18532        } else {
18533            flags = 0;
18534        }
18535        prepareAppDataContentsLIF(pkg, userId, flags);
18536
18537        return true;
18538    }
18539
18540    /**
18541     * Reverts user permission state changes (permissions and flags) in
18542     * all packages for a given user.
18543     *
18544     * @param userId The device user for which to do a reset.
18545     */
18546    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18547        final int packageCount = mPackages.size();
18548        for (int i = 0; i < packageCount; i++) {
18549            PackageParser.Package pkg = mPackages.valueAt(i);
18550            PackageSetting ps = (PackageSetting) pkg.mExtras;
18551            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18552        }
18553    }
18554
18555    private void resetNetworkPolicies(int userId) {
18556        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18557    }
18558
18559    /**
18560     * Reverts user permission state changes (permissions and flags).
18561     *
18562     * @param ps The package for which to reset.
18563     * @param userId The device user for which to do a reset.
18564     */
18565    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18566            final PackageSetting ps, final int userId) {
18567        if (ps.pkg == null) {
18568            return;
18569        }
18570
18571        // These are flags that can change base on user actions.
18572        final int userSettableMask = FLAG_PERMISSION_USER_SET
18573                | FLAG_PERMISSION_USER_FIXED
18574                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18575                | FLAG_PERMISSION_REVIEW_REQUIRED;
18576
18577        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18578                | FLAG_PERMISSION_POLICY_FIXED;
18579
18580        boolean writeInstallPermissions = false;
18581        boolean writeRuntimePermissions = false;
18582
18583        final int permissionCount = ps.pkg.requestedPermissions.size();
18584        for (int i = 0; i < permissionCount; i++) {
18585            final String permName = ps.pkg.requestedPermissions.get(i);
18586            final BasePermission bp =
18587                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
18588            if (bp == null) {
18589                continue;
18590            }
18591
18592            // If shared user we just reset the state to which only this app contributed.
18593            if (ps.sharedUser != null) {
18594                boolean used = false;
18595                final int packageCount = ps.sharedUser.packages.size();
18596                for (int j = 0; j < packageCount; j++) {
18597                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18598                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18599                            && pkg.pkg.requestedPermissions.contains(permName)) {
18600                        used = true;
18601                        break;
18602                    }
18603                }
18604                if (used) {
18605                    continue;
18606                }
18607            }
18608
18609            final PermissionsState permissionsState = ps.getPermissionsState();
18610
18611            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
18612
18613            // Always clear the user settable flags.
18614            final boolean hasInstallState =
18615                    permissionsState.getInstallPermissionState(permName) != null;
18616            // If permission review is enabled and this is a legacy app, mark the
18617            // permission as requiring a review as this is the initial state.
18618            int flags = 0;
18619            if (mSettings.mPermissions.mPermissionReviewRequired
18620                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18621                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18622            }
18623            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18624                if (hasInstallState) {
18625                    writeInstallPermissions = true;
18626                } else {
18627                    writeRuntimePermissions = true;
18628                }
18629            }
18630
18631            // Below is only runtime permission handling.
18632            if (!bp.isRuntime()) {
18633                continue;
18634            }
18635
18636            // Never clobber system or policy.
18637            if ((oldFlags & policyOrSystemFlags) != 0) {
18638                continue;
18639            }
18640
18641            // If this permission was granted by default, make sure it is.
18642            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18643                if (permissionsState.grantRuntimePermission(bp, userId)
18644                        != PERMISSION_OPERATION_FAILURE) {
18645                    writeRuntimePermissions = true;
18646                }
18647            // If permission review is enabled the permissions for a legacy apps
18648            // are represented as constantly granted runtime ones, so don't revoke.
18649            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18650                // Otherwise, reset the permission.
18651                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18652                switch (revokeResult) {
18653                    case PERMISSION_OPERATION_SUCCESS:
18654                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18655                        writeRuntimePermissions = true;
18656                        final int appId = ps.appId;
18657                        mHandler.post(new Runnable() {
18658                            @Override
18659                            public void run() {
18660                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18661                            }
18662                        });
18663                    } break;
18664                }
18665            }
18666        }
18667
18668        // Synchronously write as we are taking permissions away.
18669        if (writeRuntimePermissions) {
18670            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18671        }
18672
18673        // Synchronously write as we are taking permissions away.
18674        if (writeInstallPermissions) {
18675            mSettings.writeLPr();
18676        }
18677    }
18678
18679    /**
18680     * Remove entries from the keystore daemon. Will only remove it if the
18681     * {@code appId} is valid.
18682     */
18683    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18684        if (appId < 0) {
18685            return;
18686        }
18687
18688        final KeyStore keyStore = KeyStore.getInstance();
18689        if (keyStore != null) {
18690            if (userId == UserHandle.USER_ALL) {
18691                for (final int individual : sUserManager.getUserIds()) {
18692                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18693                }
18694            } else {
18695                keyStore.clearUid(UserHandle.getUid(userId, appId));
18696            }
18697        } else {
18698            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18699        }
18700    }
18701
18702    @Override
18703    public void deleteApplicationCacheFiles(final String packageName,
18704            final IPackageDataObserver observer) {
18705        final int userId = UserHandle.getCallingUserId();
18706        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18707    }
18708
18709    @Override
18710    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18711            final IPackageDataObserver observer) {
18712        final int callingUid = Binder.getCallingUid();
18713        mContext.enforceCallingOrSelfPermission(
18714                android.Manifest.permission.DELETE_CACHE_FILES, null);
18715        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18716                /* requireFullPermission= */ true, /* checkShell= */ false,
18717                "delete application cache files");
18718        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18719                android.Manifest.permission.ACCESS_INSTANT_APPS);
18720
18721        final PackageParser.Package pkg;
18722        synchronized (mPackages) {
18723            pkg = mPackages.get(packageName);
18724        }
18725
18726        // Queue up an async operation since the package deletion may take a little while.
18727        mHandler.post(new Runnable() {
18728            public void run() {
18729                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
18730                boolean doClearData = true;
18731                if (ps != null) {
18732                    final boolean targetIsInstantApp =
18733                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18734                    doClearData = !targetIsInstantApp
18735                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18736                }
18737                if (doClearData) {
18738                    synchronized (mInstallLock) {
18739                        final int flags = StorageManager.FLAG_STORAGE_DE
18740                                | StorageManager.FLAG_STORAGE_CE;
18741                        // We're only clearing cache files, so we don't care if the
18742                        // app is unfrozen and still able to run
18743                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18744                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18745                    }
18746                    clearExternalStorageDataSync(packageName, userId, false);
18747                }
18748                if (observer != null) {
18749                    try {
18750                        observer.onRemoveCompleted(packageName, true);
18751                    } catch (RemoteException e) {
18752                        Log.i(TAG, "Observer no longer exists.");
18753                    }
18754                }
18755            }
18756        });
18757    }
18758
18759    @Override
18760    public void getPackageSizeInfo(final String packageName, int userHandle,
18761            final IPackageStatsObserver observer) {
18762        throw new UnsupportedOperationException(
18763                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18764    }
18765
18766    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18767        final PackageSetting ps;
18768        synchronized (mPackages) {
18769            ps = mSettings.mPackages.get(packageName);
18770            if (ps == null) {
18771                Slog.w(TAG, "Failed to find settings for " + packageName);
18772                return false;
18773            }
18774        }
18775
18776        final String[] packageNames = { packageName };
18777        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18778        final String[] codePaths = { ps.codePathString };
18779
18780        try {
18781            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18782                    ps.appId, ceDataInodes, codePaths, stats);
18783
18784            // For now, ignore code size of packages on system partition
18785            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18786                stats.codeSize = 0;
18787            }
18788
18789            // External clients expect these to be tracked separately
18790            stats.dataSize -= stats.cacheSize;
18791
18792        } catch (InstallerException e) {
18793            Slog.w(TAG, String.valueOf(e));
18794            return false;
18795        }
18796
18797        return true;
18798    }
18799
18800    private int getUidTargetSdkVersionLockedLPr(int uid) {
18801        Object obj = mSettings.getUserIdLPr(uid);
18802        if (obj instanceof SharedUserSetting) {
18803            final SharedUserSetting sus = (SharedUserSetting) obj;
18804            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18805            final Iterator<PackageSetting> it = sus.packages.iterator();
18806            while (it.hasNext()) {
18807                final PackageSetting ps = it.next();
18808                if (ps.pkg != null) {
18809                    int v = ps.pkg.applicationInfo.targetSdkVersion;
18810                    if (v < vers) vers = v;
18811                }
18812            }
18813            return vers;
18814        } else if (obj instanceof PackageSetting) {
18815            final PackageSetting ps = (PackageSetting) obj;
18816            if (ps.pkg != null) {
18817                return ps.pkg.applicationInfo.targetSdkVersion;
18818            }
18819        }
18820        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18821    }
18822
18823    @Override
18824    public void addPreferredActivity(IntentFilter filter, int match,
18825            ComponentName[] set, ComponentName activity, int userId) {
18826        addPreferredActivityInternal(filter, match, set, activity, true, userId,
18827                "Adding preferred");
18828    }
18829
18830    private void addPreferredActivityInternal(IntentFilter filter, int match,
18831            ComponentName[] set, ComponentName activity, boolean always, int userId,
18832            String opname) {
18833        // writer
18834        int callingUid = Binder.getCallingUid();
18835        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18836                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18837        if (filter.countActions() == 0) {
18838            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18839            return;
18840        }
18841        synchronized (mPackages) {
18842            if (mContext.checkCallingOrSelfPermission(
18843                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18844                    != PackageManager.PERMISSION_GRANTED) {
18845                if (getUidTargetSdkVersionLockedLPr(callingUid)
18846                        < Build.VERSION_CODES.FROYO) {
18847                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18848                            + callingUid);
18849                    return;
18850                }
18851                mContext.enforceCallingOrSelfPermission(
18852                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18853            }
18854
18855            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18856            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18857                    + userId + ":");
18858            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18859            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18860            scheduleWritePackageRestrictionsLocked(userId);
18861            postPreferredActivityChangedBroadcast(userId);
18862        }
18863    }
18864
18865    private void postPreferredActivityChangedBroadcast(int userId) {
18866        mHandler.post(() -> {
18867            final IActivityManager am = ActivityManager.getService();
18868            if (am == null) {
18869                return;
18870            }
18871
18872            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18873            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18874            try {
18875                am.broadcastIntent(null, intent, null, null,
18876                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
18877                        null, false, false, userId);
18878            } catch (RemoteException e) {
18879            }
18880        });
18881    }
18882
18883    @Override
18884    public void replacePreferredActivity(IntentFilter filter, int match,
18885            ComponentName[] set, ComponentName activity, int userId) {
18886        if (filter.countActions() != 1) {
18887            throw new IllegalArgumentException(
18888                    "replacePreferredActivity expects filter to have only 1 action.");
18889        }
18890        if (filter.countDataAuthorities() != 0
18891                || filter.countDataPaths() != 0
18892                || filter.countDataSchemes() > 1
18893                || filter.countDataTypes() != 0) {
18894            throw new IllegalArgumentException(
18895                    "replacePreferredActivity expects filter to have no data authorities, " +
18896                    "paths, or types; and at most one scheme.");
18897        }
18898
18899        final int callingUid = Binder.getCallingUid();
18900        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18901                true /* requireFullPermission */, false /* checkShell */,
18902                "replace preferred activity");
18903        synchronized (mPackages) {
18904            if (mContext.checkCallingOrSelfPermission(
18905                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18906                    != PackageManager.PERMISSION_GRANTED) {
18907                if (getUidTargetSdkVersionLockedLPr(callingUid)
18908                        < Build.VERSION_CODES.FROYO) {
18909                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18910                            + Binder.getCallingUid());
18911                    return;
18912                }
18913                mContext.enforceCallingOrSelfPermission(
18914                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18915            }
18916
18917            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18918            if (pir != null) {
18919                // Get all of the existing entries that exactly match this filter.
18920                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18921                if (existing != null && existing.size() == 1) {
18922                    PreferredActivity cur = existing.get(0);
18923                    if (DEBUG_PREFERRED) {
18924                        Slog.i(TAG, "Checking replace of preferred:");
18925                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18926                        if (!cur.mPref.mAlways) {
18927                            Slog.i(TAG, "  -- CUR; not mAlways!");
18928                        } else {
18929                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
18930                            Slog.i(TAG, "  -- CUR: mSet="
18931                                    + Arrays.toString(cur.mPref.mSetComponents));
18932                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
18933                            Slog.i(TAG, "  -- NEW: mMatch="
18934                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
18935                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
18936                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
18937                        }
18938                    }
18939                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18940                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18941                            && cur.mPref.sameSet(set)) {
18942                        // Setting the preferred activity to what it happens to be already
18943                        if (DEBUG_PREFERRED) {
18944                            Slog.i(TAG, "Replacing with same preferred activity "
18945                                    + cur.mPref.mShortComponent + " for user "
18946                                    + userId + ":");
18947                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18948                        }
18949                        return;
18950                    }
18951                }
18952
18953                if (existing != null) {
18954                    if (DEBUG_PREFERRED) {
18955                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
18956                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18957                    }
18958                    for (int i = 0; i < existing.size(); i++) {
18959                        PreferredActivity pa = existing.get(i);
18960                        if (DEBUG_PREFERRED) {
18961                            Slog.i(TAG, "Removing existing preferred activity "
18962                                    + pa.mPref.mComponent + ":");
18963                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
18964                        }
18965                        pir.removeFilter(pa);
18966                    }
18967                }
18968            }
18969            addPreferredActivityInternal(filter, match, set, activity, true, userId,
18970                    "Replacing preferred");
18971        }
18972    }
18973
18974    @Override
18975    public void clearPackagePreferredActivities(String packageName) {
18976        final int callingUid = Binder.getCallingUid();
18977        if (getInstantAppPackageName(callingUid) != null) {
18978            return;
18979        }
18980        // writer
18981        synchronized (mPackages) {
18982            PackageParser.Package pkg = mPackages.get(packageName);
18983            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
18984                if (mContext.checkCallingOrSelfPermission(
18985                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18986                        != PackageManager.PERMISSION_GRANTED) {
18987                    if (getUidTargetSdkVersionLockedLPr(callingUid)
18988                            < Build.VERSION_CODES.FROYO) {
18989                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18990                                + callingUid);
18991                        return;
18992                    }
18993                    mContext.enforceCallingOrSelfPermission(
18994                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18995                }
18996            }
18997            final PackageSetting ps = mSettings.getPackageLPr(packageName);
18998            if (ps != null
18999                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19000                return;
19001            }
19002            int user = UserHandle.getCallingUserId();
19003            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19004                scheduleWritePackageRestrictionsLocked(user);
19005            }
19006        }
19007    }
19008
19009    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19010    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19011        ArrayList<PreferredActivity> removed = null;
19012        boolean changed = false;
19013        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19014            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19015            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19016            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19017                continue;
19018            }
19019            Iterator<PreferredActivity> it = pir.filterIterator();
19020            while (it.hasNext()) {
19021                PreferredActivity pa = it.next();
19022                // Mark entry for removal only if it matches the package name
19023                // and the entry is of type "always".
19024                if (packageName == null ||
19025                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19026                                && pa.mPref.mAlways)) {
19027                    if (removed == null) {
19028                        removed = new ArrayList<PreferredActivity>();
19029                    }
19030                    removed.add(pa);
19031                }
19032            }
19033            if (removed != null) {
19034                for (int j=0; j<removed.size(); j++) {
19035                    PreferredActivity pa = removed.get(j);
19036                    pir.removeFilter(pa);
19037                }
19038                changed = true;
19039            }
19040        }
19041        if (changed) {
19042            postPreferredActivityChangedBroadcast(userId);
19043        }
19044        return changed;
19045    }
19046
19047    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19048    private void clearIntentFilterVerificationsLPw(int userId) {
19049        final int packageCount = mPackages.size();
19050        for (int i = 0; i < packageCount; i++) {
19051            PackageParser.Package pkg = mPackages.valueAt(i);
19052            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19053        }
19054    }
19055
19056    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19057    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19058        if (userId == UserHandle.USER_ALL) {
19059            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19060                    sUserManager.getUserIds())) {
19061                for (int oneUserId : sUserManager.getUserIds()) {
19062                    scheduleWritePackageRestrictionsLocked(oneUserId);
19063                }
19064            }
19065        } else {
19066            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19067                scheduleWritePackageRestrictionsLocked(userId);
19068            }
19069        }
19070    }
19071
19072    /** Clears state for all users, and touches intent filter verification policy */
19073    void clearDefaultBrowserIfNeeded(String packageName) {
19074        for (int oneUserId : sUserManager.getUserIds()) {
19075            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19076        }
19077    }
19078
19079    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19080        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19081        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19082            if (packageName.equals(defaultBrowserPackageName)) {
19083                setDefaultBrowserPackageName(null, userId);
19084            }
19085        }
19086    }
19087
19088    @Override
19089    public void resetApplicationPreferences(int userId) {
19090        mContext.enforceCallingOrSelfPermission(
19091                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19092        final long identity = Binder.clearCallingIdentity();
19093        // writer
19094        try {
19095            synchronized (mPackages) {
19096                clearPackagePreferredActivitiesLPw(null, userId);
19097                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19098                // TODO: We have to reset the default SMS and Phone. This requires
19099                // significant refactoring to keep all default apps in the package
19100                // manager (cleaner but more work) or have the services provide
19101                // callbacks to the package manager to request a default app reset.
19102                applyFactoryDefaultBrowserLPw(userId);
19103                clearIntentFilterVerificationsLPw(userId);
19104                primeDomainVerificationsLPw(userId);
19105                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19106                scheduleWritePackageRestrictionsLocked(userId);
19107            }
19108            resetNetworkPolicies(userId);
19109        } finally {
19110            Binder.restoreCallingIdentity(identity);
19111        }
19112    }
19113
19114    @Override
19115    public int getPreferredActivities(List<IntentFilter> outFilters,
19116            List<ComponentName> outActivities, String packageName) {
19117        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19118            return 0;
19119        }
19120        int num = 0;
19121        final int userId = UserHandle.getCallingUserId();
19122        // reader
19123        synchronized (mPackages) {
19124            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19125            if (pir != null) {
19126                final Iterator<PreferredActivity> it = pir.filterIterator();
19127                while (it.hasNext()) {
19128                    final PreferredActivity pa = it.next();
19129                    if (packageName == null
19130                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19131                                    && pa.mPref.mAlways)) {
19132                        if (outFilters != null) {
19133                            outFilters.add(new IntentFilter(pa));
19134                        }
19135                        if (outActivities != null) {
19136                            outActivities.add(pa.mPref.mComponent);
19137                        }
19138                    }
19139                }
19140            }
19141        }
19142
19143        return num;
19144    }
19145
19146    @Override
19147    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19148            int userId) {
19149        int callingUid = Binder.getCallingUid();
19150        if (callingUid != Process.SYSTEM_UID) {
19151            throw new SecurityException(
19152                    "addPersistentPreferredActivity can only be run by the system");
19153        }
19154        if (filter.countActions() == 0) {
19155            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19156            return;
19157        }
19158        synchronized (mPackages) {
19159            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19160                    ":");
19161            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19162            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19163                    new PersistentPreferredActivity(filter, activity));
19164            scheduleWritePackageRestrictionsLocked(userId);
19165            postPreferredActivityChangedBroadcast(userId);
19166        }
19167    }
19168
19169    @Override
19170    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19171        int callingUid = Binder.getCallingUid();
19172        if (callingUid != Process.SYSTEM_UID) {
19173            throw new SecurityException(
19174                    "clearPackagePersistentPreferredActivities can only be run by the system");
19175        }
19176        ArrayList<PersistentPreferredActivity> removed = null;
19177        boolean changed = false;
19178        synchronized (mPackages) {
19179            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19180                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19181                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19182                        .valueAt(i);
19183                if (userId != thisUserId) {
19184                    continue;
19185                }
19186                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19187                while (it.hasNext()) {
19188                    PersistentPreferredActivity ppa = it.next();
19189                    // Mark entry for removal only if it matches the package name.
19190                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19191                        if (removed == null) {
19192                            removed = new ArrayList<PersistentPreferredActivity>();
19193                        }
19194                        removed.add(ppa);
19195                    }
19196                }
19197                if (removed != null) {
19198                    for (int j=0; j<removed.size(); j++) {
19199                        PersistentPreferredActivity ppa = removed.get(j);
19200                        ppir.removeFilter(ppa);
19201                    }
19202                    changed = true;
19203                }
19204            }
19205
19206            if (changed) {
19207                scheduleWritePackageRestrictionsLocked(userId);
19208                postPreferredActivityChangedBroadcast(userId);
19209            }
19210        }
19211    }
19212
19213    /**
19214     * Common machinery for picking apart a restored XML blob and passing
19215     * it to a caller-supplied functor to be applied to the running system.
19216     */
19217    private void restoreFromXml(XmlPullParser parser, int userId,
19218            String expectedStartTag, BlobXmlRestorer functor)
19219            throws IOException, XmlPullParserException {
19220        int type;
19221        while ((type = parser.next()) != XmlPullParser.START_TAG
19222                && type != XmlPullParser.END_DOCUMENT) {
19223        }
19224        if (type != XmlPullParser.START_TAG) {
19225            // oops didn't find a start tag?!
19226            if (DEBUG_BACKUP) {
19227                Slog.e(TAG, "Didn't find start tag during restore");
19228            }
19229            return;
19230        }
19231Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19232        // this is supposed to be TAG_PREFERRED_BACKUP
19233        if (!expectedStartTag.equals(parser.getName())) {
19234            if (DEBUG_BACKUP) {
19235                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19236            }
19237            return;
19238        }
19239
19240        // skip interfering stuff, then we're aligned with the backing implementation
19241        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19242Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19243        functor.apply(parser, userId);
19244    }
19245
19246    private interface BlobXmlRestorer {
19247        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19248    }
19249
19250    /**
19251     * Non-Binder method, support for the backup/restore mechanism: write the
19252     * full set of preferred activities in its canonical XML format.  Returns the
19253     * XML output as a byte array, or null if there is none.
19254     */
19255    @Override
19256    public byte[] getPreferredActivityBackup(int userId) {
19257        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19258            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19259        }
19260
19261        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19262        try {
19263            final XmlSerializer serializer = new FastXmlSerializer();
19264            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19265            serializer.startDocument(null, true);
19266            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19267
19268            synchronized (mPackages) {
19269                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19270            }
19271
19272            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19273            serializer.endDocument();
19274            serializer.flush();
19275        } catch (Exception e) {
19276            if (DEBUG_BACKUP) {
19277                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19278            }
19279            return null;
19280        }
19281
19282        return dataStream.toByteArray();
19283    }
19284
19285    @Override
19286    public void restorePreferredActivities(byte[] backup, int userId) {
19287        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19288            throw new SecurityException("Only the system may call restorePreferredActivities()");
19289        }
19290
19291        try {
19292            final XmlPullParser parser = Xml.newPullParser();
19293            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19294            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19295                    new BlobXmlRestorer() {
19296                        @Override
19297                        public void apply(XmlPullParser parser, int userId)
19298                                throws XmlPullParserException, IOException {
19299                            synchronized (mPackages) {
19300                                mSettings.readPreferredActivitiesLPw(parser, userId);
19301                            }
19302                        }
19303                    } );
19304        } catch (Exception e) {
19305            if (DEBUG_BACKUP) {
19306                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19307            }
19308        }
19309    }
19310
19311    /**
19312     * Non-Binder method, support for the backup/restore mechanism: write the
19313     * default browser (etc) settings in its canonical XML format.  Returns the default
19314     * browser XML representation as a byte array, or null if there is none.
19315     */
19316    @Override
19317    public byte[] getDefaultAppsBackup(int userId) {
19318        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19319            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19320        }
19321
19322        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19323        try {
19324            final XmlSerializer serializer = new FastXmlSerializer();
19325            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19326            serializer.startDocument(null, true);
19327            serializer.startTag(null, TAG_DEFAULT_APPS);
19328
19329            synchronized (mPackages) {
19330                mSettings.writeDefaultAppsLPr(serializer, userId);
19331            }
19332
19333            serializer.endTag(null, TAG_DEFAULT_APPS);
19334            serializer.endDocument();
19335            serializer.flush();
19336        } catch (Exception e) {
19337            if (DEBUG_BACKUP) {
19338                Slog.e(TAG, "Unable to write default apps for backup", e);
19339            }
19340            return null;
19341        }
19342
19343        return dataStream.toByteArray();
19344    }
19345
19346    @Override
19347    public void restoreDefaultApps(byte[] backup, int userId) {
19348        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19349            throw new SecurityException("Only the system may call restoreDefaultApps()");
19350        }
19351
19352        try {
19353            final XmlPullParser parser = Xml.newPullParser();
19354            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19355            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19356                    new BlobXmlRestorer() {
19357                        @Override
19358                        public void apply(XmlPullParser parser, int userId)
19359                                throws XmlPullParserException, IOException {
19360                            synchronized (mPackages) {
19361                                mSettings.readDefaultAppsLPw(parser, userId);
19362                            }
19363                        }
19364                    } );
19365        } catch (Exception e) {
19366            if (DEBUG_BACKUP) {
19367                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19368            }
19369        }
19370    }
19371
19372    @Override
19373    public byte[] getIntentFilterVerificationBackup(int userId) {
19374        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19375            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19376        }
19377
19378        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19379        try {
19380            final XmlSerializer serializer = new FastXmlSerializer();
19381            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19382            serializer.startDocument(null, true);
19383            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19384
19385            synchronized (mPackages) {
19386                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19387            }
19388
19389            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19390            serializer.endDocument();
19391            serializer.flush();
19392        } catch (Exception e) {
19393            if (DEBUG_BACKUP) {
19394                Slog.e(TAG, "Unable to write default apps for backup", e);
19395            }
19396            return null;
19397        }
19398
19399        return dataStream.toByteArray();
19400    }
19401
19402    @Override
19403    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19404        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19405            throw new SecurityException("Only the system may call restorePreferredActivities()");
19406        }
19407
19408        try {
19409            final XmlPullParser parser = Xml.newPullParser();
19410            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19411            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19412                    new BlobXmlRestorer() {
19413                        @Override
19414                        public void apply(XmlPullParser parser, int userId)
19415                                throws XmlPullParserException, IOException {
19416                            synchronized (mPackages) {
19417                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19418                                mSettings.writeLPr();
19419                            }
19420                        }
19421                    } );
19422        } catch (Exception e) {
19423            if (DEBUG_BACKUP) {
19424                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19425            }
19426        }
19427    }
19428
19429    @Override
19430    public byte[] getPermissionGrantBackup(int userId) {
19431        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19432            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19433        }
19434
19435        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19436        try {
19437            final XmlSerializer serializer = new FastXmlSerializer();
19438            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19439            serializer.startDocument(null, true);
19440            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19441
19442            synchronized (mPackages) {
19443                serializeRuntimePermissionGrantsLPr(serializer, userId);
19444            }
19445
19446            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19447            serializer.endDocument();
19448            serializer.flush();
19449        } catch (Exception e) {
19450            if (DEBUG_BACKUP) {
19451                Slog.e(TAG, "Unable to write default apps for backup", e);
19452            }
19453            return null;
19454        }
19455
19456        return dataStream.toByteArray();
19457    }
19458
19459    @Override
19460    public void restorePermissionGrants(byte[] backup, int userId) {
19461        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19462            throw new SecurityException("Only the system may call restorePermissionGrants()");
19463        }
19464
19465        try {
19466            final XmlPullParser parser = Xml.newPullParser();
19467            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19468            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19469                    new BlobXmlRestorer() {
19470                        @Override
19471                        public void apply(XmlPullParser parser, int userId)
19472                                throws XmlPullParserException, IOException {
19473                            synchronized (mPackages) {
19474                                processRestoredPermissionGrantsLPr(parser, userId);
19475                            }
19476                        }
19477                    } );
19478        } catch (Exception e) {
19479            if (DEBUG_BACKUP) {
19480                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19481            }
19482        }
19483    }
19484
19485    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19486            throws IOException {
19487        serializer.startTag(null, TAG_ALL_GRANTS);
19488
19489        final int N = mSettings.mPackages.size();
19490        for (int i = 0; i < N; i++) {
19491            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19492            boolean pkgGrantsKnown = false;
19493
19494            PermissionsState packagePerms = ps.getPermissionsState();
19495
19496            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19497                final int grantFlags = state.getFlags();
19498                // only look at grants that are not system/policy fixed
19499                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19500                    final boolean isGranted = state.isGranted();
19501                    // And only back up the user-twiddled state bits
19502                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19503                        final String packageName = mSettings.mPackages.keyAt(i);
19504                        if (!pkgGrantsKnown) {
19505                            serializer.startTag(null, TAG_GRANT);
19506                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19507                            pkgGrantsKnown = true;
19508                        }
19509
19510                        final boolean userSet =
19511                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19512                        final boolean userFixed =
19513                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19514                        final boolean revoke =
19515                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19516
19517                        serializer.startTag(null, TAG_PERMISSION);
19518                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19519                        if (isGranted) {
19520                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19521                        }
19522                        if (userSet) {
19523                            serializer.attribute(null, ATTR_USER_SET, "true");
19524                        }
19525                        if (userFixed) {
19526                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19527                        }
19528                        if (revoke) {
19529                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19530                        }
19531                        serializer.endTag(null, TAG_PERMISSION);
19532                    }
19533                }
19534            }
19535
19536            if (pkgGrantsKnown) {
19537                serializer.endTag(null, TAG_GRANT);
19538            }
19539        }
19540
19541        serializer.endTag(null, TAG_ALL_GRANTS);
19542    }
19543
19544    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19545            throws XmlPullParserException, IOException {
19546        String pkgName = null;
19547        int outerDepth = parser.getDepth();
19548        int type;
19549        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19550                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19551            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19552                continue;
19553            }
19554
19555            final String tagName = parser.getName();
19556            if (tagName.equals(TAG_GRANT)) {
19557                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19558                if (DEBUG_BACKUP) {
19559                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19560                }
19561            } else if (tagName.equals(TAG_PERMISSION)) {
19562
19563                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19564                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19565
19566                int newFlagSet = 0;
19567                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19568                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19569                }
19570                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19571                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19572                }
19573                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19574                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19575                }
19576                if (DEBUG_BACKUP) {
19577                    Slog.v(TAG, "  + Restoring grant:"
19578                            + " pkg=" + pkgName
19579                            + " perm=" + permName
19580                            + " granted=" + isGranted
19581                            + " bits=0x" + Integer.toHexString(newFlagSet));
19582                }
19583                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19584                if (ps != null) {
19585                    // Already installed so we apply the grant immediately
19586                    if (DEBUG_BACKUP) {
19587                        Slog.v(TAG, "        + already installed; applying");
19588                    }
19589                    PermissionsState perms = ps.getPermissionsState();
19590                    BasePermission bp =
19591                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19592                    if (bp != null) {
19593                        if (isGranted) {
19594                            perms.grantRuntimePermission(bp, userId);
19595                        }
19596                        if (newFlagSet != 0) {
19597                            perms.updatePermissionFlags(
19598                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19599                        }
19600                    }
19601                } else {
19602                    // Need to wait for post-restore install to apply the grant
19603                    if (DEBUG_BACKUP) {
19604                        Slog.v(TAG, "        - not yet installed; saving for later");
19605                    }
19606                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19607                            isGranted, newFlagSet, userId);
19608                }
19609            } else {
19610                PackageManagerService.reportSettingsProblem(Log.WARN,
19611                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19612                XmlUtils.skipCurrentTag(parser);
19613            }
19614        }
19615
19616        scheduleWriteSettingsLocked();
19617        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19618    }
19619
19620    @Override
19621    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19622            int sourceUserId, int targetUserId, int flags) {
19623        mContext.enforceCallingOrSelfPermission(
19624                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19625        int callingUid = Binder.getCallingUid();
19626        enforceOwnerRights(ownerPackage, callingUid);
19627        PackageManagerServiceUtils.enforceShellRestriction(
19628                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19629        if (intentFilter.countActions() == 0) {
19630            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19631            return;
19632        }
19633        synchronized (mPackages) {
19634            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19635                    ownerPackage, targetUserId, flags);
19636            CrossProfileIntentResolver resolver =
19637                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19638            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19639            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19640            if (existing != null) {
19641                int size = existing.size();
19642                for (int i = 0; i < size; i++) {
19643                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19644                        return;
19645                    }
19646                }
19647            }
19648            resolver.addFilter(newFilter);
19649            scheduleWritePackageRestrictionsLocked(sourceUserId);
19650        }
19651    }
19652
19653    @Override
19654    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19655        mContext.enforceCallingOrSelfPermission(
19656                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19657        final int callingUid = Binder.getCallingUid();
19658        enforceOwnerRights(ownerPackage, callingUid);
19659        PackageManagerServiceUtils.enforceShellRestriction(
19660                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19661        synchronized (mPackages) {
19662            CrossProfileIntentResolver resolver =
19663                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19664            ArraySet<CrossProfileIntentFilter> set =
19665                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19666            for (CrossProfileIntentFilter filter : set) {
19667                if (filter.getOwnerPackage().equals(ownerPackage)) {
19668                    resolver.removeFilter(filter);
19669                }
19670            }
19671            scheduleWritePackageRestrictionsLocked(sourceUserId);
19672        }
19673    }
19674
19675    // Enforcing that callingUid is owning pkg on userId
19676    private void enforceOwnerRights(String pkg, int callingUid) {
19677        // The system owns everything.
19678        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19679            return;
19680        }
19681        final int callingUserId = UserHandle.getUserId(callingUid);
19682        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19683        if (pi == null) {
19684            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19685                    + callingUserId);
19686        }
19687        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19688            throw new SecurityException("Calling uid " + callingUid
19689                    + " does not own package " + pkg);
19690        }
19691    }
19692
19693    @Override
19694    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19695        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19696            return null;
19697        }
19698        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19699    }
19700
19701    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19702        UserManagerService ums = UserManagerService.getInstance();
19703        if (ums != null) {
19704            final UserInfo parent = ums.getProfileParent(userId);
19705            final int launcherUid = (parent != null) ? parent.id : userId;
19706            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19707            if (launcherComponent != null) {
19708                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19709                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19710                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19711                        .setPackage(launcherComponent.getPackageName());
19712                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19713            }
19714        }
19715    }
19716
19717    /**
19718     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19719     * then reports the most likely home activity or null if there are more than one.
19720     */
19721    private ComponentName getDefaultHomeActivity(int userId) {
19722        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19723        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19724        if (cn != null) {
19725            return cn;
19726        }
19727
19728        // Find the launcher with the highest priority and return that component if there are no
19729        // other home activity with the same priority.
19730        int lastPriority = Integer.MIN_VALUE;
19731        ComponentName lastComponent = null;
19732        final int size = allHomeCandidates.size();
19733        for (int i = 0; i < size; i++) {
19734            final ResolveInfo ri = allHomeCandidates.get(i);
19735            if (ri.priority > lastPriority) {
19736                lastComponent = ri.activityInfo.getComponentName();
19737                lastPriority = ri.priority;
19738            } else if (ri.priority == lastPriority) {
19739                // Two components found with same priority.
19740                lastComponent = null;
19741            }
19742        }
19743        return lastComponent;
19744    }
19745
19746    private Intent getHomeIntent() {
19747        Intent intent = new Intent(Intent.ACTION_MAIN);
19748        intent.addCategory(Intent.CATEGORY_HOME);
19749        intent.addCategory(Intent.CATEGORY_DEFAULT);
19750        return intent;
19751    }
19752
19753    private IntentFilter getHomeFilter() {
19754        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19755        filter.addCategory(Intent.CATEGORY_HOME);
19756        filter.addCategory(Intent.CATEGORY_DEFAULT);
19757        return filter;
19758    }
19759
19760    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19761            int userId) {
19762        Intent intent  = getHomeIntent();
19763        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19764                PackageManager.GET_META_DATA, userId);
19765        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19766                true, false, false, userId);
19767
19768        allHomeCandidates.clear();
19769        if (list != null) {
19770            for (ResolveInfo ri : list) {
19771                allHomeCandidates.add(ri);
19772            }
19773        }
19774        return (preferred == null || preferred.activityInfo == null)
19775                ? null
19776                : new ComponentName(preferred.activityInfo.packageName,
19777                        preferred.activityInfo.name);
19778    }
19779
19780    @Override
19781    public void setHomeActivity(ComponentName comp, int userId) {
19782        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19783            return;
19784        }
19785        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19786        getHomeActivitiesAsUser(homeActivities, userId);
19787
19788        boolean found = false;
19789
19790        final int size = homeActivities.size();
19791        final ComponentName[] set = new ComponentName[size];
19792        for (int i = 0; i < size; i++) {
19793            final ResolveInfo candidate = homeActivities.get(i);
19794            final ActivityInfo info = candidate.activityInfo;
19795            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19796            set[i] = activityName;
19797            if (!found && activityName.equals(comp)) {
19798                found = true;
19799            }
19800        }
19801        if (!found) {
19802            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19803                    + userId);
19804        }
19805        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19806                set, comp, userId);
19807    }
19808
19809    private @Nullable String getSetupWizardPackageName() {
19810        final Intent intent = new Intent(Intent.ACTION_MAIN);
19811        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19812
19813        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19814                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19815                        | MATCH_DISABLED_COMPONENTS,
19816                UserHandle.myUserId());
19817        if (matches.size() == 1) {
19818            return matches.get(0).getComponentInfo().packageName;
19819        } else {
19820            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19821                    + ": matches=" + matches);
19822            return null;
19823        }
19824    }
19825
19826    private @Nullable String getStorageManagerPackageName() {
19827        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19828
19829        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19830                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19831                        | MATCH_DISABLED_COMPONENTS,
19832                UserHandle.myUserId());
19833        if (matches.size() == 1) {
19834            return matches.get(0).getComponentInfo().packageName;
19835        } else {
19836            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19837                    + matches.size() + ": matches=" + matches);
19838            return null;
19839        }
19840    }
19841
19842    @Override
19843    public void setApplicationEnabledSetting(String appPackageName,
19844            int newState, int flags, int userId, String callingPackage) {
19845        if (!sUserManager.exists(userId)) return;
19846        if (callingPackage == null) {
19847            callingPackage = Integer.toString(Binder.getCallingUid());
19848        }
19849        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19850    }
19851
19852    @Override
19853    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19854        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19855        synchronized (mPackages) {
19856            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19857            if (pkgSetting != null) {
19858                pkgSetting.setUpdateAvailable(updateAvailable);
19859            }
19860        }
19861    }
19862
19863    @Override
19864    public void setComponentEnabledSetting(ComponentName componentName,
19865            int newState, int flags, int userId) {
19866        if (!sUserManager.exists(userId)) return;
19867        setEnabledSetting(componentName.getPackageName(),
19868                componentName.getClassName(), newState, flags, userId, null);
19869    }
19870
19871    private void setEnabledSetting(final String packageName, String className, int newState,
19872            final int flags, int userId, String callingPackage) {
19873        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19874              || newState == COMPONENT_ENABLED_STATE_ENABLED
19875              || newState == COMPONENT_ENABLED_STATE_DISABLED
19876              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19877              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19878            throw new IllegalArgumentException("Invalid new component state: "
19879                    + newState);
19880        }
19881        PackageSetting pkgSetting;
19882        final int callingUid = Binder.getCallingUid();
19883        final int permission;
19884        if (callingUid == Process.SYSTEM_UID) {
19885            permission = PackageManager.PERMISSION_GRANTED;
19886        } else {
19887            permission = mContext.checkCallingOrSelfPermission(
19888                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19889        }
19890        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19891                false /* requireFullPermission */, true /* checkShell */, "set enabled");
19892        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19893        boolean sendNow = false;
19894        boolean isApp = (className == null);
19895        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
19896        String componentName = isApp ? packageName : className;
19897        int packageUid = -1;
19898        ArrayList<String> components;
19899
19900        // reader
19901        synchronized (mPackages) {
19902            pkgSetting = mSettings.mPackages.get(packageName);
19903            if (pkgSetting == null) {
19904                if (!isCallerInstantApp) {
19905                    if (className == null) {
19906                        throw new IllegalArgumentException("Unknown package: " + packageName);
19907                    }
19908                    throw new IllegalArgumentException(
19909                            "Unknown component: " + packageName + "/" + className);
19910                } else {
19911                    // throw SecurityException to prevent leaking package information
19912                    throw new SecurityException(
19913                            "Attempt to change component state; "
19914                            + "pid=" + Binder.getCallingPid()
19915                            + ", uid=" + callingUid
19916                            + (className == null
19917                                    ? ", package=" + packageName
19918                                    : ", component=" + packageName + "/" + className));
19919                }
19920            }
19921        }
19922
19923        // Limit who can change which apps
19924        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
19925            // Don't allow apps that don't have permission to modify other apps
19926            if (!allowedByPermission
19927                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
19928                throw new SecurityException(
19929                        "Attempt to change component state; "
19930                        + "pid=" + Binder.getCallingPid()
19931                        + ", uid=" + callingUid
19932                        + (className == null
19933                                ? ", package=" + packageName
19934                                : ", component=" + packageName + "/" + className));
19935            }
19936            // Don't allow changing protected packages.
19937            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
19938                throw new SecurityException("Cannot disable a protected package: " + packageName);
19939            }
19940        }
19941
19942        synchronized (mPackages) {
19943            if (callingUid == Process.SHELL_UID
19944                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
19945                // Shell can only change whole packages between ENABLED and DISABLED_USER states
19946                // unless it is a test package.
19947                int oldState = pkgSetting.getEnabled(userId);
19948                if (className == null
19949                        &&
19950                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
19951                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
19952                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
19953                        &&
19954                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19955                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
19956                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
19957                    // ok
19958                } else {
19959                    throw new SecurityException(
19960                            "Shell cannot change component state for " + packageName + "/"
19961                                    + className + " to " + newState);
19962                }
19963            }
19964        }
19965        if (className == null) {
19966            // We're dealing with an application/package level state change
19967            synchronized (mPackages) {
19968                if (pkgSetting.getEnabled(userId) == newState) {
19969                    // Nothing to do
19970                    return;
19971                }
19972            }
19973            // If we're enabling a system stub, there's a little more work to do.
19974            // Prior to enabling the package, we need to decompress the APK(s) to the
19975            // data partition and then replace the version on the system partition.
19976            final PackageParser.Package deletedPkg = pkgSetting.pkg;
19977            final boolean isSystemStub = deletedPkg.isStub
19978                    && deletedPkg.isSystem();
19979            if (isSystemStub
19980                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19981                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
19982                final File codePath = decompressPackage(deletedPkg);
19983                if (codePath == null) {
19984                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
19985                    return;
19986                }
19987                // TODO remove direct parsing of the package object during internal cleanup
19988                // of scan package
19989                // We need to call parse directly here for no other reason than we need
19990                // the new package in order to disable the old one [we use the information
19991                // for some internal optimization to optionally create a new package setting
19992                // object on replace]. However, we can't get the package from the scan
19993                // because the scan modifies live structures and we need to remove the
19994                // old [system] package from the system before a scan can be attempted.
19995                // Once scan is indempotent we can remove this parse and use the package
19996                // object we scanned, prior to adding it to package settings.
19997                final PackageParser pp = new PackageParser();
19998                pp.setSeparateProcesses(mSeparateProcesses);
19999                pp.setDisplayMetrics(mMetrics);
20000                pp.setCallback(mPackageParserCallback);
20001                final PackageParser.Package tmpPkg;
20002                try {
20003                    final @ParseFlags int parseFlags = mDefParseFlags
20004                            | PackageParser.PARSE_MUST_BE_APK
20005                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20006                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20007                } catch (PackageParserException e) {
20008                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20009                    return;
20010                }
20011                synchronized (mInstallLock) {
20012                    // Disable the stub and remove any package entries
20013                    removePackageLI(deletedPkg, true);
20014                    synchronized (mPackages) {
20015                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20016                    }
20017                    final PackageParser.Package pkg;
20018                    try (PackageFreezer freezer =
20019                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20020                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20021                                | PackageParser.PARSE_ENFORCE_CODE;
20022                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20023                                0 /*currentTime*/, null /*user*/);
20024                        prepareAppDataAfterInstallLIF(pkg);
20025                        synchronized (mPackages) {
20026                            try {
20027                                updateSharedLibrariesLPr(pkg, null);
20028                            } catch (PackageManagerException e) {
20029                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20030                            }
20031                            mPermissionManager.updatePermissions(
20032                                    pkg.packageName, pkg, true, mPackages.values(),
20033                                    mPermissionCallback);
20034                            mSettings.writeLPr();
20035                        }
20036                    } catch (PackageManagerException e) {
20037                        // Whoops! Something went wrong; try to roll back to the stub
20038                        Slog.w(TAG, "Failed to install compressed system package:"
20039                                + pkgSetting.name, e);
20040                        // Remove the failed install
20041                        removeCodePathLI(codePath);
20042
20043                        // Install the system package
20044                        try (PackageFreezer freezer =
20045                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20046                            synchronized (mPackages) {
20047                                // NOTE: The system package always needs to be enabled; even
20048                                // if it's for a compressed stub. If we don't, installing the
20049                                // system package fails during scan [scanning checks the disabled
20050                                // packages]. We will reverse this later, after we've "installed"
20051                                // the stub.
20052                                // This leaves us in a fragile state; the stub should never be
20053                                // enabled, so, cross your fingers and hope nothing goes wrong
20054                                // until we can disable the package later.
20055                                enableSystemPackageLPw(deletedPkg);
20056                            }
20057                            installPackageFromSystemLIF(deletedPkg.codePath,
20058                                    false /*isPrivileged*/, null /*allUserHandles*/,
20059                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20060                                    true /*writeSettings*/);
20061                        } catch (PackageManagerException pme) {
20062                            Slog.w(TAG, "Failed to restore system package:"
20063                                    + deletedPkg.packageName, pme);
20064                        } finally {
20065                            synchronized (mPackages) {
20066                                mSettings.disableSystemPackageLPw(
20067                                        deletedPkg.packageName, true /*replaced*/);
20068                                mSettings.writeLPr();
20069                            }
20070                        }
20071                        return;
20072                    }
20073                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20074                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20075                    clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20076                    mDexManager.notifyPackageUpdated(pkg.packageName,
20077                            pkg.baseCodePath, pkg.splitCodePaths);
20078                }
20079            }
20080            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20081                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20082                // Don't care about who enables an app.
20083                callingPackage = null;
20084            }
20085            synchronized (mPackages) {
20086                pkgSetting.setEnabled(newState, userId, callingPackage);
20087            }
20088        } else {
20089            synchronized (mPackages) {
20090                // We're dealing with a component level state change
20091                // First, verify that this is a valid class name.
20092                PackageParser.Package pkg = pkgSetting.pkg;
20093                if (pkg == null || !pkg.hasComponentClassName(className)) {
20094                    if (pkg != null &&
20095                            pkg.applicationInfo.targetSdkVersion >=
20096                                    Build.VERSION_CODES.JELLY_BEAN) {
20097                        throw new IllegalArgumentException("Component class " + className
20098                                + " does not exist in " + packageName);
20099                    } else {
20100                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20101                                + className + " does not exist in " + packageName);
20102                    }
20103                }
20104                switch (newState) {
20105                    case COMPONENT_ENABLED_STATE_ENABLED:
20106                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20107                            return;
20108                        }
20109                        break;
20110                    case COMPONENT_ENABLED_STATE_DISABLED:
20111                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20112                            return;
20113                        }
20114                        break;
20115                    case COMPONENT_ENABLED_STATE_DEFAULT:
20116                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20117                            return;
20118                        }
20119                        break;
20120                    default:
20121                        Slog.e(TAG, "Invalid new component state: " + newState);
20122                        return;
20123                }
20124            }
20125        }
20126        synchronized (mPackages) {
20127            scheduleWritePackageRestrictionsLocked(userId);
20128            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20129            final long callingId = Binder.clearCallingIdentity();
20130            try {
20131                updateInstantAppInstallerLocked(packageName);
20132            } finally {
20133                Binder.restoreCallingIdentity(callingId);
20134            }
20135            components = mPendingBroadcasts.get(userId, packageName);
20136            final boolean newPackage = components == null;
20137            if (newPackage) {
20138                components = new ArrayList<String>();
20139            }
20140            if (!components.contains(componentName)) {
20141                components.add(componentName);
20142            }
20143            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20144                sendNow = true;
20145                // Purge entry from pending broadcast list if another one exists already
20146                // since we are sending one right away.
20147                mPendingBroadcasts.remove(userId, packageName);
20148            } else {
20149                if (newPackage) {
20150                    mPendingBroadcasts.put(userId, packageName, components);
20151                }
20152                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20153                    // Schedule a message
20154                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20155                }
20156            }
20157        }
20158
20159        long callingId = Binder.clearCallingIdentity();
20160        try {
20161            if (sendNow) {
20162                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20163                sendPackageChangedBroadcast(packageName,
20164                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20165            }
20166        } finally {
20167            Binder.restoreCallingIdentity(callingId);
20168        }
20169    }
20170
20171    @Override
20172    public void flushPackageRestrictionsAsUser(int userId) {
20173        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20174            return;
20175        }
20176        if (!sUserManager.exists(userId)) {
20177            return;
20178        }
20179        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20180                false /* checkShell */, "flushPackageRestrictions");
20181        synchronized (mPackages) {
20182            mSettings.writePackageRestrictionsLPr(userId);
20183            mDirtyUsers.remove(userId);
20184            if (mDirtyUsers.isEmpty()) {
20185                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20186            }
20187        }
20188    }
20189
20190    private void sendPackageChangedBroadcast(String packageName,
20191            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20192        if (DEBUG_INSTALL)
20193            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20194                    + componentNames);
20195        Bundle extras = new Bundle(4);
20196        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20197        String nameList[] = new String[componentNames.size()];
20198        componentNames.toArray(nameList);
20199        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20200        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20201        extras.putInt(Intent.EXTRA_UID, packageUid);
20202        // If this is not reporting a change of the overall package, then only send it
20203        // to registered receivers.  We don't want to launch a swath of apps for every
20204        // little component state change.
20205        final int flags = !componentNames.contains(packageName)
20206                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20207        final int userId = UserHandle.getUserId(packageUid);
20208        final boolean isInstantApp = isInstantApp(packageName, userId);
20209        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20210        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20211        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20212                userIds, instantUserIds);
20213    }
20214
20215    @Override
20216    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20217        if (!sUserManager.exists(userId)) return;
20218        final int callingUid = Binder.getCallingUid();
20219        if (getInstantAppPackageName(callingUid) != null) {
20220            return;
20221        }
20222        final int permission = mContext.checkCallingOrSelfPermission(
20223                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20224        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20225        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20226                true /* requireFullPermission */, true /* checkShell */, "stop package");
20227        // writer
20228        synchronized (mPackages) {
20229            final PackageSetting ps = mSettings.mPackages.get(packageName);
20230            if (!filterAppAccessLPr(ps, callingUid, userId)
20231                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20232                            allowedByPermission, callingUid, userId)) {
20233                scheduleWritePackageRestrictionsLocked(userId);
20234            }
20235        }
20236    }
20237
20238    @Override
20239    public String getInstallerPackageName(String packageName) {
20240        final int callingUid = Binder.getCallingUid();
20241        if (getInstantAppPackageName(callingUid) != null) {
20242            return null;
20243        }
20244        // reader
20245        synchronized (mPackages) {
20246            final PackageSetting ps = mSettings.mPackages.get(packageName);
20247            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20248                return null;
20249            }
20250            return mSettings.getInstallerPackageNameLPr(packageName);
20251        }
20252    }
20253
20254    public boolean isOrphaned(String packageName) {
20255        // reader
20256        synchronized (mPackages) {
20257            return mSettings.isOrphaned(packageName);
20258        }
20259    }
20260
20261    @Override
20262    public int getApplicationEnabledSetting(String packageName, int userId) {
20263        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20264        int callingUid = Binder.getCallingUid();
20265        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20266                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20267        // reader
20268        synchronized (mPackages) {
20269            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20270                return COMPONENT_ENABLED_STATE_DISABLED;
20271            }
20272            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20273        }
20274    }
20275
20276    @Override
20277    public int getComponentEnabledSetting(ComponentName component, int userId) {
20278        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20279        int callingUid = Binder.getCallingUid();
20280        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20281                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20282        synchronized (mPackages) {
20283            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20284                    component, TYPE_UNKNOWN, userId)) {
20285                return COMPONENT_ENABLED_STATE_DISABLED;
20286            }
20287            return mSettings.getComponentEnabledSettingLPr(component, userId);
20288        }
20289    }
20290
20291    @Override
20292    public void enterSafeMode() {
20293        enforceSystemOrRoot("Only the system can request entering safe mode");
20294
20295        if (!mSystemReady) {
20296            mSafeMode = true;
20297        }
20298    }
20299
20300    @Override
20301    public void systemReady() {
20302        enforceSystemOrRoot("Only the system can claim the system is ready");
20303
20304        mSystemReady = true;
20305        final ContentResolver resolver = mContext.getContentResolver();
20306        ContentObserver co = new ContentObserver(mHandler) {
20307            @Override
20308            public void onChange(boolean selfChange) {
20309                mEphemeralAppsDisabled =
20310                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20311                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20312            }
20313        };
20314        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20315                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20316                false, co, UserHandle.USER_SYSTEM);
20317        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20318                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20319        co.onChange(true);
20320
20321        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20322        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20323        // it is done.
20324        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20325            @Override
20326            public void onChange(boolean selfChange) {
20327                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20328                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20329                        oobEnabled == 1 ? "true" : "false");
20330            }
20331        };
20332        mContext.getContentResolver().registerContentObserver(
20333                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20334                UserHandle.USER_SYSTEM);
20335        // At boot, restore the value from the setting, which persists across reboot.
20336        privAppOobObserver.onChange(true);
20337
20338        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20339        // disabled after already being started.
20340        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20341                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20342
20343        // Read the compatibilty setting when the system is ready.
20344        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20345                mContext.getContentResolver(),
20346                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20347        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20348        if (DEBUG_SETTINGS) {
20349            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20350        }
20351
20352        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20353
20354        synchronized (mPackages) {
20355            // Verify that all of the preferred activity components actually
20356            // exist.  It is possible for applications to be updated and at
20357            // that point remove a previously declared activity component that
20358            // had been set as a preferred activity.  We try to clean this up
20359            // the next time we encounter that preferred activity, but it is
20360            // possible for the user flow to never be able to return to that
20361            // situation so here we do a sanity check to make sure we haven't
20362            // left any junk around.
20363            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20364            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20365                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20366                removed.clear();
20367                for (PreferredActivity pa : pir.filterSet()) {
20368                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20369                        removed.add(pa);
20370                    }
20371                }
20372                if (removed.size() > 0) {
20373                    for (int r=0; r<removed.size(); r++) {
20374                        PreferredActivity pa = removed.get(r);
20375                        Slog.w(TAG, "Removing dangling preferred activity: "
20376                                + pa.mPref.mComponent);
20377                        pir.removeFilter(pa);
20378                    }
20379                    mSettings.writePackageRestrictionsLPr(
20380                            mSettings.mPreferredActivities.keyAt(i));
20381                }
20382            }
20383
20384            for (int userId : UserManagerService.getInstance().getUserIds()) {
20385                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20386                    grantPermissionsUserIds = ArrayUtils.appendInt(
20387                            grantPermissionsUserIds, userId);
20388                }
20389            }
20390        }
20391        sUserManager.systemReady();
20392
20393        // If we upgraded grant all default permissions before kicking off.
20394        for (int userId : grantPermissionsUserIds) {
20395            mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
20396        }
20397
20398        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20399            // If we did not grant default permissions, we preload from this the
20400            // default permission exceptions lazily to ensure we don't hit the
20401            // disk on a new user creation.
20402            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20403        }
20404
20405        // Now that we've scanned all packages, and granted any default
20406        // permissions, ensure permissions are updated. Beware of dragons if you
20407        // try optimizing this.
20408        synchronized (mPackages) {
20409            mPermissionManager.updateAllPermissions(
20410                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20411                    mPermissionCallback);
20412        }
20413
20414        // Kick off any messages waiting for system ready
20415        if (mPostSystemReadyMessages != null) {
20416            for (Message msg : mPostSystemReadyMessages) {
20417                msg.sendToTarget();
20418            }
20419            mPostSystemReadyMessages = null;
20420        }
20421
20422        // Watch for external volumes that come and go over time
20423        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20424        storage.registerListener(mStorageListener);
20425
20426        mInstallerService.systemReady();
20427        mPackageDexOptimizer.systemReady();
20428
20429        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20430                StorageManagerInternal.class);
20431        StorageManagerInternal.addExternalStoragePolicy(
20432                new StorageManagerInternal.ExternalStorageMountPolicy() {
20433            @Override
20434            public int getMountMode(int uid, String packageName) {
20435                if (Process.isIsolated(uid)) {
20436                    return Zygote.MOUNT_EXTERNAL_NONE;
20437                }
20438                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20439                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20440                }
20441                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20442                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20443                }
20444                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20445                    return Zygote.MOUNT_EXTERNAL_READ;
20446                }
20447                return Zygote.MOUNT_EXTERNAL_WRITE;
20448            }
20449
20450            @Override
20451            public boolean hasExternalStorage(int uid, String packageName) {
20452                return true;
20453            }
20454        });
20455
20456        // Now that we're mostly running, clean up stale users and apps
20457        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20458        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20459
20460        mPermissionManager.systemReady();
20461    }
20462
20463    public void waitForAppDataPrepared() {
20464        if (mPrepareAppDataFuture == null) {
20465            return;
20466        }
20467        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20468        mPrepareAppDataFuture = null;
20469    }
20470
20471    @Override
20472    public boolean isSafeMode() {
20473        // allow instant applications
20474        return mSafeMode;
20475    }
20476
20477    @Override
20478    public boolean hasSystemUidErrors() {
20479        // allow instant applications
20480        return mHasSystemUidErrors;
20481    }
20482
20483    static String arrayToString(int[] array) {
20484        StringBuffer buf = new StringBuffer(128);
20485        buf.append('[');
20486        if (array != null) {
20487            for (int i=0; i<array.length; i++) {
20488                if (i > 0) buf.append(", ");
20489                buf.append(array[i]);
20490            }
20491        }
20492        buf.append(']');
20493        return buf.toString();
20494    }
20495
20496    @Override
20497    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20498            FileDescriptor err, String[] args, ShellCallback callback,
20499            ResultReceiver resultReceiver) {
20500        (new PackageManagerShellCommand(this)).exec(
20501                this, in, out, err, args, callback, resultReceiver);
20502    }
20503
20504    @Override
20505    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20506        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20507
20508        DumpState dumpState = new DumpState();
20509        boolean fullPreferred = false;
20510        boolean checkin = false;
20511
20512        String packageName = null;
20513        ArraySet<String> permissionNames = null;
20514
20515        int opti = 0;
20516        while (opti < args.length) {
20517            String opt = args[opti];
20518            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20519                break;
20520            }
20521            opti++;
20522
20523            if ("-a".equals(opt)) {
20524                // Right now we only know how to print all.
20525            } else if ("-h".equals(opt)) {
20526                pw.println("Package manager dump options:");
20527                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20528                pw.println("    --checkin: dump for a checkin");
20529                pw.println("    -f: print details of intent filters");
20530                pw.println("    -h: print this help");
20531                pw.println("  cmd may be one of:");
20532                pw.println("    l[ibraries]: list known shared libraries");
20533                pw.println("    f[eatures]: list device features");
20534                pw.println("    k[eysets]: print known keysets");
20535                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20536                pw.println("    perm[issions]: dump permissions");
20537                pw.println("    permission [name ...]: dump declaration and use of given permission");
20538                pw.println("    pref[erred]: print preferred package settings");
20539                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20540                pw.println("    prov[iders]: dump content providers");
20541                pw.println("    p[ackages]: dump installed packages");
20542                pw.println("    s[hared-users]: dump shared user IDs");
20543                pw.println("    m[essages]: print collected runtime messages");
20544                pw.println("    v[erifiers]: print package verifier info");
20545                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20546                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20547                pw.println("    version: print database version info");
20548                pw.println("    write: write current settings now");
20549                pw.println("    installs: details about install sessions");
20550                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20551                pw.println("    dexopt: dump dexopt state");
20552                pw.println("    compiler-stats: dump compiler statistics");
20553                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20554                pw.println("    <package.name>: info about given package");
20555                return;
20556            } else if ("--checkin".equals(opt)) {
20557                checkin = true;
20558            } else if ("-f".equals(opt)) {
20559                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20560            } else if ("--proto".equals(opt)) {
20561                dumpProto(fd);
20562                return;
20563            } else {
20564                pw.println("Unknown argument: " + opt + "; use -h for help");
20565            }
20566        }
20567
20568        // Is the caller requesting to dump a particular piece of data?
20569        if (opti < args.length) {
20570            String cmd = args[opti];
20571            opti++;
20572            // Is this a package name?
20573            if ("android".equals(cmd) || cmd.contains(".")) {
20574                packageName = cmd;
20575                // When dumping a single package, we always dump all of its
20576                // filter information since the amount of data will be reasonable.
20577                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20578            } else if ("check-permission".equals(cmd)) {
20579                if (opti >= args.length) {
20580                    pw.println("Error: check-permission missing permission argument");
20581                    return;
20582                }
20583                String perm = args[opti];
20584                opti++;
20585                if (opti >= args.length) {
20586                    pw.println("Error: check-permission missing package argument");
20587                    return;
20588                }
20589
20590                String pkg = args[opti];
20591                opti++;
20592                int user = UserHandle.getUserId(Binder.getCallingUid());
20593                if (opti < args.length) {
20594                    try {
20595                        user = Integer.parseInt(args[opti]);
20596                    } catch (NumberFormatException e) {
20597                        pw.println("Error: check-permission user argument is not a number: "
20598                                + args[opti]);
20599                        return;
20600                    }
20601                }
20602
20603                // Normalize package name to handle renamed packages and static libs
20604                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20605
20606                pw.println(checkPermission(perm, pkg, user));
20607                return;
20608            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20609                dumpState.setDump(DumpState.DUMP_LIBS);
20610            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20611                dumpState.setDump(DumpState.DUMP_FEATURES);
20612            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20613                if (opti >= args.length) {
20614                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20615                            | DumpState.DUMP_SERVICE_RESOLVERS
20616                            | DumpState.DUMP_RECEIVER_RESOLVERS
20617                            | DumpState.DUMP_CONTENT_RESOLVERS);
20618                } else {
20619                    while (opti < args.length) {
20620                        String name = args[opti];
20621                        if ("a".equals(name) || "activity".equals(name)) {
20622                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20623                        } else if ("s".equals(name) || "service".equals(name)) {
20624                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20625                        } else if ("r".equals(name) || "receiver".equals(name)) {
20626                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20627                        } else if ("c".equals(name) || "content".equals(name)) {
20628                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20629                        } else {
20630                            pw.println("Error: unknown resolver table type: " + name);
20631                            return;
20632                        }
20633                        opti++;
20634                    }
20635                }
20636            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20637                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20638            } else if ("permission".equals(cmd)) {
20639                if (opti >= args.length) {
20640                    pw.println("Error: permission requires permission name");
20641                    return;
20642                }
20643                permissionNames = new ArraySet<>();
20644                while (opti < args.length) {
20645                    permissionNames.add(args[opti]);
20646                    opti++;
20647                }
20648                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20649                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20650            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20651                dumpState.setDump(DumpState.DUMP_PREFERRED);
20652            } else if ("preferred-xml".equals(cmd)) {
20653                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20654                if (opti < args.length && "--full".equals(args[opti])) {
20655                    fullPreferred = true;
20656                    opti++;
20657                }
20658            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20659                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20660            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20661                dumpState.setDump(DumpState.DUMP_PACKAGES);
20662            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20663                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20664            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20665                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20666            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20667                dumpState.setDump(DumpState.DUMP_MESSAGES);
20668            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20669                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20670            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20671                    || "intent-filter-verifiers".equals(cmd)) {
20672                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20673            } else if ("version".equals(cmd)) {
20674                dumpState.setDump(DumpState.DUMP_VERSION);
20675            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20676                dumpState.setDump(DumpState.DUMP_KEYSETS);
20677            } else if ("installs".equals(cmd)) {
20678                dumpState.setDump(DumpState.DUMP_INSTALLS);
20679            } else if ("frozen".equals(cmd)) {
20680                dumpState.setDump(DumpState.DUMP_FROZEN);
20681            } else if ("volumes".equals(cmd)) {
20682                dumpState.setDump(DumpState.DUMP_VOLUMES);
20683            } else if ("dexopt".equals(cmd)) {
20684                dumpState.setDump(DumpState.DUMP_DEXOPT);
20685            } else if ("compiler-stats".equals(cmd)) {
20686                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20687            } else if ("changes".equals(cmd)) {
20688                dumpState.setDump(DumpState.DUMP_CHANGES);
20689            } else if ("write".equals(cmd)) {
20690                synchronized (mPackages) {
20691                    mSettings.writeLPr();
20692                    pw.println("Settings written.");
20693                    return;
20694                }
20695            }
20696        }
20697
20698        if (checkin) {
20699            pw.println("vers,1");
20700        }
20701
20702        // reader
20703        synchronized (mPackages) {
20704            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20705                if (!checkin) {
20706                    if (dumpState.onTitlePrinted())
20707                        pw.println();
20708                    pw.println("Database versions:");
20709                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20710                }
20711            }
20712
20713            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20714                if (!checkin) {
20715                    if (dumpState.onTitlePrinted())
20716                        pw.println();
20717                    pw.println("Verifiers:");
20718                    pw.print("  Required: ");
20719                    pw.print(mRequiredVerifierPackage);
20720                    pw.print(" (uid=");
20721                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20722                            UserHandle.USER_SYSTEM));
20723                    pw.println(")");
20724                } else if (mRequiredVerifierPackage != null) {
20725                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20726                    pw.print(",");
20727                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20728                            UserHandle.USER_SYSTEM));
20729                }
20730            }
20731
20732            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20733                    packageName == null) {
20734                if (mIntentFilterVerifierComponent != null) {
20735                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20736                    if (!checkin) {
20737                        if (dumpState.onTitlePrinted())
20738                            pw.println();
20739                        pw.println("Intent Filter Verifier:");
20740                        pw.print("  Using: ");
20741                        pw.print(verifierPackageName);
20742                        pw.print(" (uid=");
20743                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20744                                UserHandle.USER_SYSTEM));
20745                        pw.println(")");
20746                    } else if (verifierPackageName != null) {
20747                        pw.print("ifv,"); pw.print(verifierPackageName);
20748                        pw.print(",");
20749                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20750                                UserHandle.USER_SYSTEM));
20751                    }
20752                } else {
20753                    pw.println();
20754                    pw.println("No Intent Filter Verifier available!");
20755                }
20756            }
20757
20758            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20759                boolean printedHeader = false;
20760                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20761                while (it.hasNext()) {
20762                    String libName = it.next();
20763                    LongSparseArray<SharedLibraryEntry> versionedLib
20764                            = mSharedLibraries.get(libName);
20765                    if (versionedLib == null) {
20766                        continue;
20767                    }
20768                    final int versionCount = versionedLib.size();
20769                    for (int i = 0; i < versionCount; i++) {
20770                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20771                        if (!checkin) {
20772                            if (!printedHeader) {
20773                                if (dumpState.onTitlePrinted())
20774                                    pw.println();
20775                                pw.println("Libraries:");
20776                                printedHeader = true;
20777                            }
20778                            pw.print("  ");
20779                        } else {
20780                            pw.print("lib,");
20781                        }
20782                        pw.print(libEntry.info.getName());
20783                        if (libEntry.info.isStatic()) {
20784                            pw.print(" version=" + libEntry.info.getLongVersion());
20785                        }
20786                        if (!checkin) {
20787                            pw.print(" -> ");
20788                        }
20789                        if (libEntry.path != null) {
20790                            pw.print(" (jar) ");
20791                            pw.print(libEntry.path);
20792                        } else {
20793                            pw.print(" (apk) ");
20794                            pw.print(libEntry.apk);
20795                        }
20796                        pw.println();
20797                    }
20798                }
20799            }
20800
20801            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20802                if (dumpState.onTitlePrinted())
20803                    pw.println();
20804                if (!checkin) {
20805                    pw.println("Features:");
20806                }
20807
20808                synchronized (mAvailableFeatures) {
20809                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20810                        if (checkin) {
20811                            pw.print("feat,");
20812                            pw.print(feat.name);
20813                            pw.print(",");
20814                            pw.println(feat.version);
20815                        } else {
20816                            pw.print("  ");
20817                            pw.print(feat.name);
20818                            if (feat.version > 0) {
20819                                pw.print(" version=");
20820                                pw.print(feat.version);
20821                            }
20822                            pw.println();
20823                        }
20824                    }
20825                }
20826            }
20827
20828            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20829                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20830                        : "Activity Resolver Table:", "  ", packageName,
20831                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20832                    dumpState.setTitlePrinted(true);
20833                }
20834            }
20835            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20836                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20837                        : "Receiver Resolver Table:", "  ", packageName,
20838                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20839                    dumpState.setTitlePrinted(true);
20840                }
20841            }
20842            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20843                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20844                        : "Service Resolver Table:", "  ", packageName,
20845                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20846                    dumpState.setTitlePrinted(true);
20847                }
20848            }
20849            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20850                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20851                        : "Provider Resolver Table:", "  ", packageName,
20852                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20853                    dumpState.setTitlePrinted(true);
20854                }
20855            }
20856
20857            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20858                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20859                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20860                    int user = mSettings.mPreferredActivities.keyAt(i);
20861                    if (pir.dump(pw,
20862                            dumpState.getTitlePrinted()
20863                                ? "\nPreferred Activities User " + user + ":"
20864                                : "Preferred Activities User " + user + ":", "  ",
20865                            packageName, true, false)) {
20866                        dumpState.setTitlePrinted(true);
20867                    }
20868                }
20869            }
20870
20871            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20872                pw.flush();
20873                FileOutputStream fout = new FileOutputStream(fd);
20874                BufferedOutputStream str = new BufferedOutputStream(fout);
20875                XmlSerializer serializer = new FastXmlSerializer();
20876                try {
20877                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20878                    serializer.startDocument(null, true);
20879                    serializer.setFeature(
20880                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20881                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20882                    serializer.endDocument();
20883                    serializer.flush();
20884                } catch (IllegalArgumentException e) {
20885                    pw.println("Failed writing: " + e);
20886                } catch (IllegalStateException e) {
20887                    pw.println("Failed writing: " + e);
20888                } catch (IOException e) {
20889                    pw.println("Failed writing: " + e);
20890                }
20891            }
20892
20893            if (!checkin
20894                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20895                    && packageName == null) {
20896                pw.println();
20897                int count = mSettings.mPackages.size();
20898                if (count == 0) {
20899                    pw.println("No applications!");
20900                    pw.println();
20901                } else {
20902                    final String prefix = "  ";
20903                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20904                    if (allPackageSettings.size() == 0) {
20905                        pw.println("No domain preferred apps!");
20906                        pw.println();
20907                    } else {
20908                        pw.println("App verification status:");
20909                        pw.println();
20910                        count = 0;
20911                        for (PackageSetting ps : allPackageSettings) {
20912                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20913                            if (ivi == null || ivi.getPackageName() == null) continue;
20914                            pw.println(prefix + "Package: " + ivi.getPackageName());
20915                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
20916                            pw.println(prefix + "Status:  " + ivi.getStatusString());
20917                            pw.println();
20918                            count++;
20919                        }
20920                        if (count == 0) {
20921                            pw.println(prefix + "No app verification established.");
20922                            pw.println();
20923                        }
20924                        for (int userId : sUserManager.getUserIds()) {
20925                            pw.println("App linkages for user " + userId + ":");
20926                            pw.println();
20927                            count = 0;
20928                            for (PackageSetting ps : allPackageSettings) {
20929                                final long status = ps.getDomainVerificationStatusForUser(userId);
20930                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20931                                        && !DEBUG_DOMAIN_VERIFICATION) {
20932                                    continue;
20933                                }
20934                                pw.println(prefix + "Package: " + ps.name);
20935                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20936                                String statusStr = IntentFilterVerificationInfo.
20937                                        getStatusStringFromValue(status);
20938                                pw.println(prefix + "Status:  " + statusStr);
20939                                pw.println();
20940                                count++;
20941                            }
20942                            if (count == 0) {
20943                                pw.println(prefix + "No configured app linkages.");
20944                                pw.println();
20945                            }
20946                        }
20947                    }
20948                }
20949            }
20950
20951            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
20952                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
20953            }
20954
20955            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
20956                boolean printedSomething = false;
20957                for (PackageParser.Provider p : mProviders.mProviders.values()) {
20958                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20959                        continue;
20960                    }
20961                    if (!printedSomething) {
20962                        if (dumpState.onTitlePrinted())
20963                            pw.println();
20964                        pw.println("Registered ContentProviders:");
20965                        printedSomething = true;
20966                    }
20967                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
20968                    pw.print("    "); pw.println(p.toString());
20969                }
20970                printedSomething = false;
20971                for (Map.Entry<String, PackageParser.Provider> entry :
20972                        mProvidersByAuthority.entrySet()) {
20973                    PackageParser.Provider p = entry.getValue();
20974                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20975                        continue;
20976                    }
20977                    if (!printedSomething) {
20978                        if (dumpState.onTitlePrinted())
20979                            pw.println();
20980                        pw.println("ContentProvider Authorities:");
20981                        printedSomething = true;
20982                    }
20983                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
20984                    pw.print("    "); pw.println(p.toString());
20985                    if (p.info != null && p.info.applicationInfo != null) {
20986                        final String appInfo = p.info.applicationInfo.toString();
20987                        pw.print("      applicationInfo="); pw.println(appInfo);
20988                    }
20989                }
20990            }
20991
20992            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
20993                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
20994            }
20995
20996            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
20997                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
20998            }
20999
21000            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21001                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21002            }
21003
21004            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21005                if (dumpState.onTitlePrinted()) pw.println();
21006                pw.println("Package Changes:");
21007                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21008                final int K = mChangedPackages.size();
21009                for (int i = 0; i < K; i++) {
21010                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21011                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21012                    final int N = changes.size();
21013                    if (N == 0) {
21014                        pw.print("    "); pw.println("No packages changed");
21015                    } else {
21016                        for (int j = 0; j < N; j++) {
21017                            final String pkgName = changes.valueAt(j);
21018                            final int sequenceNumber = changes.keyAt(j);
21019                            pw.print("    ");
21020                            pw.print("seq=");
21021                            pw.print(sequenceNumber);
21022                            pw.print(", package=");
21023                            pw.println(pkgName);
21024                        }
21025                    }
21026                }
21027            }
21028
21029            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21030                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21031            }
21032
21033            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21034                // XXX should handle packageName != null by dumping only install data that
21035                // the given package is involved with.
21036                if (dumpState.onTitlePrinted()) pw.println();
21037
21038                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21039                ipw.println();
21040                ipw.println("Frozen packages:");
21041                ipw.increaseIndent();
21042                if (mFrozenPackages.size() == 0) {
21043                    ipw.println("(none)");
21044                } else {
21045                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21046                        ipw.println(mFrozenPackages.valueAt(i));
21047                    }
21048                }
21049                ipw.decreaseIndent();
21050            }
21051
21052            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21053                if (dumpState.onTitlePrinted()) pw.println();
21054
21055                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21056                ipw.println();
21057                ipw.println("Loaded volumes:");
21058                ipw.increaseIndent();
21059                if (mLoadedVolumes.size() == 0) {
21060                    ipw.println("(none)");
21061                } else {
21062                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
21063                        ipw.println(mLoadedVolumes.valueAt(i));
21064                    }
21065                }
21066                ipw.decreaseIndent();
21067            }
21068
21069            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21070                if (dumpState.onTitlePrinted()) pw.println();
21071                dumpDexoptStateLPr(pw, packageName);
21072            }
21073
21074            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21075                if (dumpState.onTitlePrinted()) pw.println();
21076                dumpCompilerStatsLPr(pw, packageName);
21077            }
21078
21079            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21080                if (dumpState.onTitlePrinted()) pw.println();
21081                mSettings.dumpReadMessagesLPr(pw, dumpState);
21082
21083                pw.println();
21084                pw.println("Package warning messages:");
21085                dumpCriticalInfo(pw, null);
21086            }
21087
21088            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21089                dumpCriticalInfo(pw, "msg,");
21090            }
21091        }
21092
21093        // PackageInstaller should be called outside of mPackages lock
21094        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21095            // XXX should handle packageName != null by dumping only install data that
21096            // the given package is involved with.
21097            if (dumpState.onTitlePrinted()) pw.println();
21098            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21099        }
21100    }
21101
21102    private void dumpProto(FileDescriptor fd) {
21103        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21104
21105        synchronized (mPackages) {
21106            final long requiredVerifierPackageToken =
21107                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21108            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21109            proto.write(
21110                    PackageServiceDumpProto.PackageShortProto.UID,
21111                    getPackageUid(
21112                            mRequiredVerifierPackage,
21113                            MATCH_DEBUG_TRIAGED_MISSING,
21114                            UserHandle.USER_SYSTEM));
21115            proto.end(requiredVerifierPackageToken);
21116
21117            if (mIntentFilterVerifierComponent != null) {
21118                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21119                final long verifierPackageToken =
21120                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21121                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21122                proto.write(
21123                        PackageServiceDumpProto.PackageShortProto.UID,
21124                        getPackageUid(
21125                                verifierPackageName,
21126                                MATCH_DEBUG_TRIAGED_MISSING,
21127                                UserHandle.USER_SYSTEM));
21128                proto.end(verifierPackageToken);
21129            }
21130
21131            dumpSharedLibrariesProto(proto);
21132            dumpFeaturesProto(proto);
21133            mSettings.dumpPackagesProto(proto);
21134            mSettings.dumpSharedUsersProto(proto);
21135            dumpCriticalInfo(proto);
21136        }
21137        proto.flush();
21138    }
21139
21140    private void dumpFeaturesProto(ProtoOutputStream proto) {
21141        synchronized (mAvailableFeatures) {
21142            final int count = mAvailableFeatures.size();
21143            for (int i = 0; i < count; i++) {
21144                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21145            }
21146        }
21147    }
21148
21149    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21150        final int count = mSharedLibraries.size();
21151        for (int i = 0; i < count; i++) {
21152            final String libName = mSharedLibraries.keyAt(i);
21153            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21154            if (versionedLib == null) {
21155                continue;
21156            }
21157            final int versionCount = versionedLib.size();
21158            for (int j = 0; j < versionCount; j++) {
21159                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21160                final long sharedLibraryToken =
21161                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21162                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21163                final boolean isJar = (libEntry.path != null);
21164                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21165                if (isJar) {
21166                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21167                } else {
21168                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21169                }
21170                proto.end(sharedLibraryToken);
21171            }
21172        }
21173    }
21174
21175    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21176        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21177        ipw.println();
21178        ipw.println("Dexopt state:");
21179        ipw.increaseIndent();
21180        Collection<PackageParser.Package> packages = null;
21181        if (packageName != null) {
21182            PackageParser.Package targetPackage = mPackages.get(packageName);
21183            if (targetPackage != null) {
21184                packages = Collections.singletonList(targetPackage);
21185            } else {
21186                ipw.println("Unable to find package: " + packageName);
21187                return;
21188            }
21189        } else {
21190            packages = mPackages.values();
21191        }
21192
21193        for (PackageParser.Package pkg : packages) {
21194            ipw.println("[" + pkg.packageName + "]");
21195            ipw.increaseIndent();
21196            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21197                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21198            ipw.decreaseIndent();
21199        }
21200    }
21201
21202    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21203        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21204        ipw.println();
21205        ipw.println("Compiler stats:");
21206        ipw.increaseIndent();
21207        Collection<PackageParser.Package> packages = null;
21208        if (packageName != null) {
21209            PackageParser.Package targetPackage = mPackages.get(packageName);
21210            if (targetPackage != null) {
21211                packages = Collections.singletonList(targetPackage);
21212            } else {
21213                ipw.println("Unable to find package: " + packageName);
21214                return;
21215            }
21216        } else {
21217            packages = mPackages.values();
21218        }
21219
21220        for (PackageParser.Package pkg : packages) {
21221            ipw.println("[" + pkg.packageName + "]");
21222            ipw.increaseIndent();
21223
21224            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21225            if (stats == null) {
21226                ipw.println("(No recorded stats)");
21227            } else {
21228                stats.dump(ipw);
21229            }
21230            ipw.decreaseIndent();
21231        }
21232    }
21233
21234    private String dumpDomainString(String packageName) {
21235        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21236                .getList();
21237        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21238
21239        ArraySet<String> result = new ArraySet<>();
21240        if (iviList.size() > 0) {
21241            for (IntentFilterVerificationInfo ivi : iviList) {
21242                for (String host : ivi.getDomains()) {
21243                    result.add(host);
21244                }
21245            }
21246        }
21247        if (filters != null && filters.size() > 0) {
21248            for (IntentFilter filter : filters) {
21249                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21250                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21251                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21252                    result.addAll(filter.getHostsList());
21253                }
21254            }
21255        }
21256
21257        StringBuilder sb = new StringBuilder(result.size() * 16);
21258        for (String domain : result) {
21259            if (sb.length() > 0) sb.append(" ");
21260            sb.append(domain);
21261        }
21262        return sb.toString();
21263    }
21264
21265    // ------- apps on sdcard specific code -------
21266    static final boolean DEBUG_SD_INSTALL = false;
21267
21268    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21269
21270    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21271
21272    private boolean mMediaMounted = false;
21273
21274    static String getEncryptKey() {
21275        try {
21276            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21277                    SD_ENCRYPTION_KEYSTORE_NAME);
21278            if (sdEncKey == null) {
21279                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21280                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21281                if (sdEncKey == null) {
21282                    Slog.e(TAG, "Failed to create encryption keys");
21283                    return null;
21284                }
21285            }
21286            return sdEncKey;
21287        } catch (NoSuchAlgorithmException nsae) {
21288            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21289            return null;
21290        } catch (IOException ioe) {
21291            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21292            return null;
21293        }
21294    }
21295
21296    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21297            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21298        final int size = infos.size();
21299        final String[] packageNames = new String[size];
21300        final int[] packageUids = new int[size];
21301        for (int i = 0; i < size; i++) {
21302            final ApplicationInfo info = infos.get(i);
21303            packageNames[i] = info.packageName;
21304            packageUids[i] = info.uid;
21305        }
21306        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21307                finishedReceiver);
21308    }
21309
21310    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21311            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21312        sendResourcesChangedBroadcast(mediaStatus, replacing,
21313                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21314    }
21315
21316    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21317            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21318        int size = pkgList.length;
21319        if (size > 0) {
21320            // Send broadcasts here
21321            Bundle extras = new Bundle();
21322            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21323            if (uidArr != null) {
21324                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21325            }
21326            if (replacing) {
21327                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21328            }
21329            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21330                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21331            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21332        }
21333    }
21334
21335    private void loadPrivatePackages(final VolumeInfo vol) {
21336        mHandler.post(new Runnable() {
21337            @Override
21338            public void run() {
21339                loadPrivatePackagesInner(vol);
21340            }
21341        });
21342    }
21343
21344    private void loadPrivatePackagesInner(VolumeInfo vol) {
21345        final String volumeUuid = vol.fsUuid;
21346        if (TextUtils.isEmpty(volumeUuid)) {
21347            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21348            return;
21349        }
21350
21351        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21352        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21353        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21354
21355        final VersionInfo ver;
21356        final List<PackageSetting> packages;
21357        synchronized (mPackages) {
21358            ver = mSettings.findOrCreateVersion(volumeUuid);
21359            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21360        }
21361
21362        for (PackageSetting ps : packages) {
21363            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21364            synchronized (mInstallLock) {
21365                final PackageParser.Package pkg;
21366                try {
21367                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21368                    loaded.add(pkg.applicationInfo);
21369
21370                } catch (PackageManagerException e) {
21371                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21372                }
21373
21374                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21375                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21376                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21377                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21378                }
21379            }
21380        }
21381
21382        // Reconcile app data for all started/unlocked users
21383        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21384        final UserManager um = mContext.getSystemService(UserManager.class);
21385        UserManagerInternal umInternal = getUserManagerInternal();
21386        for (UserInfo user : um.getUsers()) {
21387            final int flags;
21388            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21389                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21390            } else if (umInternal.isUserRunning(user.id)) {
21391                flags = StorageManager.FLAG_STORAGE_DE;
21392            } else {
21393                continue;
21394            }
21395
21396            try {
21397                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21398                synchronized (mInstallLock) {
21399                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21400                }
21401            } catch (IllegalStateException e) {
21402                // Device was probably ejected, and we'll process that event momentarily
21403                Slog.w(TAG, "Failed to prepare storage: " + e);
21404            }
21405        }
21406
21407        synchronized (mPackages) {
21408            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21409            if (sdkUpdated) {
21410                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21411                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21412            }
21413            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21414                    mPermissionCallback);
21415
21416            // Yay, everything is now upgraded
21417            ver.forceCurrent();
21418
21419            mSettings.writeLPr();
21420        }
21421
21422        for (PackageFreezer freezer : freezers) {
21423            freezer.close();
21424        }
21425
21426        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21427        sendResourcesChangedBroadcast(true, false, loaded, null);
21428        mLoadedVolumes.add(vol.getId());
21429    }
21430
21431    private void unloadPrivatePackages(final VolumeInfo vol) {
21432        mHandler.post(new Runnable() {
21433            @Override
21434            public void run() {
21435                unloadPrivatePackagesInner(vol);
21436            }
21437        });
21438    }
21439
21440    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21441        final String volumeUuid = vol.fsUuid;
21442        if (TextUtils.isEmpty(volumeUuid)) {
21443            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21444            return;
21445        }
21446
21447        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21448        synchronized (mInstallLock) {
21449        synchronized (mPackages) {
21450            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21451            for (PackageSetting ps : packages) {
21452                if (ps.pkg == null) continue;
21453
21454                final ApplicationInfo info = ps.pkg.applicationInfo;
21455                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21456                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21457
21458                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21459                        "unloadPrivatePackagesInner")) {
21460                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21461                            false, null)) {
21462                        unloaded.add(info);
21463                    } else {
21464                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21465                    }
21466                }
21467
21468                // Try very hard to release any references to this package
21469                // so we don't risk the system server being killed due to
21470                // open FDs
21471                AttributeCache.instance().removePackage(ps.name);
21472            }
21473
21474            mSettings.writeLPr();
21475        }
21476        }
21477
21478        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21479        sendResourcesChangedBroadcast(false, false, unloaded, null);
21480        mLoadedVolumes.remove(vol.getId());
21481
21482        // Try very hard to release any references to this path so we don't risk
21483        // the system server being killed due to open FDs
21484        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21485
21486        for (int i = 0; i < 3; i++) {
21487            System.gc();
21488            System.runFinalization();
21489        }
21490    }
21491
21492    private void assertPackageKnown(String volumeUuid, String packageName)
21493            throws PackageManagerException {
21494        synchronized (mPackages) {
21495            // Normalize package name to handle renamed packages
21496            packageName = normalizePackageNameLPr(packageName);
21497
21498            final PackageSetting ps = mSettings.mPackages.get(packageName);
21499            if (ps == null) {
21500                throw new PackageManagerException("Package " + packageName + " is unknown");
21501            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21502                throw new PackageManagerException(
21503                        "Package " + packageName + " found on unknown volume " + volumeUuid
21504                                + "; expected volume " + ps.volumeUuid);
21505            }
21506        }
21507    }
21508
21509    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21510            throws PackageManagerException {
21511        synchronized (mPackages) {
21512            // Normalize package name to handle renamed packages
21513            packageName = normalizePackageNameLPr(packageName);
21514
21515            final PackageSetting ps = mSettings.mPackages.get(packageName);
21516            if (ps == null) {
21517                throw new PackageManagerException("Package " + packageName + " is unknown");
21518            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21519                throw new PackageManagerException(
21520                        "Package " + packageName + " found on unknown volume " + volumeUuid
21521                                + "; expected volume " + ps.volumeUuid);
21522            } else if (!ps.getInstalled(userId)) {
21523                throw new PackageManagerException(
21524                        "Package " + packageName + " not installed for user " + userId);
21525            }
21526        }
21527    }
21528
21529    private List<String> collectAbsoluteCodePaths() {
21530        synchronized (mPackages) {
21531            List<String> codePaths = new ArrayList<>();
21532            final int packageCount = mSettings.mPackages.size();
21533            for (int i = 0; i < packageCount; i++) {
21534                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21535                codePaths.add(ps.codePath.getAbsolutePath());
21536            }
21537            return codePaths;
21538        }
21539    }
21540
21541    /**
21542     * Examine all apps present on given mounted volume, and destroy apps that
21543     * aren't expected, either due to uninstallation or reinstallation on
21544     * another volume.
21545     */
21546    private void reconcileApps(String volumeUuid) {
21547        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21548        List<File> filesToDelete = null;
21549
21550        final File[] files = FileUtils.listFilesOrEmpty(
21551                Environment.getDataAppDirectory(volumeUuid));
21552        for (File file : files) {
21553            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21554                    && !PackageInstallerService.isStageName(file.getName());
21555            if (!isPackage) {
21556                // Ignore entries which are not packages
21557                continue;
21558            }
21559
21560            String absolutePath = file.getAbsolutePath();
21561
21562            boolean pathValid = false;
21563            final int absoluteCodePathCount = absoluteCodePaths.size();
21564            for (int i = 0; i < absoluteCodePathCount; i++) {
21565                String absoluteCodePath = absoluteCodePaths.get(i);
21566                if (absolutePath.startsWith(absoluteCodePath)) {
21567                    pathValid = true;
21568                    break;
21569                }
21570            }
21571
21572            if (!pathValid) {
21573                if (filesToDelete == null) {
21574                    filesToDelete = new ArrayList<>();
21575                }
21576                filesToDelete.add(file);
21577            }
21578        }
21579
21580        if (filesToDelete != null) {
21581            final int fileToDeleteCount = filesToDelete.size();
21582            for (int i = 0; i < fileToDeleteCount; i++) {
21583                File fileToDelete = filesToDelete.get(i);
21584                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21585                synchronized (mInstallLock) {
21586                    removeCodePathLI(fileToDelete);
21587                }
21588            }
21589        }
21590    }
21591
21592    /**
21593     * Reconcile all app data for the given user.
21594     * <p>
21595     * Verifies that directories exist and that ownership and labeling is
21596     * correct for all installed apps on all mounted volumes.
21597     */
21598    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21599        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21600        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21601            final String volumeUuid = vol.getFsUuid();
21602            synchronized (mInstallLock) {
21603                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21604            }
21605        }
21606    }
21607
21608    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21609            boolean migrateAppData) {
21610        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21611    }
21612
21613    /**
21614     * Reconcile all app data on given mounted volume.
21615     * <p>
21616     * Destroys app data that isn't expected, either due to uninstallation or
21617     * reinstallation on another volume.
21618     * <p>
21619     * Verifies that directories exist and that ownership and labeling is
21620     * correct for all installed apps.
21621     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
21622     */
21623    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21624            boolean migrateAppData, boolean onlyCoreApps) {
21625        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21626                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21627        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21628
21629        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21630        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21631
21632        // First look for stale data that doesn't belong, and check if things
21633        // have changed since we did our last restorecon
21634        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21635            if (StorageManager.isFileEncryptedNativeOrEmulated()
21636                    && !StorageManager.isUserKeyUnlocked(userId)) {
21637                throw new RuntimeException(
21638                        "Yikes, someone asked us to reconcile CE storage while " + userId
21639                                + " was still locked; this would have caused massive data loss!");
21640            }
21641
21642            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21643            for (File file : files) {
21644                final String packageName = file.getName();
21645                try {
21646                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21647                } catch (PackageManagerException e) {
21648                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21649                    try {
21650                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21651                                StorageManager.FLAG_STORAGE_CE, 0);
21652                    } catch (InstallerException e2) {
21653                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21654                    }
21655                }
21656            }
21657        }
21658        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21659            final File[] files = FileUtils.listFilesOrEmpty(deDir);
21660            for (File file : files) {
21661                final String packageName = file.getName();
21662                try {
21663                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21664                } catch (PackageManagerException e) {
21665                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21666                    try {
21667                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21668                                StorageManager.FLAG_STORAGE_DE, 0);
21669                    } catch (InstallerException e2) {
21670                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21671                    }
21672                }
21673            }
21674        }
21675
21676        // Ensure that data directories are ready to roll for all packages
21677        // installed for this volume and user
21678        final List<PackageSetting> packages;
21679        synchronized (mPackages) {
21680            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21681        }
21682        int preparedCount = 0;
21683        for (PackageSetting ps : packages) {
21684            final String packageName = ps.name;
21685            if (ps.pkg == null) {
21686                Slog.w(TAG, "Odd, missing scanned package " + packageName);
21687                // TODO: might be due to legacy ASEC apps; we should circle back
21688                // and reconcile again once they're scanned
21689                continue;
21690            }
21691            // Skip non-core apps if requested
21692            if (onlyCoreApps && !ps.pkg.coreApp) {
21693                result.add(packageName);
21694                continue;
21695            }
21696
21697            if (ps.getInstalled(userId)) {
21698                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21699                preparedCount++;
21700            }
21701        }
21702
21703        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21704        return result;
21705    }
21706
21707    /**
21708     * Prepare app data for the given app just after it was installed or
21709     * upgraded. This method carefully only touches users that it's installed
21710     * for, and it forces a restorecon to handle any seinfo changes.
21711     * <p>
21712     * Verifies that directories exist and that ownership and labeling is
21713     * correct for all installed apps. If there is an ownership mismatch, it
21714     * will try recovering system apps by wiping data; third-party app data is
21715     * left intact.
21716     * <p>
21717     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21718     */
21719    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21720        final PackageSetting ps;
21721        synchronized (mPackages) {
21722            ps = mSettings.mPackages.get(pkg.packageName);
21723            mSettings.writeKernelMappingLPr(ps);
21724        }
21725
21726        final UserManager um = mContext.getSystemService(UserManager.class);
21727        UserManagerInternal umInternal = getUserManagerInternal();
21728        for (UserInfo user : um.getUsers()) {
21729            final int flags;
21730            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21731                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21732            } else if (umInternal.isUserRunning(user.id)) {
21733                flags = StorageManager.FLAG_STORAGE_DE;
21734            } else {
21735                continue;
21736            }
21737
21738            if (ps.getInstalled(user.id)) {
21739                // TODO: when user data is locked, mark that we're still dirty
21740                prepareAppDataLIF(pkg, user.id, flags);
21741            }
21742        }
21743    }
21744
21745    /**
21746     * Prepare app data for the given app.
21747     * <p>
21748     * Verifies that directories exist and that ownership and labeling is
21749     * correct for all installed apps. If there is an ownership mismatch, this
21750     * will try recovering system apps by wiping data; third-party app data is
21751     * left intact.
21752     */
21753    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21754        if (pkg == null) {
21755            Slog.wtf(TAG, "Package was null!", new Throwable());
21756            return;
21757        }
21758        prepareAppDataLeafLIF(pkg, userId, flags);
21759        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21760        for (int i = 0; i < childCount; i++) {
21761            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21762        }
21763    }
21764
21765    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
21766            boolean maybeMigrateAppData) {
21767        prepareAppDataLIF(pkg, userId, flags);
21768
21769        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21770            // We may have just shuffled around app data directories, so
21771            // prepare them one more time
21772            prepareAppDataLIF(pkg, userId, flags);
21773        }
21774    }
21775
21776    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21777        if (DEBUG_APP_DATA) {
21778            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21779                    + Integer.toHexString(flags));
21780        }
21781
21782        final String volumeUuid = pkg.volumeUuid;
21783        final String packageName = pkg.packageName;
21784        final ApplicationInfo app = pkg.applicationInfo;
21785        final int appId = UserHandle.getAppId(app.uid);
21786
21787        Preconditions.checkNotNull(app.seInfo);
21788
21789        long ceDataInode = -1;
21790        try {
21791            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21792                    appId, app.seInfo, app.targetSdkVersion);
21793        } catch (InstallerException e) {
21794            if (app.isSystemApp()) {
21795                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21796                        + ", but trying to recover: " + e);
21797                destroyAppDataLeafLIF(pkg, userId, flags);
21798                try {
21799                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21800                            appId, app.seInfo, app.targetSdkVersion);
21801                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21802                } catch (InstallerException e2) {
21803                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
21804                }
21805            } else {
21806                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21807            }
21808        }
21809
21810        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21811            // TODO: mark this structure as dirty so we persist it!
21812            synchronized (mPackages) {
21813                final PackageSetting ps = mSettings.mPackages.get(packageName);
21814                if (ps != null) {
21815                    ps.setCeDataInode(ceDataInode, userId);
21816                }
21817            }
21818        }
21819
21820        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21821    }
21822
21823    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21824        if (pkg == null) {
21825            Slog.wtf(TAG, "Package was null!", new Throwable());
21826            return;
21827        }
21828        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21829        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21830        for (int i = 0; i < childCount; i++) {
21831            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21832        }
21833    }
21834
21835    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21836        final String volumeUuid = pkg.volumeUuid;
21837        final String packageName = pkg.packageName;
21838        final ApplicationInfo app = pkg.applicationInfo;
21839
21840        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21841            // Create a native library symlink only if we have native libraries
21842            // and if the native libraries are 32 bit libraries. We do not provide
21843            // this symlink for 64 bit libraries.
21844            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21845                final String nativeLibPath = app.nativeLibraryDir;
21846                try {
21847                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21848                            nativeLibPath, userId);
21849                } catch (InstallerException e) {
21850                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21851                }
21852            }
21853        }
21854    }
21855
21856    /**
21857     * For system apps on non-FBE devices, this method migrates any existing
21858     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21859     * requested by the app.
21860     */
21861    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
21862        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
21863                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
21864            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
21865                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
21866            try {
21867                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
21868                        storageTarget);
21869            } catch (InstallerException e) {
21870                logCriticalInfo(Log.WARN,
21871                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
21872            }
21873            return true;
21874        } else {
21875            return false;
21876        }
21877    }
21878
21879    public PackageFreezer freezePackage(String packageName, String killReason) {
21880        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
21881    }
21882
21883    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
21884        return new PackageFreezer(packageName, userId, killReason);
21885    }
21886
21887    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
21888            String killReason) {
21889        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
21890    }
21891
21892    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
21893            String killReason) {
21894        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
21895            return new PackageFreezer();
21896        } else {
21897            return freezePackage(packageName, userId, killReason);
21898        }
21899    }
21900
21901    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
21902            String killReason) {
21903        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
21904    }
21905
21906    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
21907            String killReason) {
21908        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
21909            return new PackageFreezer();
21910        } else {
21911            return freezePackage(packageName, userId, killReason);
21912        }
21913    }
21914
21915    /**
21916     * Class that freezes and kills the given package upon creation, and
21917     * unfreezes it upon closing. This is typically used when doing surgery on
21918     * app code/data to prevent the app from running while you're working.
21919     */
21920    private class PackageFreezer implements AutoCloseable {
21921        private final String mPackageName;
21922        private final PackageFreezer[] mChildren;
21923
21924        private final boolean mWeFroze;
21925
21926        private final AtomicBoolean mClosed = new AtomicBoolean();
21927        private final CloseGuard mCloseGuard = CloseGuard.get();
21928
21929        /**
21930         * Create and return a stub freezer that doesn't actually do anything,
21931         * typically used when someone requested
21932         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
21933         * {@link PackageManager#DELETE_DONT_KILL_APP}.
21934         */
21935        public PackageFreezer() {
21936            mPackageName = null;
21937            mChildren = null;
21938            mWeFroze = false;
21939            mCloseGuard.open("close");
21940        }
21941
21942        public PackageFreezer(String packageName, int userId, String killReason) {
21943            synchronized (mPackages) {
21944                mPackageName = packageName;
21945                mWeFroze = mFrozenPackages.add(mPackageName);
21946
21947                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
21948                if (ps != null) {
21949                    killApplication(ps.name, ps.appId, userId, killReason);
21950                }
21951
21952                final PackageParser.Package p = mPackages.get(packageName);
21953                if (p != null && p.childPackages != null) {
21954                    final int N = p.childPackages.size();
21955                    mChildren = new PackageFreezer[N];
21956                    for (int i = 0; i < N; i++) {
21957                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
21958                                userId, killReason);
21959                    }
21960                } else {
21961                    mChildren = null;
21962                }
21963            }
21964            mCloseGuard.open("close");
21965        }
21966
21967        @Override
21968        protected void finalize() throws Throwable {
21969            try {
21970                if (mCloseGuard != null) {
21971                    mCloseGuard.warnIfOpen();
21972                }
21973
21974                close();
21975            } finally {
21976                super.finalize();
21977            }
21978        }
21979
21980        @Override
21981        public void close() {
21982            mCloseGuard.close();
21983            if (mClosed.compareAndSet(false, true)) {
21984                synchronized (mPackages) {
21985                    if (mWeFroze) {
21986                        mFrozenPackages.remove(mPackageName);
21987                    }
21988
21989                    if (mChildren != null) {
21990                        for (PackageFreezer freezer : mChildren) {
21991                            freezer.close();
21992                        }
21993                    }
21994                }
21995            }
21996        }
21997    }
21998
21999    /**
22000     * Verify that given package is currently frozen.
22001     */
22002    private void checkPackageFrozen(String packageName) {
22003        synchronized (mPackages) {
22004            if (!mFrozenPackages.contains(packageName)) {
22005                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22006            }
22007        }
22008    }
22009
22010    @Override
22011    public int movePackage(final String packageName, final String volumeUuid) {
22012        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22013
22014        final int callingUid = Binder.getCallingUid();
22015        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22016        final int moveId = mNextMoveId.getAndIncrement();
22017        mHandler.post(new Runnable() {
22018            @Override
22019            public void run() {
22020                try {
22021                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22022                } catch (PackageManagerException e) {
22023                    Slog.w(TAG, "Failed to move " + packageName, e);
22024                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22025                }
22026            }
22027        });
22028        return moveId;
22029    }
22030
22031    private void movePackageInternal(final String packageName, final String volumeUuid,
22032            final int moveId, final int callingUid, UserHandle user)
22033                    throws PackageManagerException {
22034        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22035        final PackageManager pm = mContext.getPackageManager();
22036
22037        final boolean currentAsec;
22038        final String currentVolumeUuid;
22039        final File codeFile;
22040        final String installerPackageName;
22041        final String packageAbiOverride;
22042        final int appId;
22043        final String seinfo;
22044        final String label;
22045        final int targetSdkVersion;
22046        final PackageFreezer freezer;
22047        final int[] installedUserIds;
22048
22049        // reader
22050        synchronized (mPackages) {
22051            final PackageParser.Package pkg = mPackages.get(packageName);
22052            final PackageSetting ps = mSettings.mPackages.get(packageName);
22053            if (pkg == null
22054                    || ps == null
22055                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22056                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22057            }
22058            if (pkg.applicationInfo.isSystemApp()) {
22059                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22060                        "Cannot move system application");
22061            }
22062
22063            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22064            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22065                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22066            if (isInternalStorage && !allow3rdPartyOnInternal) {
22067                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22068                        "3rd party apps are not allowed on internal storage");
22069            }
22070
22071            if (pkg.applicationInfo.isExternalAsec()) {
22072                currentAsec = true;
22073                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22074            } else if (pkg.applicationInfo.isForwardLocked()) {
22075                currentAsec = true;
22076                currentVolumeUuid = "forward_locked";
22077            } else {
22078                currentAsec = false;
22079                currentVolumeUuid = ps.volumeUuid;
22080
22081                final File probe = new File(pkg.codePath);
22082                final File probeOat = new File(probe, "oat");
22083                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22084                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22085                            "Move only supported for modern cluster style installs");
22086                }
22087            }
22088
22089            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22090                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22091                        "Package already moved to " + volumeUuid);
22092            }
22093            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22094                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22095                        "Device admin cannot be moved");
22096            }
22097
22098            if (mFrozenPackages.contains(packageName)) {
22099                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22100                        "Failed to move already frozen package");
22101            }
22102
22103            codeFile = new File(pkg.codePath);
22104            installerPackageName = ps.installerPackageName;
22105            packageAbiOverride = ps.cpuAbiOverrideString;
22106            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22107            seinfo = pkg.applicationInfo.seInfo;
22108            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22109            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22110            freezer = freezePackage(packageName, "movePackageInternal");
22111            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22112        }
22113
22114        final Bundle extras = new Bundle();
22115        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22116        extras.putString(Intent.EXTRA_TITLE, label);
22117        mMoveCallbacks.notifyCreated(moveId, extras);
22118
22119        int installFlags;
22120        final boolean moveCompleteApp;
22121        final File measurePath;
22122
22123        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22124            installFlags = INSTALL_INTERNAL;
22125            moveCompleteApp = !currentAsec;
22126            measurePath = Environment.getDataAppDirectory(volumeUuid);
22127        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22128            installFlags = INSTALL_EXTERNAL;
22129            moveCompleteApp = false;
22130            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22131        } else {
22132            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22133            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22134                    || !volume.isMountedWritable()) {
22135                freezer.close();
22136                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22137                        "Move location not mounted private volume");
22138            }
22139
22140            Preconditions.checkState(!currentAsec);
22141
22142            installFlags = INSTALL_INTERNAL;
22143            moveCompleteApp = true;
22144            measurePath = Environment.getDataAppDirectory(volumeUuid);
22145        }
22146
22147        // If we're moving app data around, we need all the users unlocked
22148        if (moveCompleteApp) {
22149            for (int userId : installedUserIds) {
22150                if (StorageManager.isFileEncryptedNativeOrEmulated()
22151                        && !StorageManager.isUserKeyUnlocked(userId)) {
22152                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22153                            "User " + userId + " must be unlocked");
22154                }
22155            }
22156        }
22157
22158        final PackageStats stats = new PackageStats(null, -1);
22159        synchronized (mInstaller) {
22160            for (int userId : installedUserIds) {
22161                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22162                    freezer.close();
22163                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22164                            "Failed to measure package size");
22165                }
22166            }
22167        }
22168
22169        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22170                + stats.dataSize);
22171
22172        final long startFreeBytes = measurePath.getUsableSpace();
22173        final long sizeBytes;
22174        if (moveCompleteApp) {
22175            sizeBytes = stats.codeSize + stats.dataSize;
22176        } else {
22177            sizeBytes = stats.codeSize;
22178        }
22179
22180        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22181            freezer.close();
22182            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22183                    "Not enough free space to move");
22184        }
22185
22186        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22187
22188        final CountDownLatch installedLatch = new CountDownLatch(1);
22189        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22190            @Override
22191            public void onUserActionRequired(Intent intent) throws RemoteException {
22192                throw new IllegalStateException();
22193            }
22194
22195            @Override
22196            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22197                    Bundle extras) throws RemoteException {
22198                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22199                        + PackageManager.installStatusToString(returnCode, msg));
22200
22201                installedLatch.countDown();
22202                freezer.close();
22203
22204                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22205                switch (status) {
22206                    case PackageInstaller.STATUS_SUCCESS:
22207                        mMoveCallbacks.notifyStatusChanged(moveId,
22208                                PackageManager.MOVE_SUCCEEDED);
22209                        break;
22210                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22211                        mMoveCallbacks.notifyStatusChanged(moveId,
22212                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22213                        break;
22214                    default:
22215                        mMoveCallbacks.notifyStatusChanged(moveId,
22216                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22217                        break;
22218                }
22219            }
22220        };
22221
22222        final MoveInfo move;
22223        if (moveCompleteApp) {
22224            // Kick off a thread to report progress estimates
22225            new Thread() {
22226                @Override
22227                public void run() {
22228                    while (true) {
22229                        try {
22230                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22231                                break;
22232                            }
22233                        } catch (InterruptedException ignored) {
22234                        }
22235
22236                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22237                        final int progress = 10 + (int) MathUtils.constrain(
22238                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22239                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22240                    }
22241                }
22242            }.start();
22243
22244            final String dataAppName = codeFile.getName();
22245            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22246                    dataAppName, appId, seinfo, targetSdkVersion);
22247        } else {
22248            move = null;
22249        }
22250
22251        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22252
22253        final Message msg = mHandler.obtainMessage(INIT_COPY);
22254        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22255        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22256                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22257                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22258                PackageManager.INSTALL_REASON_UNKNOWN);
22259        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22260        msg.obj = params;
22261
22262        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22263                System.identityHashCode(msg.obj));
22264        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22265                System.identityHashCode(msg.obj));
22266
22267        mHandler.sendMessage(msg);
22268    }
22269
22270    @Override
22271    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22272        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22273
22274        final int realMoveId = mNextMoveId.getAndIncrement();
22275        final Bundle extras = new Bundle();
22276        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22277        mMoveCallbacks.notifyCreated(realMoveId, extras);
22278
22279        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22280            @Override
22281            public void onCreated(int moveId, Bundle extras) {
22282                // Ignored
22283            }
22284
22285            @Override
22286            public void onStatusChanged(int moveId, int status, long estMillis) {
22287                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22288            }
22289        };
22290
22291        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22292        storage.setPrimaryStorageUuid(volumeUuid, callback);
22293        return realMoveId;
22294    }
22295
22296    @Override
22297    public int getMoveStatus(int moveId) {
22298        mContext.enforceCallingOrSelfPermission(
22299                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22300        return mMoveCallbacks.mLastStatus.get(moveId);
22301    }
22302
22303    @Override
22304    public void registerMoveCallback(IPackageMoveObserver callback) {
22305        mContext.enforceCallingOrSelfPermission(
22306                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22307        mMoveCallbacks.register(callback);
22308    }
22309
22310    @Override
22311    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22312        mContext.enforceCallingOrSelfPermission(
22313                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22314        mMoveCallbacks.unregister(callback);
22315    }
22316
22317    @Override
22318    public boolean setInstallLocation(int loc) {
22319        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22320                null);
22321        if (getInstallLocation() == loc) {
22322            return true;
22323        }
22324        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22325                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22326            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22327                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22328            return true;
22329        }
22330        return false;
22331   }
22332
22333    @Override
22334    public int getInstallLocation() {
22335        // allow instant app access
22336        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22337                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22338                PackageHelper.APP_INSTALL_AUTO);
22339    }
22340
22341    /** Called by UserManagerService */
22342    void cleanUpUser(UserManagerService userManager, int userHandle) {
22343        synchronized (mPackages) {
22344            mDirtyUsers.remove(userHandle);
22345            mUserNeedsBadging.delete(userHandle);
22346            mSettings.removeUserLPw(userHandle);
22347            mPendingBroadcasts.remove(userHandle);
22348            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22349            removeUnusedPackagesLPw(userManager, userHandle);
22350        }
22351    }
22352
22353    /**
22354     * We're removing userHandle and would like to remove any downloaded packages
22355     * that are no longer in use by any other user.
22356     * @param userHandle the user being removed
22357     */
22358    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22359        final boolean DEBUG_CLEAN_APKS = false;
22360        int [] users = userManager.getUserIds();
22361        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22362        while (psit.hasNext()) {
22363            PackageSetting ps = psit.next();
22364            if (ps.pkg == null) {
22365                continue;
22366            }
22367            final String packageName = ps.pkg.packageName;
22368            // Skip over if system app
22369            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22370                continue;
22371            }
22372            if (DEBUG_CLEAN_APKS) {
22373                Slog.i(TAG, "Checking package " + packageName);
22374            }
22375            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22376            if (keep) {
22377                if (DEBUG_CLEAN_APKS) {
22378                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22379                }
22380            } else {
22381                for (int i = 0; i < users.length; i++) {
22382                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22383                        keep = true;
22384                        if (DEBUG_CLEAN_APKS) {
22385                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22386                                    + users[i]);
22387                        }
22388                        break;
22389                    }
22390                }
22391            }
22392            if (!keep) {
22393                if (DEBUG_CLEAN_APKS) {
22394                    Slog.i(TAG, "  Removing package " + packageName);
22395                }
22396                mHandler.post(new Runnable() {
22397                    public void run() {
22398                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22399                                userHandle, 0);
22400                    } //end run
22401                });
22402            }
22403        }
22404    }
22405
22406    /** Called by UserManagerService */
22407    void createNewUser(int userId, String[] disallowedPackages) {
22408        synchronized (mInstallLock) {
22409            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22410        }
22411        synchronized (mPackages) {
22412            scheduleWritePackageRestrictionsLocked(userId);
22413            scheduleWritePackageListLocked(userId);
22414            applyFactoryDefaultBrowserLPw(userId);
22415            primeDomainVerificationsLPw(userId);
22416        }
22417    }
22418
22419    void onNewUserCreated(final int userId) {
22420        synchronized(mPackages) {
22421            mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
22422            // If permission review for legacy apps is required, we represent
22423            // dagerous permissions for such apps as always granted runtime
22424            // permissions to keep per user flag state whether review is needed.
22425            // Hence, if a new user is added we have to propagate dangerous
22426            // permission grants for these legacy apps.
22427            if (mSettings.mPermissions.mPermissionReviewRequired) {
22428// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22429                mPermissionManager.updateAllPermissions(
22430                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22431                        mPermissionCallback);
22432            }
22433        }
22434    }
22435
22436    @Override
22437    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22438        mContext.enforceCallingOrSelfPermission(
22439                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22440                "Only package verification agents can read the verifier device identity");
22441
22442        synchronized (mPackages) {
22443            return mSettings.getVerifierDeviceIdentityLPw();
22444        }
22445    }
22446
22447    @Override
22448    public void setPermissionEnforced(String permission, boolean enforced) {
22449        // TODO: Now that we no longer change GID for storage, this should to away.
22450        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22451                "setPermissionEnforced");
22452        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22453            synchronized (mPackages) {
22454                if (mSettings.mReadExternalStorageEnforced == null
22455                        || mSettings.mReadExternalStorageEnforced != enforced) {
22456                    mSettings.mReadExternalStorageEnforced =
22457                            enforced ? Boolean.TRUE : Boolean.FALSE;
22458                    mSettings.writeLPr();
22459                }
22460            }
22461            // kill any non-foreground processes so we restart them and
22462            // grant/revoke the GID.
22463            final IActivityManager am = ActivityManager.getService();
22464            if (am != null) {
22465                final long token = Binder.clearCallingIdentity();
22466                try {
22467                    am.killProcessesBelowForeground("setPermissionEnforcement");
22468                } catch (RemoteException e) {
22469                } finally {
22470                    Binder.restoreCallingIdentity(token);
22471                }
22472            }
22473        } else {
22474            throw new IllegalArgumentException("No selective enforcement for " + permission);
22475        }
22476    }
22477
22478    @Override
22479    @Deprecated
22480    public boolean isPermissionEnforced(String permission) {
22481        // allow instant applications
22482        return true;
22483    }
22484
22485    @Override
22486    public boolean isStorageLow() {
22487        // allow instant applications
22488        final long token = Binder.clearCallingIdentity();
22489        try {
22490            final DeviceStorageMonitorInternal
22491                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22492            if (dsm != null) {
22493                return dsm.isMemoryLow();
22494            } else {
22495                return false;
22496            }
22497        } finally {
22498            Binder.restoreCallingIdentity(token);
22499        }
22500    }
22501
22502    @Override
22503    public IPackageInstaller getPackageInstaller() {
22504        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22505            return null;
22506        }
22507        return mInstallerService;
22508    }
22509
22510    @Override
22511    public IArtManager getArtManager() {
22512        return mArtManagerService;
22513    }
22514
22515    private boolean userNeedsBadging(int userId) {
22516        int index = mUserNeedsBadging.indexOfKey(userId);
22517        if (index < 0) {
22518            final UserInfo userInfo;
22519            final long token = Binder.clearCallingIdentity();
22520            try {
22521                userInfo = sUserManager.getUserInfo(userId);
22522            } finally {
22523                Binder.restoreCallingIdentity(token);
22524            }
22525            final boolean b;
22526            if (userInfo != null && userInfo.isManagedProfile()) {
22527                b = true;
22528            } else {
22529                b = false;
22530            }
22531            mUserNeedsBadging.put(userId, b);
22532            return b;
22533        }
22534        return mUserNeedsBadging.valueAt(index);
22535    }
22536
22537    @Override
22538    public KeySet getKeySetByAlias(String packageName, String alias) {
22539        if (packageName == null || alias == null) {
22540            return null;
22541        }
22542        synchronized(mPackages) {
22543            final PackageParser.Package pkg = mPackages.get(packageName);
22544            if (pkg == null) {
22545                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22546                throw new IllegalArgumentException("Unknown package: " + packageName);
22547            }
22548            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22549            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22550                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22551                throw new IllegalArgumentException("Unknown package: " + packageName);
22552            }
22553            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22554            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22555        }
22556    }
22557
22558    @Override
22559    public KeySet getSigningKeySet(String packageName) {
22560        if (packageName == null) {
22561            return null;
22562        }
22563        synchronized(mPackages) {
22564            final int callingUid = Binder.getCallingUid();
22565            final int callingUserId = UserHandle.getUserId(callingUid);
22566            final PackageParser.Package pkg = mPackages.get(packageName);
22567            if (pkg == null) {
22568                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22569                throw new IllegalArgumentException("Unknown package: " + packageName);
22570            }
22571            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22572            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
22573                // filter and pretend the package doesn't exist
22574                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22575                        + ", uid:" + callingUid);
22576                throw new IllegalArgumentException("Unknown package: " + packageName);
22577            }
22578            if (pkg.applicationInfo.uid != callingUid
22579                    && Process.SYSTEM_UID != callingUid) {
22580                throw new SecurityException("May not access signing KeySet of other apps.");
22581            }
22582            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22583            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22584        }
22585    }
22586
22587    @Override
22588    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22589        final int callingUid = Binder.getCallingUid();
22590        if (getInstantAppPackageName(callingUid) != null) {
22591            return false;
22592        }
22593        if (packageName == null || ks == null) {
22594            return false;
22595        }
22596        synchronized(mPackages) {
22597            final PackageParser.Package pkg = mPackages.get(packageName);
22598            if (pkg == null
22599                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22600                            UserHandle.getUserId(callingUid))) {
22601                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22602                throw new IllegalArgumentException("Unknown package: " + packageName);
22603            }
22604            IBinder ksh = ks.getToken();
22605            if (ksh instanceof KeySetHandle) {
22606                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22607                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22608            }
22609            return false;
22610        }
22611    }
22612
22613    @Override
22614    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22615        final int callingUid = Binder.getCallingUid();
22616        if (getInstantAppPackageName(callingUid) != null) {
22617            return false;
22618        }
22619        if (packageName == null || ks == null) {
22620            return false;
22621        }
22622        synchronized(mPackages) {
22623            final PackageParser.Package pkg = mPackages.get(packageName);
22624            if (pkg == null
22625                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22626                            UserHandle.getUserId(callingUid))) {
22627                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22628                throw new IllegalArgumentException("Unknown package: " + packageName);
22629            }
22630            IBinder ksh = ks.getToken();
22631            if (ksh instanceof KeySetHandle) {
22632                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22633                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22634            }
22635            return false;
22636        }
22637    }
22638
22639    private void deletePackageIfUnusedLPr(final String packageName) {
22640        PackageSetting ps = mSettings.mPackages.get(packageName);
22641        if (ps == null) {
22642            return;
22643        }
22644        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22645            // TODO Implement atomic delete if package is unused
22646            // It is currently possible that the package will be deleted even if it is installed
22647            // after this method returns.
22648            mHandler.post(new Runnable() {
22649                public void run() {
22650                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22651                            0, PackageManager.DELETE_ALL_USERS);
22652                }
22653            });
22654        }
22655    }
22656
22657    /**
22658     * Check and throw if the given before/after packages would be considered a
22659     * downgrade.
22660     */
22661    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22662            throws PackageManagerException {
22663        if (after.getLongVersionCode() < before.getLongVersionCode()) {
22664            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22665                    "Update version code " + after.versionCode + " is older than current "
22666                    + before.getLongVersionCode());
22667        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22668            if (after.baseRevisionCode < before.baseRevisionCode) {
22669                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22670                        "Update base revision code " + after.baseRevisionCode
22671                        + " is older than current " + before.baseRevisionCode);
22672            }
22673
22674            if (!ArrayUtils.isEmpty(after.splitNames)) {
22675                for (int i = 0; i < after.splitNames.length; i++) {
22676                    final String splitName = after.splitNames[i];
22677                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22678                    if (j != -1) {
22679                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22680                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22681                                    "Update split " + splitName + " revision code "
22682                                    + after.splitRevisionCodes[i] + " is older than current "
22683                                    + before.splitRevisionCodes[j]);
22684                        }
22685                    }
22686                }
22687            }
22688        }
22689    }
22690
22691    private static class MoveCallbacks extends Handler {
22692        private static final int MSG_CREATED = 1;
22693        private static final int MSG_STATUS_CHANGED = 2;
22694
22695        private final RemoteCallbackList<IPackageMoveObserver>
22696                mCallbacks = new RemoteCallbackList<>();
22697
22698        private final SparseIntArray mLastStatus = new SparseIntArray();
22699
22700        public MoveCallbacks(Looper looper) {
22701            super(looper);
22702        }
22703
22704        public void register(IPackageMoveObserver callback) {
22705            mCallbacks.register(callback);
22706        }
22707
22708        public void unregister(IPackageMoveObserver callback) {
22709            mCallbacks.unregister(callback);
22710        }
22711
22712        @Override
22713        public void handleMessage(Message msg) {
22714            final SomeArgs args = (SomeArgs) msg.obj;
22715            final int n = mCallbacks.beginBroadcast();
22716            for (int i = 0; i < n; i++) {
22717                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22718                try {
22719                    invokeCallback(callback, msg.what, args);
22720                } catch (RemoteException ignored) {
22721                }
22722            }
22723            mCallbacks.finishBroadcast();
22724            args.recycle();
22725        }
22726
22727        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22728                throws RemoteException {
22729            switch (what) {
22730                case MSG_CREATED: {
22731                    callback.onCreated(args.argi1, (Bundle) args.arg2);
22732                    break;
22733                }
22734                case MSG_STATUS_CHANGED: {
22735                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22736                    break;
22737                }
22738            }
22739        }
22740
22741        private void notifyCreated(int moveId, Bundle extras) {
22742            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22743
22744            final SomeArgs args = SomeArgs.obtain();
22745            args.argi1 = moveId;
22746            args.arg2 = extras;
22747            obtainMessage(MSG_CREATED, args).sendToTarget();
22748        }
22749
22750        private void notifyStatusChanged(int moveId, int status) {
22751            notifyStatusChanged(moveId, status, -1);
22752        }
22753
22754        private void notifyStatusChanged(int moveId, int status, long estMillis) {
22755            Slog.v(TAG, "Move " + moveId + " status " + status);
22756
22757            final SomeArgs args = SomeArgs.obtain();
22758            args.argi1 = moveId;
22759            args.argi2 = status;
22760            args.arg3 = estMillis;
22761            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22762
22763            synchronized (mLastStatus) {
22764                mLastStatus.put(moveId, status);
22765            }
22766        }
22767    }
22768
22769    private final static class OnPermissionChangeListeners extends Handler {
22770        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22771
22772        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22773                new RemoteCallbackList<>();
22774
22775        public OnPermissionChangeListeners(Looper looper) {
22776            super(looper);
22777        }
22778
22779        @Override
22780        public void handleMessage(Message msg) {
22781            switch (msg.what) {
22782                case MSG_ON_PERMISSIONS_CHANGED: {
22783                    final int uid = msg.arg1;
22784                    handleOnPermissionsChanged(uid);
22785                } break;
22786            }
22787        }
22788
22789        public void addListenerLocked(IOnPermissionsChangeListener listener) {
22790            mPermissionListeners.register(listener);
22791
22792        }
22793
22794        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22795            mPermissionListeners.unregister(listener);
22796        }
22797
22798        public void onPermissionsChanged(int uid) {
22799            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22800                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22801            }
22802        }
22803
22804        private void handleOnPermissionsChanged(int uid) {
22805            final int count = mPermissionListeners.beginBroadcast();
22806            try {
22807                for (int i = 0; i < count; i++) {
22808                    IOnPermissionsChangeListener callback = mPermissionListeners
22809                            .getBroadcastItem(i);
22810                    try {
22811                        callback.onPermissionsChanged(uid);
22812                    } catch (RemoteException e) {
22813                        Log.e(TAG, "Permission listener is dead", e);
22814                    }
22815                }
22816            } finally {
22817                mPermissionListeners.finishBroadcast();
22818            }
22819        }
22820    }
22821
22822    private class PackageManagerNative extends IPackageManagerNative.Stub {
22823        @Override
22824        public String[] getNamesForUids(int[] uids) throws RemoteException {
22825            final String[] results = PackageManagerService.this.getNamesForUids(uids);
22826            // massage results so they can be parsed by the native binder
22827            for (int i = results.length - 1; i >= 0; --i) {
22828                if (results[i] == null) {
22829                    results[i] = "";
22830                }
22831            }
22832            return results;
22833        }
22834
22835        // NB: this differentiates between preloads and sideloads
22836        @Override
22837        public String getInstallerForPackage(String packageName) throws RemoteException {
22838            final String installerName = getInstallerPackageName(packageName);
22839            if (!TextUtils.isEmpty(installerName)) {
22840                return installerName;
22841            }
22842            // differentiate between preload and sideload
22843            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22844            ApplicationInfo appInfo = getApplicationInfo(packageName,
22845                                    /*flags*/ 0,
22846                                    /*userId*/ callingUser);
22847            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22848                return "preload";
22849            }
22850            return "";
22851        }
22852
22853        @Override
22854        public long getVersionCodeForPackage(String packageName) throws RemoteException {
22855            try {
22856                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22857                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22858                if (pInfo != null) {
22859                    return pInfo.getLongVersionCode();
22860                }
22861            } catch (Exception e) {
22862            }
22863            return 0;
22864        }
22865    }
22866
22867    private class PackageManagerInternalImpl extends PackageManagerInternal {
22868        @Override
22869        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
22870                int flagValues, int userId) {
22871            PackageManagerService.this.updatePermissionFlags(
22872                    permName, packageName, flagMask, flagValues, userId);
22873        }
22874
22875        @Override
22876        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
22877            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
22878        }
22879
22880        @Override
22881        public boolean isInstantApp(String packageName, int userId) {
22882            return PackageManagerService.this.isInstantApp(packageName, userId);
22883        }
22884
22885        @Override
22886        public String getInstantAppPackageName(int uid) {
22887            return PackageManagerService.this.getInstantAppPackageName(uid);
22888        }
22889
22890        @Override
22891        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
22892            synchronized (mPackages) {
22893                return PackageManagerService.this.filterAppAccessLPr(
22894                        (PackageSetting) pkg.mExtras, callingUid, userId);
22895            }
22896        }
22897
22898        @Override
22899        public PackageParser.Package getPackage(String packageName) {
22900            synchronized (mPackages) {
22901                packageName = resolveInternalPackageNameLPr(
22902                        packageName, PackageManager.VERSION_CODE_HIGHEST);
22903                return mPackages.get(packageName);
22904            }
22905        }
22906
22907        @Override
22908        public PackageParser.Package getDisabledPackage(String packageName) {
22909            synchronized (mPackages) {
22910                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
22911                return (ps != null) ? ps.pkg : null;
22912            }
22913        }
22914
22915        @Override
22916        public String getKnownPackageName(int knownPackage, int userId) {
22917            switch(knownPackage) {
22918                case PackageManagerInternal.PACKAGE_BROWSER:
22919                    return getDefaultBrowserPackageName(userId);
22920                case PackageManagerInternal.PACKAGE_INSTALLER:
22921                    return mRequiredInstallerPackage;
22922                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
22923                    return mSetupWizardPackage;
22924                case PackageManagerInternal.PACKAGE_SYSTEM:
22925                    return "android";
22926                case PackageManagerInternal.PACKAGE_VERIFIER:
22927                    return mRequiredVerifierPackage;
22928            }
22929            return null;
22930        }
22931
22932        @Override
22933        public boolean isResolveActivityComponent(ComponentInfo component) {
22934            return mResolveActivity.packageName.equals(component.packageName)
22935                    && mResolveActivity.name.equals(component.name);
22936        }
22937
22938        @Override
22939        public void setLocationPackagesProvider(PackagesProvider provider) {
22940            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
22941        }
22942
22943        @Override
22944        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
22945            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
22946        }
22947
22948        @Override
22949        public void setSmsAppPackagesProvider(PackagesProvider provider) {
22950            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
22951        }
22952
22953        @Override
22954        public void setDialerAppPackagesProvider(PackagesProvider provider) {
22955            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
22956        }
22957
22958        @Override
22959        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
22960            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
22961        }
22962
22963        @Override
22964        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
22965            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
22966        }
22967
22968        @Override
22969        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
22970            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
22971        }
22972
22973        @Override
22974        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
22975            synchronized (mPackages) {
22976                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
22977            }
22978            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
22979        }
22980
22981        @Override
22982        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
22983            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
22984                    packageName, userId);
22985        }
22986
22987        @Override
22988        public void setKeepUninstalledPackages(final List<String> packageList) {
22989            Preconditions.checkNotNull(packageList);
22990            List<String> removedFromList = null;
22991            synchronized (mPackages) {
22992                if (mKeepUninstalledPackages != null) {
22993                    final int packagesCount = mKeepUninstalledPackages.size();
22994                    for (int i = 0; i < packagesCount; i++) {
22995                        String oldPackage = mKeepUninstalledPackages.get(i);
22996                        if (packageList != null && packageList.contains(oldPackage)) {
22997                            continue;
22998                        }
22999                        if (removedFromList == null) {
23000                            removedFromList = new ArrayList<>();
23001                        }
23002                        removedFromList.add(oldPackage);
23003                    }
23004                }
23005                mKeepUninstalledPackages = new ArrayList<>(packageList);
23006                if (removedFromList != null) {
23007                    final int removedCount = removedFromList.size();
23008                    for (int i = 0; i < removedCount; i++) {
23009                        deletePackageIfUnusedLPr(removedFromList.get(i));
23010                    }
23011                }
23012            }
23013        }
23014
23015        @Override
23016        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23017            synchronized (mPackages) {
23018                return mPermissionManager.isPermissionsReviewRequired(
23019                        mPackages.get(packageName), userId);
23020            }
23021        }
23022
23023        @Override
23024        public PackageInfo getPackageInfo(
23025                String packageName, int flags, int filterCallingUid, int userId) {
23026            return PackageManagerService.this
23027                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23028                            flags, filterCallingUid, userId);
23029        }
23030
23031        @Override
23032        public int getPackageUid(String packageName, int flags, int userId) {
23033            return PackageManagerService.this
23034                    .getPackageUid(packageName, flags, userId);
23035        }
23036
23037        @Override
23038        public ApplicationInfo getApplicationInfo(
23039                String packageName, int flags, int filterCallingUid, int userId) {
23040            return PackageManagerService.this
23041                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23042        }
23043
23044        @Override
23045        public ActivityInfo getActivityInfo(
23046                ComponentName component, int flags, int filterCallingUid, int userId) {
23047            return PackageManagerService.this
23048                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23049        }
23050
23051        @Override
23052        public List<ResolveInfo> queryIntentActivities(
23053                Intent intent, int flags, int filterCallingUid, int userId) {
23054            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23055            return PackageManagerService.this
23056                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23057                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23058        }
23059
23060        @Override
23061        public List<ResolveInfo> queryIntentServices(
23062                Intent intent, int flags, int callingUid, int userId) {
23063            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23064            return PackageManagerService.this
23065                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23066                            false);
23067        }
23068
23069        @Override
23070        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23071                int userId) {
23072            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23073        }
23074
23075        @Override
23076        public void setDeviceAndProfileOwnerPackages(
23077                int deviceOwnerUserId, String deviceOwnerPackage,
23078                SparseArray<String> profileOwnerPackages) {
23079            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23080                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23081        }
23082
23083        @Override
23084        public boolean isPackageDataProtected(int userId, String packageName) {
23085            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23086        }
23087
23088        @Override
23089        public boolean isPackageEphemeral(int userId, String packageName) {
23090            synchronized (mPackages) {
23091                final PackageSetting ps = mSettings.mPackages.get(packageName);
23092                return ps != null ? ps.getInstantApp(userId) : false;
23093            }
23094        }
23095
23096        @Override
23097        public boolean wasPackageEverLaunched(String packageName, int userId) {
23098            synchronized (mPackages) {
23099                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23100            }
23101        }
23102
23103        @Override
23104        public void grantRuntimePermission(String packageName, String permName, int userId,
23105                boolean overridePolicy) {
23106            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23107                    permName, packageName, overridePolicy, getCallingUid(), userId,
23108                    mPermissionCallback);
23109        }
23110
23111        @Override
23112        public void revokeRuntimePermission(String packageName, String permName, int userId,
23113                boolean overridePolicy) {
23114            mPermissionManager.revokeRuntimePermission(
23115                    permName, packageName, overridePolicy, getCallingUid(), userId,
23116                    mPermissionCallback);
23117        }
23118
23119        @Override
23120        public String getNameForUid(int uid) {
23121            return PackageManagerService.this.getNameForUid(uid);
23122        }
23123
23124        @Override
23125        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23126                Intent origIntent, String resolvedType, String callingPackage,
23127                Bundle verificationBundle, int userId) {
23128            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23129                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23130                    userId);
23131        }
23132
23133        @Override
23134        public void grantEphemeralAccess(int userId, Intent intent,
23135                int targetAppId, int ephemeralAppId) {
23136            synchronized (mPackages) {
23137                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23138                        targetAppId, ephemeralAppId);
23139            }
23140        }
23141
23142        @Override
23143        public boolean isInstantAppInstallerComponent(ComponentName component) {
23144            synchronized (mPackages) {
23145                return mInstantAppInstallerActivity != null
23146                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23147            }
23148        }
23149
23150        @Override
23151        public void pruneInstantApps() {
23152            mInstantAppRegistry.pruneInstantApps();
23153        }
23154
23155        @Override
23156        public String getSetupWizardPackageName() {
23157            return mSetupWizardPackage;
23158        }
23159
23160        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23161            if (policy != null) {
23162                mExternalSourcesPolicy = policy;
23163            }
23164        }
23165
23166        @Override
23167        public boolean isPackagePersistent(String packageName) {
23168            synchronized (mPackages) {
23169                PackageParser.Package pkg = mPackages.get(packageName);
23170                return pkg != null
23171                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23172                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23173                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23174                        : false;
23175            }
23176        }
23177
23178        @Override
23179        public boolean isLegacySystemApp(Package pkg) {
23180            synchronized (mPackages) {
23181                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23182                return mPromoteSystemApps
23183                        && ps.isSystem()
23184                        && mExistingSystemPackages.contains(ps.name);
23185            }
23186        }
23187
23188        @Override
23189        public List<PackageInfo> getOverlayPackages(int userId) {
23190            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23191            synchronized (mPackages) {
23192                for (PackageParser.Package p : mPackages.values()) {
23193                    if (p.mOverlayTarget != null) {
23194                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23195                        if (pkg != null) {
23196                            overlayPackages.add(pkg);
23197                        }
23198                    }
23199                }
23200            }
23201            return overlayPackages;
23202        }
23203
23204        @Override
23205        public List<String> getTargetPackageNames(int userId) {
23206            List<String> targetPackages = new ArrayList<>();
23207            synchronized (mPackages) {
23208                for (PackageParser.Package p : mPackages.values()) {
23209                    if (p.mOverlayTarget == null) {
23210                        targetPackages.add(p.packageName);
23211                    }
23212                }
23213            }
23214            return targetPackages;
23215        }
23216
23217        @Override
23218        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23219                @Nullable List<String> overlayPackageNames) {
23220            synchronized (mPackages) {
23221                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23222                    Slog.e(TAG, "failed to find package " + targetPackageName);
23223                    return false;
23224                }
23225                ArrayList<String> overlayPaths = null;
23226                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23227                    final int N = overlayPackageNames.size();
23228                    overlayPaths = new ArrayList<>(N);
23229                    for (int i = 0; i < N; i++) {
23230                        final String packageName = overlayPackageNames.get(i);
23231                        final PackageParser.Package pkg = mPackages.get(packageName);
23232                        if (pkg == null) {
23233                            Slog.e(TAG, "failed to find package " + packageName);
23234                            return false;
23235                        }
23236                        overlayPaths.add(pkg.baseCodePath);
23237                    }
23238                }
23239
23240                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23241                ps.setOverlayPaths(overlayPaths, userId);
23242                return true;
23243            }
23244        }
23245
23246        @Override
23247        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23248                int flags, int userId, boolean resolveForStart) {
23249            return resolveIntentInternal(
23250                    intent, resolvedType, flags, userId, resolveForStart);
23251        }
23252
23253        @Override
23254        public ResolveInfo resolveService(Intent intent, String resolvedType,
23255                int flags, int userId, int callingUid) {
23256            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23257        }
23258
23259        @Override
23260        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23261            return PackageManagerService.this.resolveContentProviderInternal(
23262                    name, flags, userId);
23263        }
23264
23265        @Override
23266        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23267            synchronized (mPackages) {
23268                mIsolatedOwners.put(isolatedUid, ownerUid);
23269            }
23270        }
23271
23272        @Override
23273        public void removeIsolatedUid(int isolatedUid) {
23274            synchronized (mPackages) {
23275                mIsolatedOwners.delete(isolatedUid);
23276            }
23277        }
23278
23279        @Override
23280        public int getUidTargetSdkVersion(int uid) {
23281            synchronized (mPackages) {
23282                return getUidTargetSdkVersionLockedLPr(uid);
23283            }
23284        }
23285
23286        @Override
23287        public boolean canAccessInstantApps(int callingUid, int userId) {
23288            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23289        }
23290
23291        @Override
23292        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23293            synchronized (mPackages) {
23294                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23295            }
23296        }
23297
23298        @Override
23299        public void notifyPackageUse(String packageName, int reason) {
23300            synchronized (mPackages) {
23301                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23302            }
23303        }
23304    }
23305
23306    @Override
23307    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23308        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23309        synchronized (mPackages) {
23310            final long identity = Binder.clearCallingIdentity();
23311            try {
23312                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23313                        packageNames, userId);
23314            } finally {
23315                Binder.restoreCallingIdentity(identity);
23316            }
23317        }
23318    }
23319
23320    @Override
23321    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23322        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23323        synchronized (mPackages) {
23324            final long identity = Binder.clearCallingIdentity();
23325            try {
23326                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23327                        packageNames, userId);
23328            } finally {
23329                Binder.restoreCallingIdentity(identity);
23330            }
23331        }
23332    }
23333
23334    private static void enforceSystemOrPhoneCaller(String tag) {
23335        int callingUid = Binder.getCallingUid();
23336        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23337            throw new SecurityException(
23338                    "Cannot call " + tag + " from UID " + callingUid);
23339        }
23340    }
23341
23342    boolean isHistoricalPackageUsageAvailable() {
23343        return mPackageUsage.isHistoricalPackageUsageAvailable();
23344    }
23345
23346    /**
23347     * Return a <b>copy</b> of the collection of packages known to the package manager.
23348     * @return A copy of the values of mPackages.
23349     */
23350    Collection<PackageParser.Package> getPackages() {
23351        synchronized (mPackages) {
23352            return new ArrayList<>(mPackages.values());
23353        }
23354    }
23355
23356    /**
23357     * Logs process start information (including base APK hash) to the security log.
23358     * @hide
23359     */
23360    @Override
23361    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23362            String apkFile, int pid) {
23363        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23364            return;
23365        }
23366        if (!SecurityLog.isLoggingEnabled()) {
23367            return;
23368        }
23369        Bundle data = new Bundle();
23370        data.putLong("startTimestamp", System.currentTimeMillis());
23371        data.putString("processName", processName);
23372        data.putInt("uid", uid);
23373        data.putString("seinfo", seinfo);
23374        data.putString("apkFile", apkFile);
23375        data.putInt("pid", pid);
23376        Message msg = mProcessLoggingHandler.obtainMessage(
23377                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23378        msg.setData(data);
23379        mProcessLoggingHandler.sendMessage(msg);
23380    }
23381
23382    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23383        return mCompilerStats.getPackageStats(pkgName);
23384    }
23385
23386    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23387        return getOrCreateCompilerPackageStats(pkg.packageName);
23388    }
23389
23390    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23391        return mCompilerStats.getOrCreatePackageStats(pkgName);
23392    }
23393
23394    public void deleteCompilerPackageStats(String pkgName) {
23395        mCompilerStats.deletePackageStats(pkgName);
23396    }
23397
23398    @Override
23399    public int getInstallReason(String packageName, int userId) {
23400        final int callingUid = Binder.getCallingUid();
23401        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23402                true /* requireFullPermission */, false /* checkShell */,
23403                "get install reason");
23404        synchronized (mPackages) {
23405            final PackageSetting ps = mSettings.mPackages.get(packageName);
23406            if (filterAppAccessLPr(ps, callingUid, userId)) {
23407                return PackageManager.INSTALL_REASON_UNKNOWN;
23408            }
23409            if (ps != null) {
23410                return ps.getInstallReason(userId);
23411            }
23412        }
23413        return PackageManager.INSTALL_REASON_UNKNOWN;
23414    }
23415
23416    @Override
23417    public boolean canRequestPackageInstalls(String packageName, int userId) {
23418        return canRequestPackageInstallsInternal(packageName, 0, userId,
23419                true /* throwIfPermNotDeclared*/);
23420    }
23421
23422    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23423            boolean throwIfPermNotDeclared) {
23424        int callingUid = Binder.getCallingUid();
23425        int uid = getPackageUid(packageName, 0, userId);
23426        if (callingUid != uid && callingUid != Process.ROOT_UID
23427                && callingUid != Process.SYSTEM_UID) {
23428            throw new SecurityException(
23429                    "Caller uid " + callingUid + " does not own package " + packageName);
23430        }
23431        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23432        if (info == null) {
23433            return false;
23434        }
23435        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23436            return false;
23437        }
23438        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23439        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23440        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23441            if (throwIfPermNotDeclared) {
23442                throw new SecurityException("Need to declare " + appOpPermission
23443                        + " to call this api");
23444            } else {
23445                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23446                return false;
23447            }
23448        }
23449        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23450            return false;
23451        }
23452        if (mExternalSourcesPolicy != null) {
23453            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23454            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23455                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23456            }
23457        }
23458        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23459    }
23460
23461    @Override
23462    public ComponentName getInstantAppResolverSettingsComponent() {
23463        return mInstantAppResolverSettingsComponent;
23464    }
23465
23466    @Override
23467    public ComponentName getInstantAppInstallerComponent() {
23468        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23469            return null;
23470        }
23471        return mInstantAppInstallerActivity == null
23472                ? null : mInstantAppInstallerActivity.getComponentName();
23473    }
23474
23475    @Override
23476    public String getInstantAppAndroidId(String packageName, int userId) {
23477        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
23478                "getInstantAppAndroidId");
23479        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
23480                true /* requireFullPermission */, false /* checkShell */,
23481                "getInstantAppAndroidId");
23482        // Make sure the target is an Instant App.
23483        if (!isInstantApp(packageName, userId)) {
23484            return null;
23485        }
23486        synchronized (mPackages) {
23487            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
23488        }
23489    }
23490
23491    boolean canHaveOatDir(String packageName) {
23492        synchronized (mPackages) {
23493            PackageParser.Package p = mPackages.get(packageName);
23494            if (p == null) {
23495                return false;
23496            }
23497            return p.canHaveOatDir();
23498        }
23499    }
23500
23501    private String getOatDir(PackageParser.Package pkg) {
23502        if (!pkg.canHaveOatDir()) {
23503            return null;
23504        }
23505        File codePath = new File(pkg.codePath);
23506        if (codePath.isDirectory()) {
23507            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
23508        }
23509        return null;
23510    }
23511
23512    void deleteOatArtifactsOfPackage(String packageName) {
23513        final String[] instructionSets;
23514        final List<String> codePaths;
23515        final String oatDir;
23516        final PackageParser.Package pkg;
23517        synchronized (mPackages) {
23518            pkg = mPackages.get(packageName);
23519        }
23520        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
23521        codePaths = pkg.getAllCodePaths();
23522        oatDir = getOatDir(pkg);
23523
23524        for (String codePath : codePaths) {
23525            for (String isa : instructionSets) {
23526                try {
23527                    mInstaller.deleteOdex(codePath, isa, oatDir);
23528                } catch (InstallerException e) {
23529                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
23530                }
23531            }
23532        }
23533    }
23534
23535    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
23536        Set<String> unusedPackages = new HashSet<>();
23537        long currentTimeInMillis = System.currentTimeMillis();
23538        synchronized (mPackages) {
23539            for (PackageParser.Package pkg : mPackages.values()) {
23540                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
23541                if (ps == null) {
23542                    continue;
23543                }
23544                PackageDexUsage.PackageUseInfo packageUseInfo =
23545                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
23546                if (PackageManagerServiceUtils
23547                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
23548                                downgradeTimeThresholdMillis, packageUseInfo,
23549                                pkg.getLatestPackageUseTimeInMills(),
23550                                pkg.getLatestForegroundPackageUseTimeInMills())) {
23551                    unusedPackages.add(pkg.packageName);
23552                }
23553            }
23554        }
23555        return unusedPackages;
23556    }
23557}
23558
23559interface PackageSender {
23560    /**
23561     * @param userIds User IDs where the action occurred on a full application
23562     * @param instantUserIds User IDs where the action occurred on an instant application
23563     */
23564    void sendPackageBroadcast(final String action, final String pkg,
23565        final Bundle extras, final int flags, final String targetPkg,
23566        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
23567    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
23568        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
23569}
23570