PackageManagerService.java revision ea18c501d4a4ec05e44fac264ea28bce9dc4763a
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.SET_HARMFUL_APP_WARNINGS;
21import static android.Manifest.permission.INSTALL_PACKAGES;
22import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
23import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
24import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
25import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
26import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
27import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
28import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
31import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
32import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
33import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
34import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
40import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
41import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
42import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
43import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
44import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
45import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
50import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
51import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
52import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
53import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
54import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
57import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
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.ActivityManagerInternal;
122import android.app.AppOpsManager;
123import android.app.IActivityManager;
124import android.app.ResourcesManager;
125import android.app.admin.IDevicePolicyManager;
126import android.app.admin.SecurityLog;
127import android.app.backup.IBackupManager;
128import android.content.BroadcastReceiver;
129import android.content.ComponentName;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.IIntentReceiver;
133import android.content.Intent;
134import android.content.IntentFilter;
135import android.content.IntentSender;
136import android.content.IntentSender.SendIntentException;
137import android.content.ServiceConnection;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.AppsQueryHelper;
141import android.content.pm.AuxiliaryResolveInfo;
142import android.content.pm.ChangedPackages;
143import android.content.pm.ComponentInfo;
144import android.content.pm.FallbackCategoryProvider;
145import android.content.pm.FeatureInfo;
146import android.content.pm.IDexModuleRegisterCallback;
147import android.content.pm.IOnPermissionsChangeListener;
148import android.content.pm.IPackageDataObserver;
149import android.content.pm.IPackageDeleteObserver;
150import android.content.pm.IPackageDeleteObserver2;
151import android.content.pm.IPackageInstallObserver2;
152import android.content.pm.IPackageInstaller;
153import android.content.pm.IPackageManager;
154import android.content.pm.IPackageManagerNative;
155import android.content.pm.IPackageMoveObserver;
156import android.content.pm.IPackageStatsObserver;
157import android.content.pm.InstantAppInfo;
158import android.content.pm.InstantAppRequest;
159import android.content.pm.InstantAppResolveInfo;
160import android.content.pm.InstrumentationInfo;
161import android.content.pm.IntentFilterVerificationInfo;
162import android.content.pm.KeySet;
163import android.content.pm.PackageCleanItem;
164import android.content.pm.PackageInfo;
165import android.content.pm.PackageInfoLite;
166import android.content.pm.PackageInstaller;
167import android.content.pm.PackageList;
168import android.content.pm.PackageManager;
169import android.content.pm.PackageManagerInternal;
170import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
171import android.content.pm.PackageManagerInternal.PackageListObserver;
172import android.content.pm.PackageParser;
173import android.content.pm.PackageParser.ActivityIntentInfo;
174import android.content.pm.PackageParser.Package;
175import android.content.pm.PackageParser.PackageLite;
176import android.content.pm.PackageParser.PackageParserException;
177import android.content.pm.PackageParser.ParseFlags;
178import android.content.pm.PackageParser.ServiceIntentInfo;
179import android.content.pm.PackageParser.SigningDetails;
180import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
181import android.content.pm.PackageStats;
182import android.content.pm.PackageUserState;
183import android.content.pm.ParceledListSlice;
184import android.content.pm.PermissionGroupInfo;
185import android.content.pm.PermissionInfo;
186import android.content.pm.ProviderInfo;
187import android.content.pm.ResolveInfo;
188import android.content.pm.ServiceInfo;
189import android.content.pm.SharedLibraryInfo;
190import android.content.pm.Signature;
191import android.content.pm.UserInfo;
192import android.content.pm.VerifierDeviceIdentity;
193import android.content.pm.VerifierInfo;
194import android.content.pm.VersionedPackage;
195import android.content.pm.dex.ArtManager;
196import android.content.pm.dex.DexMetadataHelper;
197import android.content.pm.dex.IArtManager;
198import android.content.res.Resources;
199import android.database.ContentObserver;
200import android.graphics.Bitmap;
201import android.hardware.display.DisplayManager;
202import android.net.Uri;
203import android.os.Binder;
204import android.os.Build;
205import android.os.Bundle;
206import android.os.Debug;
207import android.os.Environment;
208import android.os.Environment.UserEnvironment;
209import android.os.FileUtils;
210import android.os.Handler;
211import android.os.IBinder;
212import android.os.Looper;
213import android.os.Message;
214import android.os.Parcel;
215import android.os.ParcelFileDescriptor;
216import android.os.PatternMatcher;
217import android.os.Process;
218import android.os.RemoteCallbackList;
219import android.os.RemoteException;
220import android.os.ResultReceiver;
221import android.os.SELinux;
222import android.os.ServiceManager;
223import android.os.ShellCallback;
224import android.os.SystemClock;
225import android.os.SystemProperties;
226import android.os.Trace;
227import android.os.UserHandle;
228import android.os.UserManager;
229import android.os.UserManagerInternal;
230import android.os.storage.IStorageManager;
231import android.os.storage.StorageEventListener;
232import android.os.storage.StorageManager;
233import android.os.storage.StorageManagerInternal;
234import android.os.storage.VolumeInfo;
235import android.os.storage.VolumeRecord;
236import android.provider.Settings.Global;
237import android.provider.Settings.Secure;
238import android.security.KeyStore;
239import android.security.SystemKeyStore;
240import android.service.pm.PackageServiceDumpProto;
241import android.service.textclassifier.TextClassifierService;
242import android.system.ErrnoException;
243import android.system.Os;
244import android.text.TextUtils;
245import android.text.format.DateUtils;
246import android.util.ArrayMap;
247import android.util.ArraySet;
248import android.util.Base64;
249import android.util.ByteStringUtils;
250import android.util.DisplayMetrics;
251import android.util.EventLog;
252import android.util.ExceptionUtils;
253import android.util.Log;
254import android.util.LogPrinter;
255import android.util.LongSparseArray;
256import android.util.LongSparseLongArray;
257import android.util.MathUtils;
258import android.util.PackageUtils;
259import android.util.Pair;
260import android.util.PrintStreamPrinter;
261import android.util.Slog;
262import android.util.SparseArray;
263import android.util.SparseBooleanArray;
264import android.util.SparseIntArray;
265import android.util.TimingsTraceLog;
266import android.util.Xml;
267import android.util.jar.StrictJarFile;
268import android.util.proto.ProtoOutputStream;
269import android.view.Display;
270
271import com.android.internal.R;
272import com.android.internal.annotations.GuardedBy;
273import com.android.internal.app.IMediaContainerService;
274import com.android.internal.app.ResolverActivity;
275import com.android.internal.content.NativeLibraryHelper;
276import com.android.internal.content.PackageHelper;
277import com.android.internal.logging.MetricsLogger;
278import com.android.internal.os.IParcelFileDescriptorFactory;
279import com.android.internal.os.SomeArgs;
280import com.android.internal.os.Zygote;
281import com.android.internal.telephony.CarrierAppUtils;
282import com.android.internal.util.ArrayUtils;
283import com.android.internal.util.ConcurrentUtils;
284import com.android.internal.util.DumpUtils;
285import com.android.internal.util.FastXmlSerializer;
286import com.android.internal.util.IndentingPrintWriter;
287import com.android.internal.util.Preconditions;
288import com.android.internal.util.XmlUtils;
289import com.android.server.AttributeCache;
290import com.android.server.DeviceIdleController;
291import com.android.server.EventLogTags;
292import com.android.server.FgThread;
293import com.android.server.IntentResolver;
294import com.android.server.LocalServices;
295import com.android.server.LockGuard;
296import com.android.server.ServiceThread;
297import com.android.server.SystemConfig;
298import com.android.server.SystemServerInitThreadPool;
299import com.android.server.Watchdog;
300import com.android.server.net.NetworkPolicyManagerInternal;
301import com.android.server.pm.Installer.InstallerException;
302import com.android.server.pm.Settings.DatabaseVersion;
303import com.android.server.pm.Settings.VersionInfo;
304import com.android.server.pm.dex.ArtManagerService;
305import com.android.server.pm.dex.DexLogger;
306import com.android.server.pm.dex.DexManager;
307import com.android.server.pm.dex.DexoptOptions;
308import com.android.server.pm.dex.PackageDexUsage;
309import com.android.server.pm.permission.BasePermission;
310import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
311import com.android.server.pm.permission.PermissionManagerService;
312import com.android.server.pm.permission.PermissionManagerInternal;
313import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
314import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
315import com.android.server.pm.permission.PermissionsState;
316import com.android.server.pm.permission.PermissionsState.PermissionState;
317import com.android.server.security.VerityUtils;
318import com.android.server.storage.DeviceStorageMonitorInternal;
319
320import dalvik.system.CloseGuard;
321import dalvik.system.VMRuntime;
322
323import libcore.io.IoUtils;
324
325import org.xmlpull.v1.XmlPullParser;
326import org.xmlpull.v1.XmlPullParserException;
327import org.xmlpull.v1.XmlSerializer;
328
329import java.io.BufferedOutputStream;
330import java.io.ByteArrayInputStream;
331import java.io.ByteArrayOutputStream;
332import java.io.File;
333import java.io.FileDescriptor;
334import java.io.FileInputStream;
335import java.io.FileOutputStream;
336import java.io.FilenameFilter;
337import java.io.IOException;
338import java.io.PrintWriter;
339import java.lang.annotation.Retention;
340import java.lang.annotation.RetentionPolicy;
341import java.nio.charset.StandardCharsets;
342import java.security.DigestException;
343import java.security.DigestInputStream;
344import java.security.MessageDigest;
345import java.security.NoSuchAlgorithmException;
346import java.security.PublicKey;
347import java.security.SecureRandom;
348import java.security.cert.CertificateException;
349import java.util.ArrayList;
350import java.util.Arrays;
351import java.util.Collection;
352import java.util.Collections;
353import java.util.Comparator;
354import java.util.HashMap;
355import java.util.HashSet;
356import java.util.Iterator;
357import java.util.LinkedHashSet;
358import java.util.List;
359import java.util.Map;
360import java.util.Objects;
361import java.util.Set;
362import java.util.concurrent.CountDownLatch;
363import java.util.concurrent.Future;
364import java.util.concurrent.TimeUnit;
365import java.util.concurrent.atomic.AtomicBoolean;
366import java.util.concurrent.atomic.AtomicInteger;
367
368/**
369 * Keep track of all those APKs everywhere.
370 * <p>
371 * Internally there are two important locks:
372 * <ul>
373 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
374 * and other related state. It is a fine-grained lock that should only be held
375 * momentarily, as it's one of the most contended locks in the system.
376 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
377 * operations typically involve heavy lifting of application data on disk. Since
378 * {@code installd} is single-threaded, and it's operations can often be slow,
379 * this lock should never be acquired while already holding {@link #mPackages}.
380 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
381 * holding {@link #mInstallLock}.
382 * </ul>
383 * Many internal methods rely on the caller to hold the appropriate locks, and
384 * this contract is expressed through method name suffixes:
385 * <ul>
386 * <li>fooLI(): the caller must hold {@link #mInstallLock}
387 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
388 * being modified must be frozen
389 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
390 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
391 * </ul>
392 * <p>
393 * Because this class is very central to the platform's security; please run all
394 * CTS and unit tests whenever making modifications:
395 *
396 * <pre>
397 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
398 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
399 * </pre>
400 */
401public class PackageManagerService extends IPackageManager.Stub
402        implements PackageSender {
403    static final String TAG = "PackageManager";
404    public static final boolean DEBUG_SETTINGS = false;
405    static final boolean DEBUG_PREFERRED = false;
406    static final boolean DEBUG_UPGRADE = false;
407    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
408    private static final boolean DEBUG_BACKUP = false;
409    public static final boolean DEBUG_INSTALL = false;
410    public static final boolean DEBUG_REMOVE = false;
411    private static final boolean DEBUG_BROADCASTS = false;
412    private static final boolean DEBUG_SHOW_INFO = false;
413    private static final boolean DEBUG_PACKAGE_INFO = false;
414    private static final boolean DEBUG_INTENT_MATCHING = false;
415    public static final boolean DEBUG_PACKAGE_SCANNING = false;
416    private static final boolean DEBUG_VERIFY = false;
417    private static final boolean DEBUG_FILTERS = false;
418    public static final boolean DEBUG_PERMISSIONS = false;
419    private static final boolean DEBUG_SHARED_LIBRARIES = false;
420    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
421
422    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
423    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
424    // user, but by default initialize to this.
425    public static final boolean DEBUG_DEXOPT = false;
426
427    private static final boolean DEBUG_ABI_SELECTION = false;
428    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
429    private static final boolean DEBUG_TRIAGED_MISSING = false;
430    private static final boolean DEBUG_APP_DATA = false;
431
432    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
433    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
434
435    private static final boolean HIDE_EPHEMERAL_APIS = false;
436
437    private static final boolean ENABLE_FREE_CACHE_V2 =
438            SystemProperties.getBoolean("fw.free_cache_v2", true);
439
440    private static final int RADIO_UID = Process.PHONE_UID;
441    private static final int LOG_UID = Process.LOG_UID;
442    private static final int NFC_UID = Process.NFC_UID;
443    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
444    private static final int SHELL_UID = Process.SHELL_UID;
445    private static final int SE_UID = Process.SE_UID;
446
447    // Suffix used during package installation when copying/moving
448    // package apks to install directory.
449    private static final String INSTALL_PACKAGE_SUFFIX = "-";
450
451    static final int SCAN_NO_DEX = 1<<0;
452    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
453    static final int SCAN_NEW_INSTALL = 1<<2;
454    static final int SCAN_UPDATE_TIME = 1<<3;
455    static final int SCAN_BOOTING = 1<<4;
456    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
457    static final int SCAN_REQUIRE_KNOWN = 1<<7;
458    static final int SCAN_MOVE = 1<<8;
459    static final int SCAN_INITIAL = 1<<9;
460    static final int SCAN_CHECK_ONLY = 1<<10;
461    static final int SCAN_DONT_KILL_APP = 1<<11;
462    static final int SCAN_IGNORE_FROZEN = 1<<12;
463    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
464    static final int SCAN_AS_INSTANT_APP = 1<<14;
465    static final int SCAN_AS_FULL_APP = 1<<15;
466    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
467    static final int SCAN_AS_SYSTEM = 1<<17;
468    static final int SCAN_AS_PRIVILEGED = 1<<18;
469    static final int SCAN_AS_OEM = 1<<19;
470    static final int SCAN_AS_VENDOR = 1<<20;
471    static final int SCAN_AS_PRODUCT = 1<<21;
472
473    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
474            SCAN_NO_DEX,
475            SCAN_UPDATE_SIGNATURE,
476            SCAN_NEW_INSTALL,
477            SCAN_UPDATE_TIME,
478            SCAN_BOOTING,
479            SCAN_DELETE_DATA_ON_FAILURES,
480            SCAN_REQUIRE_KNOWN,
481            SCAN_MOVE,
482            SCAN_INITIAL,
483            SCAN_CHECK_ONLY,
484            SCAN_DONT_KILL_APP,
485            SCAN_IGNORE_FROZEN,
486            SCAN_FIRST_BOOT_OR_UPGRADE,
487            SCAN_AS_INSTANT_APP,
488            SCAN_AS_FULL_APP,
489            SCAN_AS_VIRTUAL_PRELOAD,
490    })
491    @Retention(RetentionPolicy.SOURCE)
492    public @interface ScanFlags {}
493
494    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
495    /** Extension of the compressed packages */
496    public final static String COMPRESSED_EXTENSION = ".gz";
497    /** Suffix of stub packages on the system partition */
498    public final static String STUB_SUFFIX = "-Stub";
499
500    private static final int[] EMPTY_INT_ARRAY = new int[0];
501
502    private static final int TYPE_UNKNOWN = 0;
503    private static final int TYPE_ACTIVITY = 1;
504    private static final int TYPE_RECEIVER = 2;
505    private static final int TYPE_SERVICE = 3;
506    private static final int TYPE_PROVIDER = 4;
507    @IntDef(prefix = { "TYPE_" }, value = {
508            TYPE_UNKNOWN,
509            TYPE_ACTIVITY,
510            TYPE_RECEIVER,
511            TYPE_SERVICE,
512            TYPE_PROVIDER,
513    })
514    @Retention(RetentionPolicy.SOURCE)
515    public @interface ComponentType {}
516
517    /**
518     * Timeout (in milliseconds) after which the watchdog should declare that
519     * our handler thread is wedged.  The usual default for such things is one
520     * minute but we sometimes do very lengthy I/O operations on this thread,
521     * such as installing multi-gigabyte applications, so ours needs to be longer.
522     */
523    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
524
525    /**
526     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
527     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
528     * settings entry if available, otherwise we use the hardcoded default.  If it's been
529     * more than this long since the last fstrim, we force one during the boot sequence.
530     *
531     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
532     * one gets run at the next available charging+idle time.  This final mandatory
533     * no-fstrim check kicks in only of the other scheduling criteria is never met.
534     */
535    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
536
537    /**
538     * Whether verification is enabled by default.
539     */
540    private static final boolean DEFAULT_VERIFY_ENABLE = true;
541
542    /**
543     * The default maximum time to wait for the verification agent to return in
544     * milliseconds.
545     */
546    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
547
548    /**
549     * The default response for package verification timeout.
550     *
551     * This can be either PackageManager.VERIFICATION_ALLOW or
552     * PackageManager.VERIFICATION_REJECT.
553     */
554    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
555
556    public static final String PLATFORM_PACKAGE_NAME = "android";
557
558    public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
559
560    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
561            DEFAULT_CONTAINER_PACKAGE,
562            "com.android.defcontainer.DefaultContainerService");
563
564    private static final String KILL_APP_REASON_GIDS_CHANGED =
565            "permission grant or revoke changed gids";
566
567    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
568            "permissions revoked";
569
570    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
571
572    private static final String PACKAGE_SCHEME = "package";
573
574    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
575
576    private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
577
578    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
579
580    /** Canonical intent used to identify what counts as a "web browser" app */
581    private static final Intent sBrowserIntent;
582    static {
583        sBrowserIntent = new Intent();
584        sBrowserIntent.setAction(Intent.ACTION_VIEW);
585        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
586        sBrowserIntent.setData(Uri.parse("http:"));
587        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
588    }
589
590    /**
591     * The set of all protected actions [i.e. those actions for which a high priority
592     * intent filter is disallowed].
593     */
594    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
595    static {
596        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
597        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
598        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
599        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
600    }
601
602    // Compilation reasons.
603    public static final int REASON_UNKNOWN = -1;
604    public static final int REASON_FIRST_BOOT = 0;
605    public static final int REASON_BOOT = 1;
606    public static final int REASON_INSTALL = 2;
607    public static final int REASON_BACKGROUND_DEXOPT = 3;
608    public static final int REASON_AB_OTA = 4;
609    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
610    public static final int REASON_SHARED = 6;
611
612    public static final int REASON_LAST = REASON_SHARED;
613
614    /**
615     * Version number for the package parser cache. Increment this whenever the format or
616     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
617     */
618    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
619
620    /**
621     * Whether the package parser cache is enabled.
622     */
623    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
624
625    /**
626     * Permissions required in order to receive instant application lifecycle broadcasts.
627     */
628    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
629            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
630
631    final ServiceThread mHandlerThread;
632
633    final PackageHandler mHandler;
634
635    private final ProcessLoggingHandler mProcessLoggingHandler;
636
637    /**
638     * Messages for {@link #mHandler} that need to wait for system ready before
639     * being dispatched.
640     */
641    private ArrayList<Message> mPostSystemReadyMessages;
642
643    final int mSdkVersion = Build.VERSION.SDK_INT;
644
645    final Context mContext;
646    final boolean mFactoryTest;
647    final boolean mOnlyCore;
648    final DisplayMetrics mMetrics;
649    final int mDefParseFlags;
650    final String[] mSeparateProcesses;
651    final boolean mIsUpgrade;
652    final boolean mIsPreNUpgrade;
653    final boolean mIsPreNMR1Upgrade;
654
655    // Have we told the Activity Manager to whitelist the default container service by uid yet?
656    @GuardedBy("mPackages")
657    boolean mDefaultContainerWhitelisted = false;
658
659    @GuardedBy("mPackages")
660    private boolean mDexOptDialogShown;
661
662    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
663    // LOCK HELD.  Can be called with mInstallLock held.
664    @GuardedBy("mInstallLock")
665    final Installer mInstaller;
666
667    /** Directory where installed applications are stored */
668    private static final File sAppInstallDir =
669            new File(Environment.getDataDirectory(), "app");
670    /** Directory where installed application's 32-bit native libraries are copied. */
671    private static final File sAppLib32InstallDir =
672            new File(Environment.getDataDirectory(), "app-lib");
673    /** Directory where code and non-resource assets of forward-locked applications are stored */
674    private static final File sDrmAppPrivateInstallDir =
675            new File(Environment.getDataDirectory(), "app-private");
676
677    // ----------------------------------------------------------------
678
679    // Lock for state used when installing and doing other long running
680    // operations.  Methods that must be called with this lock held have
681    // the suffix "LI".
682    final Object mInstallLock = new Object();
683
684    // ----------------------------------------------------------------
685
686    // Keys are String (package name), values are Package.  This also serves
687    // as the lock for the global state.  Methods that must be called with
688    // this lock held have the prefix "LP".
689    @GuardedBy("mPackages")
690    final ArrayMap<String, PackageParser.Package> mPackages =
691            new ArrayMap<String, PackageParser.Package>();
692
693    final ArrayMap<String, Set<String>> mKnownCodebase =
694            new ArrayMap<String, Set<String>>();
695
696    // Keys are isolated uids and values are the uid of the application
697    // that created the isolated proccess.
698    @GuardedBy("mPackages")
699    final SparseIntArray mIsolatedOwners = new SparseIntArray();
700
701    /**
702     * Tracks new system packages [received in an OTA] that we expect to
703     * find updated user-installed versions. Keys are package name, values
704     * are package location.
705     */
706    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
707    /**
708     * Tracks high priority intent filters for protected actions. During boot, certain
709     * filter actions are protected and should never be allowed to have a high priority
710     * intent filter for them. However, there is one, and only one exception -- the
711     * setup wizard. It must be able to define a high priority intent filter for these
712     * actions to ensure there are no escapes from the wizard. We need to delay processing
713     * of these during boot as we need to look at all of the system packages in order
714     * to know which component is the setup wizard.
715     */
716    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
717    /**
718     * Whether or not processing protected filters should be deferred.
719     */
720    private boolean mDeferProtectedFilters = true;
721
722    /**
723     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
724     */
725    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
726    /**
727     * Whether or not system app permissions should be promoted from install to runtime.
728     */
729    boolean mPromoteSystemApps;
730
731    @GuardedBy("mPackages")
732    final Settings mSettings;
733
734    /**
735     * Set of package names that are currently "frozen", which means active
736     * surgery is being done on the code/data for that package. The platform
737     * will refuse to launch frozen packages to avoid race conditions.
738     *
739     * @see PackageFreezer
740     */
741    @GuardedBy("mPackages")
742    final ArraySet<String> mFrozenPackages = new ArraySet<>();
743
744    final ProtectedPackages mProtectedPackages;
745
746    @GuardedBy("mLoadedVolumes")
747    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
748
749    boolean mFirstBoot;
750
751    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
752
753    @GuardedBy("mAvailableFeatures")
754    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
755
756    private final InstantAppRegistry mInstantAppRegistry;
757
758    @GuardedBy("mPackages")
759    int mChangedPackagesSequenceNumber;
760    /**
761     * List of changed [installed, removed or updated] packages.
762     * mapping from user id -> sequence number -> package name
763     */
764    @GuardedBy("mPackages")
765    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
766    /**
767     * The sequence number of the last change to a package.
768     * mapping from user id -> package name -> sequence number
769     */
770    @GuardedBy("mPackages")
771    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
772
773    @GuardedBy("mPackages")
774    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
775
776    class PackageParserCallback implements PackageParser.Callback {
777        @Override public final boolean hasFeature(String feature) {
778            return PackageManagerService.this.hasSystemFeature(feature, 0);
779        }
780
781        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
782                Collection<PackageParser.Package> allPackages, String targetPackageName) {
783            List<PackageParser.Package> overlayPackages = null;
784            for (PackageParser.Package p : allPackages) {
785                if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
786                    if (overlayPackages == null) {
787                        overlayPackages = new ArrayList<PackageParser.Package>();
788                    }
789                    overlayPackages.add(p);
790                }
791            }
792            if (overlayPackages != null) {
793                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
794                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
795                        return p1.mOverlayPriority - p2.mOverlayPriority;
796                    }
797                };
798                Collections.sort(overlayPackages, cmp);
799            }
800            return overlayPackages;
801        }
802
803        @GuardedBy("mInstallLock")
804        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
805                String targetPackageName, String targetPath) {
806            if ("android".equals(targetPackageName)) {
807                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
808                // native AssetManager.
809                return null;
810            }
811            List<PackageParser.Package> overlayPackages =
812                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
813            if (overlayPackages == null || overlayPackages.isEmpty()) {
814                return null;
815            }
816            List<String> overlayPathList = null;
817            for (PackageParser.Package overlayPackage : overlayPackages) {
818                if (targetPath == null) {
819                    if (overlayPathList == null) {
820                        overlayPathList = new ArrayList<String>();
821                    }
822                    overlayPathList.add(overlayPackage.baseCodePath);
823                    continue;
824                }
825
826                try {
827                    // Creates idmaps for system to parse correctly the Android manifest of the
828                    // target package.
829                    //
830                    // OverlayManagerService will update each of them with a correct gid from its
831                    // target package app id.
832                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
833                            UserHandle.getSharedAppGid(
834                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
835                    if (overlayPathList == null) {
836                        overlayPathList = new ArrayList<String>();
837                    }
838                    overlayPathList.add(overlayPackage.baseCodePath);
839                } catch (InstallerException e) {
840                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
841                            overlayPackage.baseCodePath);
842                }
843            }
844            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
845        }
846
847        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
848            synchronized (mPackages) {
849                return getStaticOverlayPathsLocked(
850                        mPackages.values(), targetPackageName, targetPath);
851            }
852        }
853
854        @Override public final String[] getOverlayApks(String targetPackageName) {
855            return getStaticOverlayPaths(targetPackageName, null);
856        }
857
858        @Override public final String[] getOverlayPaths(String targetPackageName,
859                String targetPath) {
860            return getStaticOverlayPaths(targetPackageName, targetPath);
861        }
862    }
863
864    class ParallelPackageParserCallback extends PackageParserCallback {
865        List<PackageParser.Package> mOverlayPackages = null;
866
867        void findStaticOverlayPackages() {
868            synchronized (mPackages) {
869                for (PackageParser.Package p : mPackages.values()) {
870                    if (p.mOverlayIsStatic) {
871                        if (mOverlayPackages == null) {
872                            mOverlayPackages = new ArrayList<PackageParser.Package>();
873                        }
874                        mOverlayPackages.add(p);
875                    }
876                }
877            }
878        }
879
880        @Override
881        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
882            // We can trust mOverlayPackages without holding mPackages because package uninstall
883            // can't happen while running parallel parsing.
884            // Moreover holding mPackages on each parsing thread causes dead-lock.
885            return mOverlayPackages == null ? null :
886                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
887        }
888    }
889
890    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
891    final ParallelPackageParserCallback mParallelPackageParserCallback =
892            new ParallelPackageParserCallback();
893
894    public static final class SharedLibraryEntry {
895        public final @Nullable String path;
896        public final @Nullable String apk;
897        public final @NonNull SharedLibraryInfo info;
898
899        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
900                String declaringPackageName, long declaringPackageVersionCode) {
901            path = _path;
902            apk = _apk;
903            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
904                    declaringPackageName, declaringPackageVersionCode), null);
905        }
906    }
907
908    // Currently known shared libraries.
909    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
910    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
911            new ArrayMap<>();
912
913    // All available activities, for your resolving pleasure.
914    final ActivityIntentResolver mActivities =
915            new ActivityIntentResolver();
916
917    // All available receivers, for your resolving pleasure.
918    final ActivityIntentResolver mReceivers =
919            new ActivityIntentResolver();
920
921    // All available services, for your resolving pleasure.
922    final ServiceIntentResolver mServices = new ServiceIntentResolver();
923
924    // All available providers, for your resolving pleasure.
925    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
926
927    // Mapping from provider base names (first directory in content URI codePath)
928    // to the provider information.
929    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
930            new ArrayMap<String, PackageParser.Provider>();
931
932    // Mapping from instrumentation class names to info about them.
933    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
934            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
935
936    // Packages whose data we have transfered into another package, thus
937    // should no longer exist.
938    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
939
940    // Broadcast actions that are only available to the system.
941    @GuardedBy("mProtectedBroadcasts")
942    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
943
944    /** List of packages waiting for verification. */
945    final SparseArray<PackageVerificationState> mPendingVerification
946            = new SparseArray<PackageVerificationState>();
947
948    final PackageInstallerService mInstallerService;
949
950    final ArtManagerService mArtManagerService;
951
952    private final PackageDexOptimizer mPackageDexOptimizer;
953    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
954    // is used by other apps).
955    private final DexManager mDexManager;
956
957    private AtomicInteger mNextMoveId = new AtomicInteger();
958    private final MoveCallbacks mMoveCallbacks;
959
960    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
961
962    // Cache of users who need badging.
963    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
964
965    /** Token for keys in mPendingVerification. */
966    private int mPendingVerificationToken = 0;
967
968    volatile boolean mSystemReady;
969    volatile boolean mSafeMode;
970    volatile boolean mHasSystemUidErrors;
971    private volatile boolean mWebInstantAppsDisabled;
972
973    ApplicationInfo mAndroidApplication;
974    final ActivityInfo mResolveActivity = new ActivityInfo();
975    final ResolveInfo mResolveInfo = new ResolveInfo();
976    ComponentName mResolveComponentName;
977    PackageParser.Package mPlatformPackage;
978    ComponentName mCustomResolverComponentName;
979
980    boolean mResolverReplaced = false;
981
982    private final @Nullable ComponentName mIntentFilterVerifierComponent;
983    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
984
985    private int mIntentFilterVerificationToken = 0;
986
987    /** The service connection to the ephemeral resolver */
988    final InstantAppResolverConnection mInstantAppResolverConnection;
989    /** Component used to show resolver settings for Instant Apps */
990    final ComponentName mInstantAppResolverSettingsComponent;
991
992    /** Activity used to install instant applications */
993    ActivityInfo mInstantAppInstallerActivity;
994    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
995
996    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
997            = new SparseArray<IntentFilterVerificationState>();
998
999    // TODO remove this and go through mPermissonManager directly
1000    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1001    private final PermissionManagerInternal mPermissionManager;
1002
1003    // List of packages names to keep cached, even if they are uninstalled for all users
1004    private List<String> mKeepUninstalledPackages;
1005
1006    private UserManagerInternal mUserManagerInternal;
1007    private ActivityManagerInternal mActivityManagerInternal;
1008
1009    private DeviceIdleController.LocalService mDeviceIdleController;
1010
1011    private File mCacheDir;
1012
1013    private Future<?> mPrepareAppDataFuture;
1014
1015    private static class IFVerificationParams {
1016        PackageParser.Package pkg;
1017        boolean replacing;
1018        int userId;
1019        int verifierUid;
1020
1021        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1022                int _userId, int _verifierUid) {
1023            pkg = _pkg;
1024            replacing = _replacing;
1025            userId = _userId;
1026            replacing = _replacing;
1027            verifierUid = _verifierUid;
1028        }
1029    }
1030
1031    private interface IntentFilterVerifier<T extends IntentFilter> {
1032        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1033                                               T filter, String packageName);
1034        void startVerifications(int userId);
1035        void receiveVerificationResponse(int verificationId);
1036    }
1037
1038    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1039        private Context mContext;
1040        private ComponentName mIntentFilterVerifierComponent;
1041        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1042
1043        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1044            mContext = context;
1045            mIntentFilterVerifierComponent = verifierComponent;
1046        }
1047
1048        private String getDefaultScheme() {
1049            return IntentFilter.SCHEME_HTTPS;
1050        }
1051
1052        @Override
1053        public void startVerifications(int userId) {
1054            // Launch verifications requests
1055            int count = mCurrentIntentFilterVerifications.size();
1056            for (int n=0; n<count; n++) {
1057                int verificationId = mCurrentIntentFilterVerifications.get(n);
1058                final IntentFilterVerificationState ivs =
1059                        mIntentFilterVerificationStates.get(verificationId);
1060
1061                String packageName = ivs.getPackageName();
1062
1063                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1064                final int filterCount = filters.size();
1065                ArraySet<String> domainsSet = new ArraySet<>();
1066                for (int m=0; m<filterCount; m++) {
1067                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1068                    domainsSet.addAll(filter.getHostsList());
1069                }
1070                synchronized (mPackages) {
1071                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1072                            packageName, domainsSet) != null) {
1073                        scheduleWriteSettingsLocked();
1074                    }
1075                }
1076                sendVerificationRequest(verificationId, ivs);
1077            }
1078            mCurrentIntentFilterVerifications.clear();
1079        }
1080
1081        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1082            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1083            verificationIntent.putExtra(
1084                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1085                    verificationId);
1086            verificationIntent.putExtra(
1087                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1088                    getDefaultScheme());
1089            verificationIntent.putExtra(
1090                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1091                    ivs.getHostsString());
1092            verificationIntent.putExtra(
1093                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1094                    ivs.getPackageName());
1095            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1096            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1097
1098            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1099            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1100                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1101                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1102
1103            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1104            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1105                    "Sending IntentFilter verification broadcast");
1106        }
1107
1108        public void receiveVerificationResponse(int verificationId) {
1109            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1110
1111            final boolean verified = ivs.isVerified();
1112
1113            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1114            final int count = filters.size();
1115            if (DEBUG_DOMAIN_VERIFICATION) {
1116                Slog.i(TAG, "Received verification response " + verificationId
1117                        + " for " + count + " filters, verified=" + verified);
1118            }
1119            for (int n=0; n<count; n++) {
1120                PackageParser.ActivityIntentInfo filter = filters.get(n);
1121                filter.setVerified(verified);
1122
1123                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1124                        + " verified with result:" + verified + " and hosts:"
1125                        + ivs.getHostsString());
1126            }
1127
1128            mIntentFilterVerificationStates.remove(verificationId);
1129
1130            final String packageName = ivs.getPackageName();
1131            IntentFilterVerificationInfo ivi = null;
1132
1133            synchronized (mPackages) {
1134                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1135            }
1136            if (ivi == null) {
1137                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1138                        + verificationId + " packageName:" + packageName);
1139                return;
1140            }
1141            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1142                    "Updating IntentFilterVerificationInfo for package " + packageName
1143                            +" verificationId:" + verificationId);
1144
1145            synchronized (mPackages) {
1146                if (verified) {
1147                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1148                } else {
1149                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1150                }
1151                scheduleWriteSettingsLocked();
1152
1153                final int userId = ivs.getUserId();
1154                if (userId != UserHandle.USER_ALL) {
1155                    final int userStatus =
1156                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1157
1158                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1159                    boolean needUpdate = false;
1160
1161                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1162                    // already been set by the User thru the Disambiguation dialog
1163                    switch (userStatus) {
1164                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1165                            if (verified) {
1166                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1167                            } else {
1168                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1169                            }
1170                            needUpdate = true;
1171                            break;
1172
1173                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1174                            if (verified) {
1175                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1176                                needUpdate = true;
1177                            }
1178                            break;
1179
1180                        default:
1181                            // Nothing to do
1182                    }
1183
1184                    if (needUpdate) {
1185                        mSettings.updateIntentFilterVerificationStatusLPw(
1186                                packageName, updatedStatus, userId);
1187                        scheduleWritePackageRestrictionsLocked(userId);
1188                    }
1189                }
1190            }
1191        }
1192
1193        @Override
1194        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1195                    ActivityIntentInfo filter, String packageName) {
1196            if (!hasValidDomains(filter)) {
1197                return false;
1198            }
1199            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1200            if (ivs == null) {
1201                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1202                        packageName);
1203            }
1204            if (DEBUG_DOMAIN_VERIFICATION) {
1205                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1206            }
1207            ivs.addFilter(filter);
1208            return true;
1209        }
1210
1211        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1212                int userId, int verificationId, String packageName) {
1213            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1214                    verifierUid, userId, packageName);
1215            ivs.setPendingState();
1216            synchronized (mPackages) {
1217                mIntentFilterVerificationStates.append(verificationId, ivs);
1218                mCurrentIntentFilterVerifications.add(verificationId);
1219            }
1220            return ivs;
1221        }
1222    }
1223
1224    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1225        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1226                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1227                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1228    }
1229
1230    // Set of pending broadcasts for aggregating enable/disable of components.
1231    static class PendingPackageBroadcasts {
1232        // for each user id, a map of <package name -> components within that package>
1233        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1234
1235        public PendingPackageBroadcasts() {
1236            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1237        }
1238
1239        public ArrayList<String> get(int userId, String packageName) {
1240            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1241            return packages.get(packageName);
1242        }
1243
1244        public void put(int userId, String packageName, ArrayList<String> components) {
1245            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1246            packages.put(packageName, components);
1247        }
1248
1249        public void remove(int userId, String packageName) {
1250            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1251            if (packages != null) {
1252                packages.remove(packageName);
1253            }
1254        }
1255
1256        public void remove(int userId) {
1257            mUidMap.remove(userId);
1258        }
1259
1260        public int userIdCount() {
1261            return mUidMap.size();
1262        }
1263
1264        public int userIdAt(int n) {
1265            return mUidMap.keyAt(n);
1266        }
1267
1268        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1269            return mUidMap.get(userId);
1270        }
1271
1272        public int size() {
1273            // total number of pending broadcast entries across all userIds
1274            int num = 0;
1275            for (int i = 0; i< mUidMap.size(); i++) {
1276                num += mUidMap.valueAt(i).size();
1277            }
1278            return num;
1279        }
1280
1281        public void clear() {
1282            mUidMap.clear();
1283        }
1284
1285        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1286            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1287            if (map == null) {
1288                map = new ArrayMap<String, ArrayList<String>>();
1289                mUidMap.put(userId, map);
1290            }
1291            return map;
1292        }
1293    }
1294    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1295
1296    // Service Connection to remote media container service to copy
1297    // package uri's from external media onto secure containers
1298    // or internal storage.
1299    private IMediaContainerService mContainerService = null;
1300
1301    static final int SEND_PENDING_BROADCAST = 1;
1302    static final int MCS_BOUND = 3;
1303    static final int END_COPY = 4;
1304    static final int INIT_COPY = 5;
1305    static final int MCS_UNBIND = 6;
1306    static final int START_CLEANING_PACKAGE = 7;
1307    static final int FIND_INSTALL_LOC = 8;
1308    static final int POST_INSTALL = 9;
1309    static final int MCS_RECONNECT = 10;
1310    static final int MCS_GIVE_UP = 11;
1311    static final int WRITE_SETTINGS = 13;
1312    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1313    static final int PACKAGE_VERIFIED = 15;
1314    static final int CHECK_PENDING_VERIFICATION = 16;
1315    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1316    static final int INTENT_FILTER_VERIFIED = 18;
1317    static final int WRITE_PACKAGE_LIST = 19;
1318    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1319
1320    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1321
1322    // Delay time in millisecs
1323    static final int BROADCAST_DELAY = 10 * 1000;
1324
1325    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1326            2 * 60 * 60 * 1000L; /* two hours */
1327
1328    static UserManagerService sUserManager;
1329
1330    // Stores a list of users whose package restrictions file needs to be updated
1331    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1332
1333    final private DefaultContainerConnection mDefContainerConn =
1334            new DefaultContainerConnection();
1335    class DefaultContainerConnection implements ServiceConnection {
1336        public void onServiceConnected(ComponentName name, IBinder service) {
1337            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1338            final IMediaContainerService imcs = IMediaContainerService.Stub
1339                    .asInterface(Binder.allowBlocking(service));
1340            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1341        }
1342
1343        public void onServiceDisconnected(ComponentName name) {
1344            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1345        }
1346    }
1347
1348    // Recordkeeping of restore-after-install operations that are currently in flight
1349    // between the Package Manager and the Backup Manager
1350    static class PostInstallData {
1351        public InstallArgs args;
1352        public PackageInstalledInfo res;
1353
1354        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1355            args = _a;
1356            res = _r;
1357        }
1358    }
1359
1360    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1361    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1362
1363    // XML tags for backup/restore of various bits of state
1364    private static final String TAG_PREFERRED_BACKUP = "pa";
1365    private static final String TAG_DEFAULT_APPS = "da";
1366    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1367
1368    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1369    private static final String TAG_ALL_GRANTS = "rt-grants";
1370    private static final String TAG_GRANT = "grant";
1371    private static final String ATTR_PACKAGE_NAME = "pkg";
1372
1373    private static final String TAG_PERMISSION = "perm";
1374    private static final String ATTR_PERMISSION_NAME = "name";
1375    private static final String ATTR_IS_GRANTED = "g";
1376    private static final String ATTR_USER_SET = "set";
1377    private static final String ATTR_USER_FIXED = "fixed";
1378    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1379
1380    // System/policy permission grants are not backed up
1381    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1382            FLAG_PERMISSION_POLICY_FIXED
1383            | FLAG_PERMISSION_SYSTEM_FIXED
1384            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1385
1386    // And we back up these user-adjusted states
1387    private static final int USER_RUNTIME_GRANT_MASK =
1388            FLAG_PERMISSION_USER_SET
1389            | FLAG_PERMISSION_USER_FIXED
1390            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1391
1392    final @Nullable String mRequiredVerifierPackage;
1393    final @NonNull String mRequiredInstallerPackage;
1394    final @NonNull String mRequiredUninstallerPackage;
1395    final @Nullable String mSetupWizardPackage;
1396    final @Nullable String mStorageManagerPackage;
1397    final @Nullable String mSystemTextClassifierPackage;
1398    final @NonNull String mServicesSystemSharedLibraryPackageName;
1399    final @NonNull String mSharedSystemSharedLibraryPackageName;
1400
1401    private final PackageUsage mPackageUsage = new PackageUsage();
1402    private final CompilerStats mCompilerStats = new CompilerStats();
1403
1404    class PackageHandler extends Handler {
1405        private boolean mBound = false;
1406        final ArrayList<HandlerParams> mPendingInstalls =
1407            new ArrayList<HandlerParams>();
1408
1409        private boolean connectToService() {
1410            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1411                    " DefaultContainerService");
1412            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1413            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1414            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1415                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1416                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1417                mBound = true;
1418                return true;
1419            }
1420            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1421            return false;
1422        }
1423
1424        private void disconnectService() {
1425            mContainerService = null;
1426            mBound = false;
1427            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1428            mContext.unbindService(mDefContainerConn);
1429            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1430        }
1431
1432        PackageHandler(Looper looper) {
1433            super(looper);
1434        }
1435
1436        public void handleMessage(Message msg) {
1437            try {
1438                doHandleMessage(msg);
1439            } finally {
1440                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1441            }
1442        }
1443
1444        void doHandleMessage(Message msg) {
1445            switch (msg.what) {
1446                case INIT_COPY: {
1447                    HandlerParams params = (HandlerParams) msg.obj;
1448                    int idx = mPendingInstalls.size();
1449                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1450                    // If a bind was already initiated we dont really
1451                    // need to do anything. The pending install
1452                    // will be processed later on.
1453                    if (!mBound) {
1454                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1455                                System.identityHashCode(mHandler));
1456                        // If this is the only one pending we might
1457                        // have to bind to the service again.
1458                        if (!connectToService()) {
1459                            Slog.e(TAG, "Failed to bind to media container service");
1460                            params.serviceError();
1461                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1462                                    System.identityHashCode(mHandler));
1463                            if (params.traceMethod != null) {
1464                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1465                                        params.traceCookie);
1466                            }
1467                            return;
1468                        } else {
1469                            // Once we bind to the service, the first
1470                            // pending request will be processed.
1471                            mPendingInstalls.add(idx, params);
1472                        }
1473                    } else {
1474                        mPendingInstalls.add(idx, params);
1475                        // Already bound to the service. Just make
1476                        // sure we trigger off processing the first request.
1477                        if (idx == 0) {
1478                            mHandler.sendEmptyMessage(MCS_BOUND);
1479                        }
1480                    }
1481                    break;
1482                }
1483                case MCS_BOUND: {
1484                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1485                    if (msg.obj != null) {
1486                        mContainerService = (IMediaContainerService) msg.obj;
1487                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1488                                System.identityHashCode(mHandler));
1489                    }
1490                    if (mContainerService == null) {
1491                        if (!mBound) {
1492                            // Something seriously wrong since we are not bound and we are not
1493                            // waiting for connection. Bail out.
1494                            Slog.e(TAG, "Cannot bind to media container service");
1495                            for (HandlerParams params : mPendingInstalls) {
1496                                // Indicate service bind error
1497                                params.serviceError();
1498                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1499                                        System.identityHashCode(params));
1500                                if (params.traceMethod != null) {
1501                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1502                                            params.traceMethod, params.traceCookie);
1503                                }
1504                                return;
1505                            }
1506                            mPendingInstalls.clear();
1507                        } else {
1508                            Slog.w(TAG, "Waiting to connect to media container service");
1509                        }
1510                    } else if (mPendingInstalls.size() > 0) {
1511                        HandlerParams params = mPendingInstalls.get(0);
1512                        if (params != null) {
1513                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1514                                    System.identityHashCode(params));
1515                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1516                            if (params.startCopy()) {
1517                                // We are done...  look for more work or to
1518                                // go idle.
1519                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1520                                        "Checking for more work or unbind...");
1521                                // Delete pending install
1522                                if (mPendingInstalls.size() > 0) {
1523                                    mPendingInstalls.remove(0);
1524                                }
1525                                if (mPendingInstalls.size() == 0) {
1526                                    if (mBound) {
1527                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1528                                                "Posting delayed MCS_UNBIND");
1529                                        removeMessages(MCS_UNBIND);
1530                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1531                                        // Unbind after a little delay, to avoid
1532                                        // continual thrashing.
1533                                        sendMessageDelayed(ubmsg, 10000);
1534                                    }
1535                                } else {
1536                                    // There are more pending requests in queue.
1537                                    // Just post MCS_BOUND message to trigger processing
1538                                    // of next pending install.
1539                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1540                                            "Posting MCS_BOUND for next work");
1541                                    mHandler.sendEmptyMessage(MCS_BOUND);
1542                                }
1543                            }
1544                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1545                        }
1546                    } else {
1547                        // Should never happen ideally.
1548                        Slog.w(TAG, "Empty queue");
1549                    }
1550                    break;
1551                }
1552                case MCS_RECONNECT: {
1553                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1554                    if (mPendingInstalls.size() > 0) {
1555                        if (mBound) {
1556                            disconnectService();
1557                        }
1558                        if (!connectToService()) {
1559                            Slog.e(TAG, "Failed to bind to media container service");
1560                            for (HandlerParams params : mPendingInstalls) {
1561                                // Indicate service bind error
1562                                params.serviceError();
1563                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1564                                        System.identityHashCode(params));
1565                            }
1566                            mPendingInstalls.clear();
1567                        }
1568                    }
1569                    break;
1570                }
1571                case MCS_UNBIND: {
1572                    // If there is no actual work left, then time to unbind.
1573                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1574
1575                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1576                        if (mBound) {
1577                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1578
1579                            disconnectService();
1580                        }
1581                    } else if (mPendingInstalls.size() > 0) {
1582                        // There are more pending requests in queue.
1583                        // Just post MCS_BOUND message to trigger processing
1584                        // of next pending install.
1585                        mHandler.sendEmptyMessage(MCS_BOUND);
1586                    }
1587
1588                    break;
1589                }
1590                case MCS_GIVE_UP: {
1591                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1592                    HandlerParams params = mPendingInstalls.remove(0);
1593                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1594                            System.identityHashCode(params));
1595                    break;
1596                }
1597                case SEND_PENDING_BROADCAST: {
1598                    String packages[];
1599                    ArrayList<String> components[];
1600                    int size = 0;
1601                    int uids[];
1602                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1603                    synchronized (mPackages) {
1604                        if (mPendingBroadcasts == null) {
1605                            return;
1606                        }
1607                        size = mPendingBroadcasts.size();
1608                        if (size <= 0) {
1609                            // Nothing to be done. Just return
1610                            return;
1611                        }
1612                        packages = new String[size];
1613                        components = new ArrayList[size];
1614                        uids = new int[size];
1615                        int i = 0;  // filling out the above arrays
1616
1617                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1618                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1619                            Iterator<Map.Entry<String, ArrayList<String>>> it
1620                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1621                                            .entrySet().iterator();
1622                            while (it.hasNext() && i < size) {
1623                                Map.Entry<String, ArrayList<String>> ent = it.next();
1624                                packages[i] = ent.getKey();
1625                                components[i] = ent.getValue();
1626                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1627                                uids[i] = (ps != null)
1628                                        ? UserHandle.getUid(packageUserId, ps.appId)
1629                                        : -1;
1630                                i++;
1631                            }
1632                        }
1633                        size = i;
1634                        mPendingBroadcasts.clear();
1635                    }
1636                    // Send broadcasts
1637                    for (int i = 0; i < size; i++) {
1638                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1639                    }
1640                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1641                    break;
1642                }
1643                case START_CLEANING_PACKAGE: {
1644                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1645                    final String packageName = (String)msg.obj;
1646                    final int userId = msg.arg1;
1647                    final boolean andCode = msg.arg2 != 0;
1648                    synchronized (mPackages) {
1649                        if (userId == UserHandle.USER_ALL) {
1650                            int[] users = sUserManager.getUserIds();
1651                            for (int user : users) {
1652                                mSettings.addPackageToCleanLPw(
1653                                        new PackageCleanItem(user, packageName, andCode));
1654                            }
1655                        } else {
1656                            mSettings.addPackageToCleanLPw(
1657                                    new PackageCleanItem(userId, packageName, andCode));
1658                        }
1659                    }
1660                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1661                    startCleaningPackages();
1662                } break;
1663                case POST_INSTALL: {
1664                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1665
1666                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1667                    final boolean didRestore = (msg.arg2 != 0);
1668                    mRunningInstalls.delete(msg.arg1);
1669
1670                    if (data != null) {
1671                        InstallArgs args = data.args;
1672                        PackageInstalledInfo parentRes = data.res;
1673
1674                        final boolean grantPermissions = (args.installFlags
1675                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1676                        final boolean killApp = (args.installFlags
1677                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1678                        final boolean virtualPreload = ((args.installFlags
1679                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1680                        final String[] grantedPermissions = args.installGrantPermissions;
1681
1682                        // Handle the parent package
1683                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1684                                virtualPreload, grantedPermissions, didRestore,
1685                                args.installerPackageName, args.observer);
1686
1687                        // Handle the child packages
1688                        final int childCount = (parentRes.addedChildPackages != null)
1689                                ? parentRes.addedChildPackages.size() : 0;
1690                        for (int i = 0; i < childCount; i++) {
1691                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1692                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1693                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1694                                    args.installerPackageName, args.observer);
1695                        }
1696
1697                        // Log tracing if needed
1698                        if (args.traceMethod != null) {
1699                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1700                                    args.traceCookie);
1701                        }
1702                    } else {
1703                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1704                    }
1705
1706                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1707                } break;
1708                case WRITE_SETTINGS: {
1709                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1710                    synchronized (mPackages) {
1711                        removeMessages(WRITE_SETTINGS);
1712                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1713                        mSettings.writeLPr();
1714                        mDirtyUsers.clear();
1715                    }
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1717                } break;
1718                case WRITE_PACKAGE_RESTRICTIONS: {
1719                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1720                    synchronized (mPackages) {
1721                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1722                        for (int userId : mDirtyUsers) {
1723                            mSettings.writePackageRestrictionsLPr(userId);
1724                        }
1725                        mDirtyUsers.clear();
1726                    }
1727                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1728                } break;
1729                case WRITE_PACKAGE_LIST: {
1730                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1731                    synchronized (mPackages) {
1732                        removeMessages(WRITE_PACKAGE_LIST);
1733                        mSettings.writePackageListLPr(msg.arg1);
1734                    }
1735                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1736                } break;
1737                case CHECK_PENDING_VERIFICATION: {
1738                    final int verificationId = msg.arg1;
1739                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1740
1741                    if ((state != null) && !state.timeoutExtended()) {
1742                        final InstallArgs args = state.getInstallArgs();
1743                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1744
1745                        Slog.i(TAG, "Verification timed out for " + originUri);
1746                        mPendingVerification.remove(verificationId);
1747
1748                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1749
1750                        final UserHandle user = args.getUser();
1751                        if (getDefaultVerificationResponse(user)
1752                                == PackageManager.VERIFICATION_ALLOW) {
1753                            Slog.i(TAG, "Continuing with installation of " + originUri);
1754                            state.setVerifierResponse(Binder.getCallingUid(),
1755                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1756                            broadcastPackageVerified(verificationId, originUri,
1757                                    PackageManager.VERIFICATION_ALLOW, user);
1758                            try {
1759                                ret = args.copyApk(mContainerService, true);
1760                            } catch (RemoteException e) {
1761                                Slog.e(TAG, "Could not contact the ContainerService");
1762                            }
1763                        } else {
1764                            broadcastPackageVerified(verificationId, originUri,
1765                                    PackageManager.VERIFICATION_REJECT, user);
1766                        }
1767
1768                        Trace.asyncTraceEnd(
1769                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1770
1771                        processPendingInstall(args, ret);
1772                        mHandler.sendEmptyMessage(MCS_UNBIND);
1773                    }
1774                    break;
1775                }
1776                case PACKAGE_VERIFIED: {
1777                    final int verificationId = msg.arg1;
1778
1779                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1780                    if (state == null) {
1781                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1782                        break;
1783                    }
1784
1785                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1786
1787                    state.setVerifierResponse(response.callerUid, response.code);
1788
1789                    if (state.isVerificationComplete()) {
1790                        mPendingVerification.remove(verificationId);
1791
1792                        final InstallArgs args = state.getInstallArgs();
1793                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1794
1795                        int ret;
1796                        if (state.isInstallAllowed()) {
1797                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1798                            broadcastPackageVerified(verificationId, originUri,
1799                                    response.code, state.getInstallArgs().getUser());
1800                            try {
1801                                ret = args.copyApk(mContainerService, true);
1802                            } catch (RemoteException e) {
1803                                Slog.e(TAG, "Could not contact the ContainerService");
1804                            }
1805                        } else {
1806                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1807                        }
1808
1809                        Trace.asyncTraceEnd(
1810                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1811
1812                        processPendingInstall(args, ret);
1813                        mHandler.sendEmptyMessage(MCS_UNBIND);
1814                    }
1815
1816                    break;
1817                }
1818                case START_INTENT_FILTER_VERIFICATIONS: {
1819                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1820                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1821                            params.replacing, params.pkg);
1822                    break;
1823                }
1824                case INTENT_FILTER_VERIFIED: {
1825                    final int verificationId = msg.arg1;
1826
1827                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1828                            verificationId);
1829                    if (state == null) {
1830                        Slog.w(TAG, "Invalid IntentFilter verification token "
1831                                + verificationId + " received");
1832                        break;
1833                    }
1834
1835                    final int userId = state.getUserId();
1836
1837                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1838                            "Processing IntentFilter verification with token:"
1839                            + verificationId + " and userId:" + userId);
1840
1841                    final IntentFilterVerificationResponse response =
1842                            (IntentFilterVerificationResponse) msg.obj;
1843
1844                    state.setVerifierResponse(response.callerUid, response.code);
1845
1846                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1847                            "IntentFilter verification with token:" + verificationId
1848                            + " and userId:" + userId
1849                            + " is settings verifier response with response code:"
1850                            + response.code);
1851
1852                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1853                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1854                                + response.getFailedDomainsString());
1855                    }
1856
1857                    if (state.isVerificationComplete()) {
1858                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1859                    } else {
1860                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1861                                "IntentFilter verification with token:" + verificationId
1862                                + " was not said to be complete");
1863                    }
1864
1865                    break;
1866                }
1867                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1868                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1869                            mInstantAppResolverConnection,
1870                            (InstantAppRequest) msg.obj,
1871                            mInstantAppInstallerActivity,
1872                            mHandler);
1873                }
1874            }
1875        }
1876    }
1877
1878    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1879        @Override
1880        public void onGidsChanged(int appId, int userId) {
1881            mHandler.post(new Runnable() {
1882                @Override
1883                public void run() {
1884                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1885                }
1886            });
1887        }
1888        @Override
1889        public void onPermissionGranted(int uid, int userId) {
1890            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1891
1892            // Not critical; if this is lost, the application has to request again.
1893            synchronized (mPackages) {
1894                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1895            }
1896        }
1897        @Override
1898        public void onInstallPermissionGranted() {
1899            synchronized (mPackages) {
1900                scheduleWriteSettingsLocked();
1901            }
1902        }
1903        @Override
1904        public void onPermissionRevoked(int uid, int userId) {
1905            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1906
1907            synchronized (mPackages) {
1908                // Critical; after this call the application should never have the permission
1909                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1910            }
1911
1912            final int appId = UserHandle.getAppId(uid);
1913            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1914        }
1915        @Override
1916        public void onInstallPermissionRevoked() {
1917            synchronized (mPackages) {
1918                scheduleWriteSettingsLocked();
1919            }
1920        }
1921        @Override
1922        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1923            synchronized (mPackages) {
1924                for (int userId : updatedUserIds) {
1925                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1926                }
1927            }
1928        }
1929        @Override
1930        public void onInstallPermissionUpdated() {
1931            synchronized (mPackages) {
1932                scheduleWriteSettingsLocked();
1933            }
1934        }
1935        @Override
1936        public void onPermissionRemoved() {
1937            synchronized (mPackages) {
1938                mSettings.writeLPr();
1939            }
1940        }
1941    };
1942
1943    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1944            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1945            boolean launchedForRestore, String installerPackage,
1946            IPackageInstallObserver2 installObserver) {
1947        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1948            // Send the removed broadcasts
1949            if (res.removedInfo != null) {
1950                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1951            }
1952
1953            // Now that we successfully installed the package, grant runtime
1954            // permissions if requested before broadcasting the install. Also
1955            // for legacy apps in permission review mode we clear the permission
1956            // review flag which is used to emulate runtime permissions for
1957            // legacy apps.
1958            if (grantPermissions) {
1959                final int callingUid = Binder.getCallingUid();
1960                mPermissionManager.grantRequestedRuntimePermissions(
1961                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1962                        mPermissionCallback);
1963            }
1964
1965            final boolean update = res.removedInfo != null
1966                    && res.removedInfo.removedPackage != null;
1967            final String installerPackageName =
1968                    res.installerPackageName != null
1969                            ? res.installerPackageName
1970                            : res.removedInfo != null
1971                                    ? res.removedInfo.installerPackageName
1972                                    : null;
1973
1974            // If this is the first time we have child packages for a disabled privileged
1975            // app that had no children, we grant requested runtime permissions to the new
1976            // children if the parent on the system image had them already granted.
1977            if (res.pkg.parentPackage != null) {
1978                final int callingUid = Binder.getCallingUid();
1979                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1980                        res.pkg, callingUid, mPermissionCallback);
1981            }
1982
1983            synchronized (mPackages) {
1984                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1985            }
1986
1987            final String packageName = res.pkg.applicationInfo.packageName;
1988
1989            // Determine the set of users who are adding this package for
1990            // the first time vs. those who are seeing an update.
1991            int[] firstUserIds = EMPTY_INT_ARRAY;
1992            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1993            int[] updateUserIds = EMPTY_INT_ARRAY;
1994            int[] instantUserIds = EMPTY_INT_ARRAY;
1995            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1996            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1997            for (int newUser : res.newUsers) {
1998                final boolean isInstantApp = ps.getInstantApp(newUser);
1999                if (allNewUsers) {
2000                    if (isInstantApp) {
2001                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2002                    } else {
2003                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2004                    }
2005                    continue;
2006                }
2007                boolean isNew = true;
2008                for (int origUser : res.origUsers) {
2009                    if (origUser == newUser) {
2010                        isNew = false;
2011                        break;
2012                    }
2013                }
2014                if (isNew) {
2015                    if (isInstantApp) {
2016                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2017                    } else {
2018                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2019                    }
2020                } else {
2021                    if (isInstantApp) {
2022                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2023                    } else {
2024                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2025                    }
2026                }
2027            }
2028
2029            // Send installed broadcasts if the package is not a static shared lib.
2030            if (res.pkg.staticSharedLibName == null) {
2031                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2032
2033                // Send added for users that see the package for the first time
2034                // sendPackageAddedForNewUsers also deals with system apps
2035                int appId = UserHandle.getAppId(res.uid);
2036                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2037                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2038                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2039
2040                // Send added for users that don't see the package for the first time
2041                Bundle extras = new Bundle(1);
2042                extras.putInt(Intent.EXTRA_UID, res.uid);
2043                if (update) {
2044                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2045                }
2046                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2047                        extras, 0 /*flags*/,
2048                        null /*targetPackage*/, null /*finishedReceiver*/,
2049                        updateUserIds, instantUserIds);
2050                if (installerPackageName != null) {
2051                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2052                            extras, 0 /*flags*/,
2053                            installerPackageName, null /*finishedReceiver*/,
2054                            updateUserIds, instantUserIds);
2055                }
2056
2057                // Send replaced for users that don't see the package for the first time
2058                if (update) {
2059                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2060                            packageName, extras, 0 /*flags*/,
2061                            null /*targetPackage*/, null /*finishedReceiver*/,
2062                            updateUserIds, instantUserIds);
2063                    if (installerPackageName != null) {
2064                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2065                                extras, 0 /*flags*/,
2066                                installerPackageName, null /*finishedReceiver*/,
2067                                updateUserIds, instantUserIds);
2068                    }
2069                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2070                            null /*package*/, null /*extras*/, 0 /*flags*/,
2071                            packageName /*targetPackage*/,
2072                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2073                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2074                    // First-install and we did a restore, so we're responsible for the
2075                    // first-launch broadcast.
2076                    if (DEBUG_BACKUP) {
2077                        Slog.i(TAG, "Post-restore of " + packageName
2078                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2079                    }
2080                    sendFirstLaunchBroadcast(packageName, installerPackage,
2081                            firstUserIds, firstInstantUserIds);
2082                }
2083
2084                // Send broadcast package appeared if forward locked/external for all users
2085                // treat asec-hosted packages like removable media on upgrade
2086                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2087                    if (DEBUG_INSTALL) {
2088                        Slog.i(TAG, "upgrading pkg " + res.pkg
2089                                + " is ASEC-hosted -> AVAILABLE");
2090                    }
2091                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2092                    ArrayList<String> pkgList = new ArrayList<>(1);
2093                    pkgList.add(packageName);
2094                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2095                }
2096            }
2097
2098            // Work that needs to happen on first install within each user
2099            if (firstUserIds != null && firstUserIds.length > 0) {
2100                synchronized (mPackages) {
2101                    for (int userId : firstUserIds) {
2102                        // If this app is a browser and it's newly-installed for some
2103                        // users, clear any default-browser state in those users. The
2104                        // app's nature doesn't depend on the user, so we can just check
2105                        // its browser nature in any user and generalize.
2106                        if (packageIsBrowser(packageName, userId)) {
2107                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2108                        }
2109
2110                        // We may also need to apply pending (restored) runtime
2111                        // permission grants within these users.
2112                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2113                    }
2114                }
2115            }
2116
2117            if (allNewUsers && !update) {
2118                notifyPackageAdded(packageName);
2119            }
2120
2121            // Log current value of "unknown sources" setting
2122            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2123                    getUnknownSourcesSettings());
2124
2125            // Remove the replaced package's older resources safely now
2126            // We delete after a gc for applications  on sdcard.
2127            if (res.removedInfo != null && res.removedInfo.args != null) {
2128                Runtime.getRuntime().gc();
2129                synchronized (mInstallLock) {
2130                    res.removedInfo.args.doPostDeleteLI(true);
2131                }
2132            } else {
2133                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2134                // and not block here.
2135                VMRuntime.getRuntime().requestConcurrentGC();
2136            }
2137
2138            // Notify DexManager that the package was installed for new users.
2139            // The updated users should already be indexed and the package code paths
2140            // should not change.
2141            // Don't notify the manager for ephemeral apps as they are not expected to
2142            // survive long enough to benefit of background optimizations.
2143            for (int userId : firstUserIds) {
2144                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2145                // There's a race currently where some install events may interleave with an uninstall.
2146                // This can lead to package info being null (b/36642664).
2147                if (info != null) {
2148                    mDexManager.notifyPackageInstalled(info, userId);
2149                }
2150            }
2151        }
2152
2153        // If someone is watching installs - notify them
2154        if (installObserver != null) {
2155            try {
2156                Bundle extras = extrasForInstallResult(res);
2157                installObserver.onPackageInstalled(res.name, res.returnCode,
2158                        res.returnMsg, extras);
2159            } catch (RemoteException e) {
2160                Slog.i(TAG, "Observer no longer exists.");
2161            }
2162        }
2163    }
2164
2165    private StorageEventListener mStorageListener = new StorageEventListener() {
2166        @Override
2167        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2168            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2169                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2170                    final String volumeUuid = vol.getFsUuid();
2171
2172                    // Clean up any users or apps that were removed or recreated
2173                    // while this volume was missing
2174                    sUserManager.reconcileUsers(volumeUuid);
2175                    reconcileApps(volumeUuid);
2176
2177                    // Clean up any install sessions that expired or were
2178                    // cancelled while this volume was missing
2179                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2180
2181                    loadPrivatePackages(vol);
2182
2183                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2184                    unloadPrivatePackages(vol);
2185                }
2186            }
2187        }
2188
2189        @Override
2190        public void onVolumeForgotten(String fsUuid) {
2191            if (TextUtils.isEmpty(fsUuid)) {
2192                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2193                return;
2194            }
2195
2196            // Remove any apps installed on the forgotten volume
2197            synchronized (mPackages) {
2198                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2199                for (PackageSetting ps : packages) {
2200                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2201                    deletePackageVersioned(new VersionedPackage(ps.name,
2202                            PackageManager.VERSION_CODE_HIGHEST),
2203                            new LegacyPackageDeleteObserver(null).getBinder(),
2204                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2205                    // Try very hard to release any references to this package
2206                    // so we don't risk the system server being killed due to
2207                    // open FDs
2208                    AttributeCache.instance().removePackage(ps.name);
2209                }
2210
2211                mSettings.onVolumeForgotten(fsUuid);
2212                mSettings.writeLPr();
2213            }
2214        }
2215    };
2216
2217    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2218        Bundle extras = null;
2219        switch (res.returnCode) {
2220            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2221                extras = new Bundle();
2222                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2223                        res.origPermission);
2224                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2225                        res.origPackage);
2226                break;
2227            }
2228            case PackageManager.INSTALL_SUCCEEDED: {
2229                extras = new Bundle();
2230                extras.putBoolean(Intent.EXTRA_REPLACING,
2231                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2232                break;
2233            }
2234        }
2235        return extras;
2236    }
2237
2238    void scheduleWriteSettingsLocked() {
2239        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2240            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2241        }
2242    }
2243
2244    void scheduleWritePackageListLocked(int userId) {
2245        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2246            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2247            msg.arg1 = userId;
2248            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2249        }
2250    }
2251
2252    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2253        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2254        scheduleWritePackageRestrictionsLocked(userId);
2255    }
2256
2257    void scheduleWritePackageRestrictionsLocked(int userId) {
2258        final int[] userIds = (userId == UserHandle.USER_ALL)
2259                ? sUserManager.getUserIds() : new int[]{userId};
2260        for (int nextUserId : userIds) {
2261            if (!sUserManager.exists(nextUserId)) return;
2262            mDirtyUsers.add(nextUserId);
2263            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2264                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2265            }
2266        }
2267    }
2268
2269    public static PackageManagerService main(Context context, Installer installer,
2270            boolean factoryTest, boolean onlyCore) {
2271        // Self-check for initial settings.
2272        PackageManagerServiceCompilerMapping.checkProperties();
2273
2274        PackageManagerService m = new PackageManagerService(context, installer,
2275                factoryTest, onlyCore);
2276        m.enableSystemUserPackages();
2277        ServiceManager.addService("package", m);
2278        final PackageManagerNative pmn = m.new PackageManagerNative();
2279        ServiceManager.addService("package_native", pmn);
2280        return m;
2281    }
2282
2283    private void enableSystemUserPackages() {
2284        if (!UserManager.isSplitSystemUser()) {
2285            return;
2286        }
2287        // For system user, enable apps based on the following conditions:
2288        // - app is whitelisted or belong to one of these groups:
2289        //   -- system app which has no launcher icons
2290        //   -- system app which has INTERACT_ACROSS_USERS permission
2291        //   -- system IME app
2292        // - app is not in the blacklist
2293        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2294        Set<String> enableApps = new ArraySet<>();
2295        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2296                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2297                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2298        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2299        enableApps.addAll(wlApps);
2300        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2301                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2302        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2303        enableApps.removeAll(blApps);
2304        Log.i(TAG, "Applications installed for system user: " + enableApps);
2305        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2306                UserHandle.SYSTEM);
2307        final int allAppsSize = allAps.size();
2308        synchronized (mPackages) {
2309            for (int i = 0; i < allAppsSize; i++) {
2310                String pName = allAps.get(i);
2311                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2312                // Should not happen, but we shouldn't be failing if it does
2313                if (pkgSetting == null) {
2314                    continue;
2315                }
2316                boolean install = enableApps.contains(pName);
2317                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2318                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2319                            + " for system user");
2320                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2321                }
2322            }
2323            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2324        }
2325    }
2326
2327    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2328        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2329                Context.DISPLAY_SERVICE);
2330        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2331    }
2332
2333    /**
2334     * Requests that files preopted on a secondary system partition be copied to the data partition
2335     * if possible.  Note that the actual copying of the files is accomplished by init for security
2336     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2337     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2338     */
2339    private static void requestCopyPreoptedFiles() {
2340        final int WAIT_TIME_MS = 100;
2341        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2342        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2343            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2344            // We will wait for up to 100 seconds.
2345            final long timeStart = SystemClock.uptimeMillis();
2346            final long timeEnd = timeStart + 100 * 1000;
2347            long timeNow = timeStart;
2348            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2349                try {
2350                    Thread.sleep(WAIT_TIME_MS);
2351                } catch (InterruptedException e) {
2352                    // Do nothing
2353                }
2354                timeNow = SystemClock.uptimeMillis();
2355                if (timeNow > timeEnd) {
2356                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2357                    Slog.wtf(TAG, "cppreopt did not finish!");
2358                    break;
2359                }
2360            }
2361
2362            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2363        }
2364    }
2365
2366    public PackageManagerService(Context context, Installer installer,
2367            boolean factoryTest, boolean onlyCore) {
2368        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2369        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2370        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2371                SystemClock.uptimeMillis());
2372
2373        if (mSdkVersion <= 0) {
2374            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2375        }
2376
2377        mContext = context;
2378
2379        mFactoryTest = factoryTest;
2380        mOnlyCore = onlyCore;
2381        mMetrics = new DisplayMetrics();
2382        mInstaller = installer;
2383
2384        // Create sub-components that provide services / data. Order here is important.
2385        synchronized (mInstallLock) {
2386        synchronized (mPackages) {
2387            // Expose private service for system components to use.
2388            LocalServices.addService(
2389                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2390            sUserManager = new UserManagerService(context, this,
2391                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2392            mPermissionManager = PermissionManagerService.create(context,
2393                    new DefaultPermissionGrantedCallback() {
2394                        @Override
2395                        public void onDefaultRuntimePermissionsGranted(int userId) {
2396                            synchronized(mPackages) {
2397                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2398                            }
2399                        }
2400                    }, mPackages /*externalLock*/);
2401            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2402            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2403        }
2404        }
2405        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2406                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2407        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2408                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2409        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2410                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2411        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2412                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2413        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2414                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2415        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2416                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2417        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2418                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2419
2420        String separateProcesses = SystemProperties.get("debug.separate_processes");
2421        if (separateProcesses != null && separateProcesses.length() > 0) {
2422            if ("*".equals(separateProcesses)) {
2423                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2424                mSeparateProcesses = null;
2425                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2426            } else {
2427                mDefParseFlags = 0;
2428                mSeparateProcesses = separateProcesses.split(",");
2429                Slog.w(TAG, "Running with debug.separate_processes: "
2430                        + separateProcesses);
2431            }
2432        } else {
2433            mDefParseFlags = 0;
2434            mSeparateProcesses = null;
2435        }
2436
2437        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2438                "*dexopt*");
2439        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2440                installer, mInstallLock);
2441        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2442                dexManagerListener);
2443        mArtManagerService = new ArtManagerService(this, installer, mInstallLock);
2444        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2445
2446        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2447                FgThread.get().getLooper());
2448
2449        getDefaultDisplayMetrics(context, mMetrics);
2450
2451        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2452        SystemConfig systemConfig = SystemConfig.getInstance();
2453        mAvailableFeatures = systemConfig.getAvailableFeatures();
2454        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2455
2456        mProtectedPackages = new ProtectedPackages(mContext);
2457
2458        synchronized (mInstallLock) {
2459        // writer
2460        synchronized (mPackages) {
2461            mHandlerThread = new ServiceThread(TAG,
2462                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2463            mHandlerThread.start();
2464            mHandler = new PackageHandler(mHandlerThread.getLooper());
2465            mProcessLoggingHandler = new ProcessLoggingHandler();
2466            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2467            mInstantAppRegistry = new InstantAppRegistry(this);
2468
2469            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2470            final int builtInLibCount = libConfig.size();
2471            for (int i = 0; i < builtInLibCount; i++) {
2472                String name = libConfig.keyAt(i);
2473                String path = libConfig.valueAt(i);
2474                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2475                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2476            }
2477
2478            SELinuxMMAC.readInstallPolicy();
2479
2480            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2481            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2482            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2483
2484            // Clean up orphaned packages for which the code path doesn't exist
2485            // and they are an update to a system app - caused by bug/32321269
2486            final int packageSettingCount = mSettings.mPackages.size();
2487            for (int i = packageSettingCount - 1; i >= 0; i--) {
2488                PackageSetting ps = mSettings.mPackages.valueAt(i);
2489                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2490                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2491                    mSettings.mPackages.removeAt(i);
2492                    mSettings.enableSystemPackageLPw(ps.name);
2493                }
2494            }
2495
2496            if (mFirstBoot) {
2497                requestCopyPreoptedFiles();
2498            }
2499
2500            String customResolverActivity = Resources.getSystem().getString(
2501                    R.string.config_customResolverActivity);
2502            if (TextUtils.isEmpty(customResolverActivity)) {
2503                customResolverActivity = null;
2504            } else {
2505                mCustomResolverComponentName = ComponentName.unflattenFromString(
2506                        customResolverActivity);
2507            }
2508
2509            long startTime = SystemClock.uptimeMillis();
2510
2511            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2512                    startTime);
2513
2514            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2515            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2516
2517            if (bootClassPath == null) {
2518                Slog.w(TAG, "No BOOTCLASSPATH found!");
2519            }
2520
2521            if (systemServerClassPath == null) {
2522                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2523            }
2524
2525            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2526
2527            final VersionInfo ver = mSettings.getInternalVersion();
2528            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2529            if (mIsUpgrade) {
2530                logCriticalInfo(Log.INFO,
2531                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2532            }
2533
2534            // when upgrading from pre-M, promote system app permissions from install to runtime
2535            mPromoteSystemApps =
2536                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2537
2538            // When upgrading from pre-N, we need to handle package extraction like first boot,
2539            // as there is no profiling data available.
2540            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2541
2542            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2543
2544            // save off the names of pre-existing system packages prior to scanning; we don't
2545            // want to automatically grant runtime permissions for new system apps
2546            if (mPromoteSystemApps) {
2547                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2548                while (pkgSettingIter.hasNext()) {
2549                    PackageSetting ps = pkgSettingIter.next();
2550                    if (isSystemApp(ps)) {
2551                        mExistingSystemPackages.add(ps.name);
2552                    }
2553                }
2554            }
2555
2556            mCacheDir = preparePackageParserCache(mIsUpgrade);
2557
2558            // Set flag to monitor and not change apk file paths when
2559            // scanning install directories.
2560            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2561
2562            if (mIsUpgrade || mFirstBoot) {
2563                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2564            }
2565
2566            // Collect vendor/product overlay packages. (Do this before scanning any apps.)
2567            // For security and version matching reason, only consider
2568            // overlay packages if they reside in the right directory.
2569            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2570                    mDefParseFlags
2571                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2572                    scanFlags
2573                    | SCAN_AS_SYSTEM
2574                    | SCAN_AS_VENDOR,
2575                    0);
2576            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2577                    mDefParseFlags
2578                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2579                    scanFlags
2580                    | SCAN_AS_SYSTEM
2581                    | SCAN_AS_PRODUCT,
2582                    0);
2583
2584            mParallelPackageParserCallback.findStaticOverlayPackages();
2585
2586            // Find base frameworks (resource packages without code).
2587            scanDirTracedLI(frameworkDir,
2588                    mDefParseFlags
2589                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2590                    scanFlags
2591                    | SCAN_NO_DEX
2592                    | SCAN_AS_SYSTEM
2593                    | SCAN_AS_PRIVILEGED,
2594                    0);
2595
2596            // Collected privileged system packages.
2597            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2598            scanDirTracedLI(privilegedAppDir,
2599                    mDefParseFlags
2600                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2601                    scanFlags
2602                    | SCAN_AS_SYSTEM
2603                    | SCAN_AS_PRIVILEGED,
2604                    0);
2605
2606            // Collect ordinary system packages.
2607            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2608            scanDirTracedLI(systemAppDir,
2609                    mDefParseFlags
2610                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2611                    scanFlags
2612                    | SCAN_AS_SYSTEM,
2613                    0);
2614
2615            // Collected privileged vendor packages.
2616            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2617            try {
2618                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2619            } catch (IOException e) {
2620                // failed to look up canonical path, continue with original one
2621            }
2622            scanDirTracedLI(privilegedVendorAppDir,
2623                    mDefParseFlags
2624                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2625                    scanFlags
2626                    | SCAN_AS_SYSTEM
2627                    | SCAN_AS_VENDOR
2628                    | SCAN_AS_PRIVILEGED,
2629                    0);
2630
2631            // Collect ordinary vendor packages.
2632            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2633            try {
2634                vendorAppDir = vendorAppDir.getCanonicalFile();
2635            } catch (IOException e) {
2636                // failed to look up canonical path, continue with original one
2637            }
2638            scanDirTracedLI(vendorAppDir,
2639                    mDefParseFlags
2640                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2641                    scanFlags
2642                    | SCAN_AS_SYSTEM
2643                    | SCAN_AS_VENDOR,
2644                    0);
2645
2646            // Collect all OEM packages.
2647            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2648            scanDirTracedLI(oemAppDir,
2649                    mDefParseFlags
2650                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2651                    scanFlags
2652                    | SCAN_AS_SYSTEM
2653                    | SCAN_AS_OEM,
2654                    0);
2655
2656            // Collected privileged product packages.
2657            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2658            try {
2659                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2660            } catch (IOException e) {
2661                // failed to look up canonical path, continue with original one
2662            }
2663            scanDirTracedLI(privilegedProductAppDir,
2664                    mDefParseFlags
2665                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2666                    scanFlags
2667                    | SCAN_AS_SYSTEM
2668                    | SCAN_AS_PRODUCT
2669                    | SCAN_AS_PRIVILEGED,
2670                    0);
2671
2672            // Collect ordinary product packages.
2673            File productAppDir = new File(Environment.getProductDirectory(), "app");
2674            try {
2675                productAppDir = productAppDir.getCanonicalFile();
2676            } catch (IOException e) {
2677                // failed to look up canonical path, continue with original one
2678            }
2679            scanDirTracedLI(productAppDir,
2680                    mDefParseFlags
2681                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2682                    scanFlags
2683                    | SCAN_AS_SYSTEM
2684                    | SCAN_AS_PRODUCT,
2685                    0);
2686
2687            // Prune any system packages that no longer exist.
2688            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2689            // Stub packages must either be replaced with full versions in the /data
2690            // partition or be disabled.
2691            final List<String> stubSystemApps = new ArrayList<>();
2692            if (!mOnlyCore) {
2693                // do this first before mucking with mPackages for the "expecting better" case
2694                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2695                while (pkgIterator.hasNext()) {
2696                    final PackageParser.Package pkg = pkgIterator.next();
2697                    if (pkg.isStub) {
2698                        stubSystemApps.add(pkg.packageName);
2699                    }
2700                }
2701
2702                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2703                while (psit.hasNext()) {
2704                    PackageSetting ps = psit.next();
2705
2706                    /*
2707                     * If this is not a system app, it can't be a
2708                     * disable system app.
2709                     */
2710                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2711                        continue;
2712                    }
2713
2714                    /*
2715                     * If the package is scanned, it's not erased.
2716                     */
2717                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2718                    if (scannedPkg != null) {
2719                        /*
2720                         * If the system app is both scanned and in the
2721                         * disabled packages list, then it must have been
2722                         * added via OTA. Remove it from the currently
2723                         * scanned package so the previously user-installed
2724                         * application can be scanned.
2725                         */
2726                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2727                            logCriticalInfo(Log.WARN,
2728                                    "Expecting better updated system app for " + ps.name
2729                                    + "; removing system app.  Last known"
2730                                    + " codePath=" + ps.codePathString
2731                                    + ", versionCode=" + ps.versionCode
2732                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2733                            removePackageLI(scannedPkg, true);
2734                            mExpectingBetter.put(ps.name, ps.codePath);
2735                        }
2736
2737                        continue;
2738                    }
2739
2740                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2741                        psit.remove();
2742                        logCriticalInfo(Log.WARN, "System package " + ps.name
2743                                + " no longer exists; it's data will be wiped");
2744                        // Actual deletion of code and data will be handled by later
2745                        // reconciliation step
2746                    } else {
2747                        // we still have a disabled system package, but, it still might have
2748                        // been removed. check the code path still exists and check there's
2749                        // still a package. the latter can happen if an OTA keeps the same
2750                        // code path, but, changes the package name.
2751                        final PackageSetting disabledPs =
2752                                mSettings.getDisabledSystemPkgLPr(ps.name);
2753                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2754                                || disabledPs.pkg == null) {
2755                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2756                        }
2757                    }
2758                }
2759            }
2760
2761            //delete tmp files
2762            deleteTempPackageFiles();
2763
2764            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2765
2766            // Remove any shared userIDs that have no associated packages
2767            mSettings.pruneSharedUsersLPw();
2768            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2769            final int systemPackagesCount = mPackages.size();
2770            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2771                    + " ms, packageCount: " + systemPackagesCount
2772                    + " , timePerPackage: "
2773                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2774                    + " , cached: " + cachedSystemApps);
2775            if (mIsUpgrade && systemPackagesCount > 0) {
2776                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2777                        ((int) systemScanTime) / systemPackagesCount);
2778            }
2779            if (!mOnlyCore) {
2780                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2781                        SystemClock.uptimeMillis());
2782                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2783
2784                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2785                        | PackageParser.PARSE_FORWARD_LOCK,
2786                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2787
2788                // Remove disable package settings for updated system apps that were
2789                // removed via an OTA. If the update is no longer present, remove the
2790                // app completely. Otherwise, revoke their system privileges.
2791                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2792                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2793                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2794                    final String msg;
2795                    if (deletedPkg == null) {
2796                        // should have found an update, but, we didn't; remove everything
2797                        msg = "Updated system package " + deletedAppName
2798                                + " no longer exists; removing its data";
2799                        // Actual deletion of code and data will be handled by later
2800                        // reconciliation step
2801                    } else {
2802                        // found an update; revoke system privileges
2803                        msg = "Updated system package + " + deletedAppName
2804                                + " no longer exists; revoking system privileges";
2805
2806                        // Don't do anything if a stub is removed from the system image. If
2807                        // we were to remove the uncompressed version from the /data partition,
2808                        // this is where it'd be done.
2809
2810                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2811                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2812                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2813                    }
2814                    logCriticalInfo(Log.WARN, msg);
2815                }
2816
2817                /*
2818                 * Make sure all system apps that we expected to appear on
2819                 * the userdata partition actually showed up. If they never
2820                 * appeared, crawl back and revive the system version.
2821                 */
2822                for (int i = 0; i < mExpectingBetter.size(); i++) {
2823                    final String packageName = mExpectingBetter.keyAt(i);
2824                    if (!mPackages.containsKey(packageName)) {
2825                        final File scanFile = mExpectingBetter.valueAt(i);
2826
2827                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2828                                + " but never showed up; reverting to system");
2829
2830                        final @ParseFlags int reparseFlags;
2831                        final @ScanFlags int rescanFlags;
2832                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2833                            reparseFlags =
2834                                    mDefParseFlags |
2835                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2836                            rescanFlags =
2837                                    scanFlags
2838                                    | SCAN_AS_SYSTEM
2839                                    | SCAN_AS_PRIVILEGED;
2840                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2841                            reparseFlags =
2842                                    mDefParseFlags |
2843                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2844                            rescanFlags =
2845                                    scanFlags
2846                                    | SCAN_AS_SYSTEM;
2847                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2848                            reparseFlags =
2849                                    mDefParseFlags |
2850                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2851                            rescanFlags =
2852                                    scanFlags
2853                                    | SCAN_AS_SYSTEM
2854                                    | SCAN_AS_VENDOR
2855                                    | SCAN_AS_PRIVILEGED;
2856                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2857                            reparseFlags =
2858                                    mDefParseFlags |
2859                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2860                            rescanFlags =
2861                                    scanFlags
2862                                    | SCAN_AS_SYSTEM
2863                                    | SCAN_AS_VENDOR;
2864                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2865                            reparseFlags =
2866                                    mDefParseFlags |
2867                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2868                            rescanFlags =
2869                                    scanFlags
2870                                    | SCAN_AS_SYSTEM
2871                                    | SCAN_AS_OEM;
2872                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
2873                            reparseFlags =
2874                                    mDefParseFlags |
2875                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2876                            rescanFlags =
2877                                    scanFlags
2878                                    | SCAN_AS_SYSTEM
2879                                    | SCAN_AS_PRODUCT
2880                                    | SCAN_AS_PRIVILEGED;
2881                        } else if (FileUtils.contains(productAppDir, scanFile)) {
2882                            reparseFlags =
2883                                    mDefParseFlags |
2884                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2885                            rescanFlags =
2886                                    scanFlags
2887                                    | SCAN_AS_SYSTEM
2888                                    | SCAN_AS_PRODUCT;
2889                        } else {
2890                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2891                            continue;
2892                        }
2893
2894                        mSettings.enableSystemPackageLPw(packageName);
2895
2896                        try {
2897                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2898                        } catch (PackageManagerException e) {
2899                            Slog.e(TAG, "Failed to parse original system package: "
2900                                    + e.getMessage());
2901                        }
2902                    }
2903                }
2904
2905                // Uncompress and install any stubbed system applications.
2906                // This must be done last to ensure all stubs are replaced or disabled.
2907                decompressSystemApplications(stubSystemApps, scanFlags);
2908
2909                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2910                                - cachedSystemApps;
2911
2912                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2913                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2914                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2915                        + " ms, packageCount: " + dataPackagesCount
2916                        + " , timePerPackage: "
2917                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2918                        + " , cached: " + cachedNonSystemApps);
2919                if (mIsUpgrade && dataPackagesCount > 0) {
2920                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2921                            ((int) dataScanTime) / dataPackagesCount);
2922                }
2923            }
2924            mExpectingBetter.clear();
2925
2926            // Resolve the storage manager.
2927            mStorageManagerPackage = getStorageManagerPackageName();
2928
2929            // Resolve protected action filters. Only the setup wizard is allowed to
2930            // have a high priority filter for these actions.
2931            mSetupWizardPackage = getSetupWizardPackageName();
2932            if (mProtectedFilters.size() > 0) {
2933                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2934                    Slog.i(TAG, "No setup wizard;"
2935                        + " All protected intents capped to priority 0");
2936                }
2937                for (ActivityIntentInfo filter : mProtectedFilters) {
2938                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2939                        if (DEBUG_FILTERS) {
2940                            Slog.i(TAG, "Found setup wizard;"
2941                                + " allow priority " + filter.getPriority() + ";"
2942                                + " package: " + filter.activity.info.packageName
2943                                + " activity: " + filter.activity.className
2944                                + " priority: " + filter.getPriority());
2945                        }
2946                        // skip setup wizard; allow it to keep the high priority filter
2947                        continue;
2948                    }
2949                    if (DEBUG_FILTERS) {
2950                        Slog.i(TAG, "Protected action; cap priority to 0;"
2951                                + " package: " + filter.activity.info.packageName
2952                                + " activity: " + filter.activity.className
2953                                + " origPrio: " + filter.getPriority());
2954                    }
2955                    filter.setPriority(0);
2956                }
2957            }
2958
2959            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
2960
2961            mDeferProtectedFilters = false;
2962            mProtectedFilters.clear();
2963
2964            // Now that we know all of the shared libraries, update all clients to have
2965            // the correct library paths.
2966            updateAllSharedLibrariesLPw(null);
2967
2968            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2969                // NOTE: We ignore potential failures here during a system scan (like
2970                // the rest of the commands above) because there's precious little we
2971                // can do about it. A settings error is reported, though.
2972                final List<String> changedAbiCodePath =
2973                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2974                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
2975                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
2976                        final String codePathString = changedAbiCodePath.get(i);
2977                        try {
2978                            mInstaller.rmdex(codePathString,
2979                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
2980                        } catch (InstallerException ignored) {
2981                        }
2982                    }
2983                }
2984                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
2985                // SELinux domain.
2986                setting.fixSeInfoLocked();
2987            }
2988
2989            // Now that we know all the packages we are keeping,
2990            // read and update their last usage times.
2991            mPackageUsage.read(mPackages);
2992            mCompilerStats.read();
2993
2994            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2995                    SystemClock.uptimeMillis());
2996            Slog.i(TAG, "Time to scan packages: "
2997                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2998                    + " seconds");
2999
3000            // If the platform SDK has changed since the last time we booted,
3001            // we need to re-grant app permission to catch any new ones that
3002            // appear.  This is really a hack, and means that apps can in some
3003            // cases get permissions that the user didn't initially explicitly
3004            // allow...  it would be nice to have some better way to handle
3005            // this situation.
3006            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3007            if (sdkUpdated) {
3008                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3009                        + mSdkVersion + "; regranting permissions for internal storage");
3010            }
3011            mPermissionManager.updateAllPermissions(
3012                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3013                    mPermissionCallback);
3014            ver.sdkVersion = mSdkVersion;
3015
3016            // If this is the first boot or an update from pre-M, and it is a normal
3017            // boot, then we need to initialize the default preferred apps across
3018            // all defined users.
3019            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3020                for (UserInfo user : sUserManager.getUsers(true)) {
3021                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
3022                    applyFactoryDefaultBrowserLPw(user.id);
3023                    primeDomainVerificationsLPw(user.id);
3024                }
3025            }
3026
3027            // Prepare storage for system user really early during boot,
3028            // since core system apps like SettingsProvider and SystemUI
3029            // can't wait for user to start
3030            final int storageFlags;
3031            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3032                storageFlags = StorageManager.FLAG_STORAGE_DE;
3033            } else {
3034                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3035            }
3036            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3037                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3038                    true /* onlyCoreApps */);
3039            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3040                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3041                        Trace.TRACE_TAG_PACKAGE_MANAGER);
3042                traceLog.traceBegin("AppDataFixup");
3043                try {
3044                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3045                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3046                } catch (InstallerException e) {
3047                    Slog.w(TAG, "Trouble fixing GIDs", e);
3048                }
3049                traceLog.traceEnd();
3050
3051                traceLog.traceBegin("AppDataPrepare");
3052                if (deferPackages == null || deferPackages.isEmpty()) {
3053                    return;
3054                }
3055                int count = 0;
3056                for (String pkgName : deferPackages) {
3057                    PackageParser.Package pkg = null;
3058                    synchronized (mPackages) {
3059                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
3060                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3061                            pkg = ps.pkg;
3062                        }
3063                    }
3064                    if (pkg != null) {
3065                        synchronized (mInstallLock) {
3066                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3067                                    true /* maybeMigrateAppData */);
3068                        }
3069                        count++;
3070                    }
3071                }
3072                traceLog.traceEnd();
3073                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3074            }, "prepareAppData");
3075
3076            // If this is first boot after an OTA, and a normal boot, then
3077            // we need to clear code cache directories.
3078            // Note that we do *not* clear the application profiles. These remain valid
3079            // across OTAs and are used to drive profile verification (post OTA) and
3080            // profile compilation (without waiting to collect a fresh set of profiles).
3081            if (mIsUpgrade && !onlyCore) {
3082                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3083                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3084                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3085                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3086                        // No apps are running this early, so no need to freeze
3087                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3088                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3089                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3090                    }
3091                }
3092                ver.fingerprint = Build.FINGERPRINT;
3093            }
3094
3095            checkDefaultBrowser();
3096
3097            // clear only after permissions and other defaults have been updated
3098            mExistingSystemPackages.clear();
3099            mPromoteSystemApps = false;
3100
3101            // All the changes are done during package scanning.
3102            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3103
3104            // can downgrade to reader
3105            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3106            mSettings.writeLPr();
3107            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3108            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3109                    SystemClock.uptimeMillis());
3110
3111            if (!mOnlyCore) {
3112                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3113                mRequiredInstallerPackage = getRequiredInstallerLPr();
3114                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3115                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3116                if (mIntentFilterVerifierComponent != null) {
3117                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3118                            mIntentFilterVerifierComponent);
3119                } else {
3120                    mIntentFilterVerifier = null;
3121                }
3122                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3123                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3124                        SharedLibraryInfo.VERSION_UNDEFINED);
3125                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3126                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3127                        SharedLibraryInfo.VERSION_UNDEFINED);
3128            } else {
3129                mRequiredVerifierPackage = null;
3130                mRequiredInstallerPackage = null;
3131                mRequiredUninstallerPackage = null;
3132                mIntentFilterVerifierComponent = null;
3133                mIntentFilterVerifier = null;
3134                mServicesSystemSharedLibraryPackageName = null;
3135                mSharedSystemSharedLibraryPackageName = null;
3136            }
3137
3138            mInstallerService = new PackageInstallerService(context, this);
3139            final Pair<ComponentName, String> instantAppResolverComponent =
3140                    getInstantAppResolverLPr();
3141            if (instantAppResolverComponent != null) {
3142                if (DEBUG_INSTANT) {
3143                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3144                }
3145                mInstantAppResolverConnection = new InstantAppResolverConnection(
3146                        mContext, instantAppResolverComponent.first,
3147                        instantAppResolverComponent.second);
3148                mInstantAppResolverSettingsComponent =
3149                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3150            } else {
3151                mInstantAppResolverConnection = null;
3152                mInstantAppResolverSettingsComponent = null;
3153            }
3154            updateInstantAppInstallerLocked(null);
3155
3156            // Read and update the usage of dex files.
3157            // Do this at the end of PM init so that all the packages have their
3158            // data directory reconciled.
3159            // At this point we know the code paths of the packages, so we can validate
3160            // the disk file and build the internal cache.
3161            // The usage file is expected to be small so loading and verifying it
3162            // should take a fairly small time compare to the other activities (e.g. package
3163            // scanning).
3164            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3165            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3166            for (int userId : currentUserIds) {
3167                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3168            }
3169            mDexManager.load(userPackages);
3170            if (mIsUpgrade) {
3171                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3172                        (int) (SystemClock.uptimeMillis() - startTime));
3173            }
3174        } // synchronized (mPackages)
3175        } // synchronized (mInstallLock)
3176
3177        // Now after opening every single application zip, make sure they
3178        // are all flushed.  Not really needed, but keeps things nice and
3179        // tidy.
3180        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3181        Runtime.getRuntime().gc();
3182        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3183
3184        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3185        FallbackCategoryProvider.loadFallbacks();
3186        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3187
3188        // The initial scanning above does many calls into installd while
3189        // holding the mPackages lock, but we're mostly interested in yelling
3190        // once we have a booted system.
3191        mInstaller.setWarnIfHeld(mPackages);
3192
3193        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3194    }
3195
3196    /**
3197     * Uncompress and install stub applications.
3198     * <p>In order to save space on the system partition, some applications are shipped in a
3199     * compressed form. In addition the compressed bits for the full application, the
3200     * system image contains a tiny stub comprised of only the Android manifest.
3201     * <p>During the first boot, attempt to uncompress and install the full application. If
3202     * the application can't be installed for any reason, disable the stub and prevent
3203     * uncompressing the full application during future boots.
3204     * <p>In order to forcefully attempt an installation of a full application, go to app
3205     * settings and enable the application.
3206     */
3207    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3208        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3209            final String pkgName = stubSystemApps.get(i);
3210            // skip if the system package is already disabled
3211            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3212                stubSystemApps.remove(i);
3213                continue;
3214            }
3215            // skip if the package isn't installed (?!); this should never happen
3216            final PackageParser.Package pkg = mPackages.get(pkgName);
3217            if (pkg == null) {
3218                stubSystemApps.remove(i);
3219                continue;
3220            }
3221            // skip if the package has been disabled by the user
3222            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3223            if (ps != null) {
3224                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3225                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3226                    stubSystemApps.remove(i);
3227                    continue;
3228                }
3229            }
3230
3231            if (DEBUG_COMPRESSION) {
3232                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3233            }
3234
3235            // uncompress the binary to its eventual destination on /data
3236            final File scanFile = decompressPackage(pkg);
3237            if (scanFile == null) {
3238                continue;
3239            }
3240
3241            // install the package to replace the stub on /system
3242            try {
3243                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3244                removePackageLI(pkg, true /*chatty*/);
3245                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3246                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3247                        UserHandle.USER_SYSTEM, "android");
3248                stubSystemApps.remove(i);
3249                continue;
3250            } catch (PackageManagerException e) {
3251                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3252            }
3253
3254            // any failed attempt to install the package will be cleaned up later
3255        }
3256
3257        // disable any stub still left; these failed to install the full application
3258        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3259            final String pkgName = stubSystemApps.get(i);
3260            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3261            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3262                    UserHandle.USER_SYSTEM, "android");
3263            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3264        }
3265    }
3266
3267    /**
3268     * Decompresses the given package on the system image onto
3269     * the /data partition.
3270     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3271     */
3272    private File decompressPackage(PackageParser.Package pkg) {
3273        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3274        if (compressedFiles == null || compressedFiles.length == 0) {
3275            if (DEBUG_COMPRESSION) {
3276                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3277            }
3278            return null;
3279        }
3280        final File dstCodePath =
3281                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3282        int ret = PackageManager.INSTALL_SUCCEEDED;
3283        try {
3284            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3285            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3286            for (File srcFile : compressedFiles) {
3287                final String srcFileName = srcFile.getName();
3288                final String dstFileName = srcFileName.substring(
3289                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3290                final File dstFile = new File(dstCodePath, dstFileName);
3291                ret = decompressFile(srcFile, dstFile);
3292                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3293                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3294                            + "; pkg: " + pkg.packageName
3295                            + ", file: " + dstFileName);
3296                    break;
3297                }
3298            }
3299        } catch (ErrnoException e) {
3300            logCriticalInfo(Log.ERROR, "Failed to decompress"
3301                    + "; pkg: " + pkg.packageName
3302                    + ", err: " + e.errno);
3303        }
3304        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3305            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3306            NativeLibraryHelper.Handle handle = null;
3307            try {
3308                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3309                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3310                        null /*abiOverride*/);
3311            } catch (IOException e) {
3312                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3313                        + "; pkg: " + pkg.packageName);
3314                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3315            } finally {
3316                IoUtils.closeQuietly(handle);
3317            }
3318        }
3319        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3320            if (dstCodePath == null || !dstCodePath.exists()) {
3321                return null;
3322            }
3323            removeCodePathLI(dstCodePath);
3324            return null;
3325        }
3326
3327        return dstCodePath;
3328    }
3329
3330    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3331        // we're only interested in updating the installer appliction when 1) it's not
3332        // already set or 2) the modified package is the installer
3333        if (mInstantAppInstallerActivity != null
3334                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3335                        .equals(modifiedPackage)) {
3336            return;
3337        }
3338        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3339    }
3340
3341    private static File preparePackageParserCache(boolean isUpgrade) {
3342        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3343            return null;
3344        }
3345
3346        // Disable package parsing on eng builds to allow for faster incremental development.
3347        if (Build.IS_ENG) {
3348            return null;
3349        }
3350
3351        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3352            Slog.i(TAG, "Disabling package parser cache due to system property.");
3353            return null;
3354        }
3355
3356        // The base directory for the package parser cache lives under /data/system/.
3357        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3358                "package_cache");
3359        if (cacheBaseDir == null) {
3360            return null;
3361        }
3362
3363        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3364        // This also serves to "GC" unused entries when the package cache version changes (which
3365        // can only happen during upgrades).
3366        if (isUpgrade) {
3367            FileUtils.deleteContents(cacheBaseDir);
3368        }
3369
3370
3371        // Return the versioned package cache directory. This is something like
3372        // "/data/system/package_cache/1"
3373        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3374
3375        // The following is a workaround to aid development on non-numbered userdebug
3376        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3377        // the system partition is newer.
3378        //
3379        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3380        // that starts with "eng." to signify that this is an engineering build and not
3381        // destined for release.
3382        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3383            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3384
3385            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3386            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3387            // in general and should not be used for production changes. In this specific case,
3388            // we know that they will work.
3389            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3390            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3391                FileUtils.deleteContents(cacheBaseDir);
3392                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3393            }
3394        }
3395
3396        return cacheDir;
3397    }
3398
3399    @Override
3400    public boolean isFirstBoot() {
3401        // allow instant applications
3402        return mFirstBoot;
3403    }
3404
3405    @Override
3406    public boolean isOnlyCoreApps() {
3407        // allow instant applications
3408        return mOnlyCore;
3409    }
3410
3411    @Override
3412    public boolean isUpgrade() {
3413        // allow instant applications
3414        // The system property allows testing ota flow when upgraded to the same image.
3415        return mIsUpgrade || SystemProperties.getBoolean(
3416                "persist.pm.mock-upgrade", false /* default */);
3417    }
3418
3419    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3420        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3421
3422        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3423                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3424                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3425        if (matches.size() == 1) {
3426            return matches.get(0).getComponentInfo().packageName;
3427        } else if (matches.size() == 0) {
3428            Log.e(TAG, "There should probably be a verifier, but, none were found");
3429            return null;
3430        }
3431        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3432    }
3433
3434    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3435        synchronized (mPackages) {
3436            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3437            if (libraryEntry == null) {
3438                throw new IllegalStateException("Missing required shared library:" + name);
3439            }
3440            return libraryEntry.apk;
3441        }
3442    }
3443
3444    private @NonNull String getRequiredInstallerLPr() {
3445        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3446        intent.addCategory(Intent.CATEGORY_DEFAULT);
3447        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3448
3449        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3450                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3451                UserHandle.USER_SYSTEM);
3452        if (matches.size() == 1) {
3453            ResolveInfo resolveInfo = matches.get(0);
3454            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3455                throw new RuntimeException("The installer must be a privileged app");
3456            }
3457            return matches.get(0).getComponentInfo().packageName;
3458        } else {
3459            throw new RuntimeException("There must be exactly one installer; found " + matches);
3460        }
3461    }
3462
3463    private @NonNull String getRequiredUninstallerLPr() {
3464        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3465        intent.addCategory(Intent.CATEGORY_DEFAULT);
3466        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3467
3468        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3469                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3470                UserHandle.USER_SYSTEM);
3471        if (resolveInfo == null ||
3472                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3473            throw new RuntimeException("There must be exactly one uninstaller; found "
3474                    + resolveInfo);
3475        }
3476        return resolveInfo.getComponentInfo().packageName;
3477    }
3478
3479    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3480        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3481
3482        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3483                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3484                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3485        ResolveInfo best = null;
3486        final int N = matches.size();
3487        for (int i = 0; i < N; i++) {
3488            final ResolveInfo cur = matches.get(i);
3489            final String packageName = cur.getComponentInfo().packageName;
3490            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3491                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3492                continue;
3493            }
3494
3495            if (best == null || cur.priority > best.priority) {
3496                best = cur;
3497            }
3498        }
3499
3500        if (best != null) {
3501            return best.getComponentInfo().getComponentName();
3502        }
3503        Slog.w(TAG, "Intent filter verifier not found");
3504        return null;
3505    }
3506
3507    @Override
3508    public @Nullable ComponentName getInstantAppResolverComponent() {
3509        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3510            return null;
3511        }
3512        synchronized (mPackages) {
3513            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3514            if (instantAppResolver == null) {
3515                return null;
3516            }
3517            return instantAppResolver.first;
3518        }
3519    }
3520
3521    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3522        final String[] packageArray =
3523                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3524        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3525            if (DEBUG_INSTANT) {
3526                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3527            }
3528            return null;
3529        }
3530
3531        final int callingUid = Binder.getCallingUid();
3532        final int resolveFlags =
3533                MATCH_DIRECT_BOOT_AWARE
3534                | MATCH_DIRECT_BOOT_UNAWARE
3535                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3536        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3537        final Intent resolverIntent = new Intent(actionName);
3538        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3539                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3540        final int N = resolvers.size();
3541        if (N == 0) {
3542            if (DEBUG_INSTANT) {
3543                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3544            }
3545            return null;
3546        }
3547
3548        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3549        for (int i = 0; i < N; i++) {
3550            final ResolveInfo info = resolvers.get(i);
3551
3552            if (info.serviceInfo == null) {
3553                continue;
3554            }
3555
3556            final String packageName = info.serviceInfo.packageName;
3557            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3558                if (DEBUG_INSTANT) {
3559                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3560                            + " pkg: " + packageName + ", info:" + info);
3561                }
3562                continue;
3563            }
3564
3565            if (DEBUG_INSTANT) {
3566                Slog.v(TAG, "Ephemeral resolver found;"
3567                        + " pkg: " + packageName + ", info:" + info);
3568            }
3569            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3570        }
3571        if (DEBUG_INSTANT) {
3572            Slog.v(TAG, "Ephemeral resolver NOT found");
3573        }
3574        return null;
3575    }
3576
3577    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3578        String[] orderedActions = Build.IS_ENG
3579                ? new String[]{
3580                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3581                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3582                : new String[]{
3583                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3584
3585        final int resolveFlags =
3586                MATCH_DIRECT_BOOT_AWARE
3587                        | MATCH_DIRECT_BOOT_UNAWARE
3588                        | Intent.FLAG_IGNORE_EPHEMERAL
3589                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3590        final Intent intent = new Intent();
3591        intent.addCategory(Intent.CATEGORY_DEFAULT);
3592        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3593        List<ResolveInfo> matches = null;
3594        for (String action : orderedActions) {
3595            intent.setAction(action);
3596            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3597                    resolveFlags, UserHandle.USER_SYSTEM);
3598            if (matches.isEmpty()) {
3599                if (DEBUG_INSTANT) {
3600                    Slog.d(TAG, "Instant App installer not found with " + action);
3601                }
3602            } else {
3603                break;
3604            }
3605        }
3606        Iterator<ResolveInfo> iter = matches.iterator();
3607        while (iter.hasNext()) {
3608            final ResolveInfo rInfo = iter.next();
3609            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3610            if (ps != null) {
3611                final PermissionsState permissionsState = ps.getPermissionsState();
3612                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3613                        || Build.IS_ENG) {
3614                    continue;
3615                }
3616            }
3617            iter.remove();
3618        }
3619        if (matches.size() == 0) {
3620            return null;
3621        } else if (matches.size() == 1) {
3622            return (ActivityInfo) matches.get(0).getComponentInfo();
3623        } else {
3624            throw new RuntimeException(
3625                    "There must be at most one ephemeral installer; found " + matches);
3626        }
3627    }
3628
3629    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3630            @NonNull ComponentName resolver) {
3631        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3632                .addCategory(Intent.CATEGORY_DEFAULT)
3633                .setPackage(resolver.getPackageName());
3634        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3635        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3636                UserHandle.USER_SYSTEM);
3637        if (matches.isEmpty()) {
3638            return null;
3639        }
3640        return matches.get(0).getComponentInfo().getComponentName();
3641    }
3642
3643    private void primeDomainVerificationsLPw(int userId) {
3644        if (DEBUG_DOMAIN_VERIFICATION) {
3645            Slog.d(TAG, "Priming domain verifications in user " + userId);
3646        }
3647
3648        SystemConfig systemConfig = SystemConfig.getInstance();
3649        ArraySet<String> packages = systemConfig.getLinkedApps();
3650
3651        for (String packageName : packages) {
3652            PackageParser.Package pkg = mPackages.get(packageName);
3653            if (pkg != null) {
3654                if (!pkg.isSystem()) {
3655                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3656                    continue;
3657                }
3658
3659                ArraySet<String> domains = null;
3660                for (PackageParser.Activity a : pkg.activities) {
3661                    for (ActivityIntentInfo filter : a.intents) {
3662                        if (hasValidDomains(filter)) {
3663                            if (domains == null) {
3664                                domains = new ArraySet<String>();
3665                            }
3666                            domains.addAll(filter.getHostsList());
3667                        }
3668                    }
3669                }
3670
3671                if (domains != null && domains.size() > 0) {
3672                    if (DEBUG_DOMAIN_VERIFICATION) {
3673                        Slog.v(TAG, "      + " + packageName);
3674                    }
3675                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3676                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3677                    // and then 'always' in the per-user state actually used for intent resolution.
3678                    final IntentFilterVerificationInfo ivi;
3679                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3680                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3681                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3682                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3683                } else {
3684                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3685                            + "' does not handle web links");
3686                }
3687            } else {
3688                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3689            }
3690        }
3691
3692        scheduleWritePackageRestrictionsLocked(userId);
3693        scheduleWriteSettingsLocked();
3694    }
3695
3696    private void applyFactoryDefaultBrowserLPw(int userId) {
3697        // The default browser app's package name is stored in a string resource,
3698        // with a product-specific overlay used for vendor customization.
3699        String browserPkg = mContext.getResources().getString(
3700                com.android.internal.R.string.default_browser);
3701        if (!TextUtils.isEmpty(browserPkg)) {
3702            // non-empty string => required to be a known package
3703            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3704            if (ps == null) {
3705                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3706                browserPkg = null;
3707            } else {
3708                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3709            }
3710        }
3711
3712        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3713        // default.  If there's more than one, just leave everything alone.
3714        if (browserPkg == null) {
3715            calculateDefaultBrowserLPw(userId);
3716        }
3717    }
3718
3719    private void calculateDefaultBrowserLPw(int userId) {
3720        List<String> allBrowsers = resolveAllBrowserApps(userId);
3721        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3722        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3723    }
3724
3725    private List<String> resolveAllBrowserApps(int userId) {
3726        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3727        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3728                PackageManager.MATCH_ALL, userId);
3729
3730        final int count = list.size();
3731        List<String> result = new ArrayList<String>(count);
3732        for (int i=0; i<count; i++) {
3733            ResolveInfo info = list.get(i);
3734            if (info.activityInfo == null
3735                    || !info.handleAllWebDataURI
3736                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3737                    || result.contains(info.activityInfo.packageName)) {
3738                continue;
3739            }
3740            result.add(info.activityInfo.packageName);
3741        }
3742
3743        return result;
3744    }
3745
3746    private boolean packageIsBrowser(String packageName, int userId) {
3747        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3748                PackageManager.MATCH_ALL, userId);
3749        final int N = list.size();
3750        for (int i = 0; i < N; i++) {
3751            ResolveInfo info = list.get(i);
3752            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3753                return true;
3754            }
3755        }
3756        return false;
3757    }
3758
3759    private void checkDefaultBrowser() {
3760        final int myUserId = UserHandle.myUserId();
3761        final String packageName = getDefaultBrowserPackageName(myUserId);
3762        if (packageName != null) {
3763            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3764            if (info == null) {
3765                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3766                synchronized (mPackages) {
3767                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3768                }
3769            }
3770        }
3771    }
3772
3773    @Override
3774    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3775            throws RemoteException {
3776        try {
3777            return super.onTransact(code, data, reply, flags);
3778        } catch (RuntimeException e) {
3779            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3780                Slog.wtf(TAG, "Package Manager Crash", e);
3781            }
3782            throw e;
3783        }
3784    }
3785
3786    static int[] appendInts(int[] cur, int[] add) {
3787        if (add == null) return cur;
3788        if (cur == null) return add;
3789        final int N = add.length;
3790        for (int i=0; i<N; i++) {
3791            cur = appendInt(cur, add[i]);
3792        }
3793        return cur;
3794    }
3795
3796    /**
3797     * Returns whether or not a full application can see an instant application.
3798     * <p>
3799     * Currently, there are three cases in which this can occur:
3800     * <ol>
3801     * <li>The calling application is a "special" process. Special processes
3802     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3803     * <li>The calling application has the permission
3804     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3805     * <li>The calling application is the default launcher on the
3806     *     system partition.</li>
3807     * </ol>
3808     */
3809    private boolean canViewInstantApps(int callingUid, int userId) {
3810        if (callingUid < Process.FIRST_APPLICATION_UID) {
3811            return true;
3812        }
3813        if (mContext.checkCallingOrSelfPermission(
3814                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3815            return true;
3816        }
3817        if (mContext.checkCallingOrSelfPermission(
3818                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3819            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3820            if (homeComponent != null
3821                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3822                return true;
3823            }
3824        }
3825        return false;
3826    }
3827
3828    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3829        if (!sUserManager.exists(userId)) return null;
3830        if (ps == null) {
3831            return null;
3832        }
3833        final int callingUid = Binder.getCallingUid();
3834        // Filter out ephemeral app metadata:
3835        //   * The system/shell/root can see metadata for any app
3836        //   * An installed app can see metadata for 1) other installed apps
3837        //     and 2) ephemeral apps that have explicitly interacted with it
3838        //   * Ephemeral apps can only see their own data and exposed installed apps
3839        //   * Holding a signature permission allows seeing instant apps
3840        if (filterAppAccessLPr(ps, callingUid, userId)) {
3841            return null;
3842        }
3843
3844        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3845                && ps.isSystem()) {
3846            flags |= MATCH_ANY_USER;
3847        }
3848
3849        final PackageUserState state = ps.readUserState(userId);
3850        PackageParser.Package p = ps.pkg;
3851        if (p != null) {
3852            final PermissionsState permissionsState = ps.getPermissionsState();
3853
3854            // Compute GIDs only if requested
3855            final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3856                    ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3857            // Compute granted permissions only if package has requested permissions
3858            final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3859                    ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3860
3861            PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3862                    ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3863
3864            if (packageInfo == null) {
3865                return null;
3866            }
3867
3868            packageInfo.packageName = packageInfo.applicationInfo.packageName =
3869                    resolveExternalPackageNameLPr(p);
3870
3871            return packageInfo;
3872        } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3873            PackageInfo pi = new PackageInfo();
3874            pi.packageName = ps.name;
3875            pi.setLongVersionCode(ps.versionCode);
3876            pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3877            pi.firstInstallTime = ps.firstInstallTime;
3878            pi.lastUpdateTime = ps.lastUpdateTime;
3879
3880            ApplicationInfo ai = new ApplicationInfo();
3881            ai.packageName = ps.name;
3882            ai.uid = UserHandle.getUid(userId, ps.appId);
3883            ai.primaryCpuAbi = ps.primaryCpuAbiString;
3884            ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3885            ai.versionCode = ps.versionCode;
3886            ai.flags = ps.pkgFlags;
3887            ai.privateFlags = ps.pkgPrivateFlags;
3888            pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
3889
3890            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3891                    + ps.name + "]. Provides a minimum info.");
3892            return pi;
3893        } else {
3894            return null;
3895        }
3896    }
3897
3898    @Override
3899    public void checkPackageStartable(String packageName, int userId) {
3900        final int callingUid = Binder.getCallingUid();
3901        if (getInstantAppPackageName(callingUid) != null) {
3902            throw new SecurityException("Instant applications don't have access to this method");
3903        }
3904        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3905        synchronized (mPackages) {
3906            final PackageSetting ps = mSettings.mPackages.get(packageName);
3907            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3908                throw new SecurityException("Package " + packageName + " was not found!");
3909            }
3910
3911            if (!ps.getInstalled(userId)) {
3912                throw new SecurityException(
3913                        "Package " + packageName + " was not installed for user " + userId + "!");
3914            }
3915
3916            if (mSafeMode && !ps.isSystem()) {
3917                throw new SecurityException("Package " + packageName + " not a system app!");
3918            }
3919
3920            if (mFrozenPackages.contains(packageName)) {
3921                throw new SecurityException("Package " + packageName + " is currently frozen!");
3922            }
3923
3924            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3925                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3926            }
3927        }
3928    }
3929
3930    @Override
3931    public boolean isPackageAvailable(String packageName, int userId) {
3932        if (!sUserManager.exists(userId)) return false;
3933        final int callingUid = Binder.getCallingUid();
3934        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3935                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3936        synchronized (mPackages) {
3937            PackageParser.Package p = mPackages.get(packageName);
3938            if (p != null) {
3939                final PackageSetting ps = (PackageSetting) p.mExtras;
3940                if (filterAppAccessLPr(ps, callingUid, userId)) {
3941                    return false;
3942                }
3943                if (ps != null) {
3944                    final PackageUserState state = ps.readUserState(userId);
3945                    if (state != null) {
3946                        return PackageParser.isAvailable(state);
3947                    }
3948                }
3949            }
3950        }
3951        return false;
3952    }
3953
3954    @Override
3955    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3956        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3957                flags, Binder.getCallingUid(), userId);
3958    }
3959
3960    @Override
3961    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3962            int flags, int userId) {
3963        return getPackageInfoInternal(versionedPackage.getPackageName(),
3964                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3965    }
3966
3967    /**
3968     * Important: The provided filterCallingUid is used exclusively to filter out packages
3969     * that can be seen based on user state. It's typically the original caller uid prior
3970     * to clearing. Because it can only be provided by trusted code, it's value can be
3971     * trusted and will be used as-is; unlike userId which will be validated by this method.
3972     */
3973    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3974            int flags, int filterCallingUid, int userId) {
3975        if (!sUserManager.exists(userId)) return null;
3976        flags = updateFlagsForPackage(flags, userId, packageName);
3977        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
3978                false /* requireFullPermission */, false /* checkShell */, "get package info");
3979
3980        // reader
3981        synchronized (mPackages) {
3982            // Normalize package name to handle renamed packages and static libs
3983            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3984
3985            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3986            if (matchFactoryOnly) {
3987                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3988                if (ps != null) {
3989                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3990                        return null;
3991                    }
3992                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3993                        return null;
3994                    }
3995                    return generatePackageInfo(ps, flags, userId);
3996                }
3997            }
3998
3999            PackageParser.Package p = mPackages.get(packageName);
4000            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4001                return null;
4002            }
4003            if (DEBUG_PACKAGE_INFO)
4004                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4005            if (p != null) {
4006                final PackageSetting ps = (PackageSetting) p.mExtras;
4007                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4008                    return null;
4009                }
4010                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4011                    return null;
4012                }
4013                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4014            }
4015            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4016                final PackageSetting ps = mSettings.mPackages.get(packageName);
4017                if (ps == null) return null;
4018                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4019                    return null;
4020                }
4021                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4022                    return null;
4023                }
4024                return generatePackageInfo(ps, flags, userId);
4025            }
4026        }
4027        return null;
4028    }
4029
4030    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4031        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4032            return true;
4033        }
4034        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4035            return true;
4036        }
4037        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4038            return true;
4039        }
4040        return false;
4041    }
4042
4043    private boolean isComponentVisibleToInstantApp(
4044            @Nullable ComponentName component, @ComponentType int type) {
4045        if (type == TYPE_ACTIVITY) {
4046            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4047            return activity != null
4048                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4049                    : false;
4050        } else if (type == TYPE_RECEIVER) {
4051            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4052            return activity != null
4053                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4054                    : false;
4055        } else if (type == TYPE_SERVICE) {
4056            final PackageParser.Service service = mServices.mServices.get(component);
4057            return service != null
4058                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4059                    : false;
4060        } else if (type == TYPE_PROVIDER) {
4061            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4062            return provider != null
4063                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4064                    : false;
4065        } else if (type == TYPE_UNKNOWN) {
4066            return isComponentVisibleToInstantApp(component);
4067        }
4068        return false;
4069    }
4070
4071    /**
4072     * Returns whether or not access to the application should be filtered.
4073     * <p>
4074     * Access may be limited based upon whether the calling or target applications
4075     * are instant applications.
4076     *
4077     * @see #canAccessInstantApps(int)
4078     */
4079    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4080            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4081        // if we're in an isolated process, get the real calling UID
4082        if (Process.isIsolated(callingUid)) {
4083            callingUid = mIsolatedOwners.get(callingUid);
4084        }
4085        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4086        final boolean callerIsInstantApp = instantAppPkgName != null;
4087        if (ps == null) {
4088            if (callerIsInstantApp) {
4089                // pretend the application exists, but, needs to be filtered
4090                return true;
4091            }
4092            return false;
4093        }
4094        // if the target and caller are the same application, don't filter
4095        if (isCallerSameApp(ps.name, callingUid)) {
4096            return false;
4097        }
4098        if (callerIsInstantApp) {
4099            // request for a specific component; if it hasn't been explicitly exposed through
4100            // property or instrumentation target, filter
4101            if (component != null) {
4102                final PackageParser.Instrumentation instrumentation =
4103                        mInstrumentation.get(component);
4104                if (instrumentation != null
4105                        && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4106                    return false;
4107                }
4108                return !isComponentVisibleToInstantApp(component, componentType);
4109            }
4110            // request for application; if no components have been explicitly exposed, filter
4111            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4112        }
4113        if (ps.getInstantApp(userId)) {
4114            // caller can see all components of all instant applications, don't filter
4115            if (canViewInstantApps(callingUid, userId)) {
4116                return false;
4117            }
4118            // request for a specific instant application component, filter
4119            if (component != null) {
4120                return true;
4121            }
4122            // request for an instant application; if the caller hasn't been granted access, filter
4123            return !mInstantAppRegistry.isInstantAccessGranted(
4124                    userId, UserHandle.getAppId(callingUid), ps.appId);
4125        }
4126        return false;
4127    }
4128
4129    /**
4130     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4131     */
4132    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4133        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4134    }
4135
4136    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4137            int flags) {
4138        // Callers can access only the libs they depend on, otherwise they need to explicitly
4139        // ask for the shared libraries given the caller is allowed to access all static libs.
4140        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4141            // System/shell/root get to see all static libs
4142            final int appId = UserHandle.getAppId(uid);
4143            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4144                    || appId == Process.ROOT_UID) {
4145                return false;
4146            }
4147        }
4148
4149        // No package means no static lib as it is always on internal storage
4150        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4151            return false;
4152        }
4153
4154        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4155                ps.pkg.staticSharedLibVersion);
4156        if (libEntry == null) {
4157            return false;
4158        }
4159
4160        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4161        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4162        if (uidPackageNames == null) {
4163            return true;
4164        }
4165
4166        for (String uidPackageName : uidPackageNames) {
4167            if (ps.name.equals(uidPackageName)) {
4168                return false;
4169            }
4170            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4171            if (uidPs != null) {
4172                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4173                        libEntry.info.getName());
4174                if (index < 0) {
4175                    continue;
4176                }
4177                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4178                    return false;
4179                }
4180            }
4181        }
4182        return true;
4183    }
4184
4185    @Override
4186    public String[] currentToCanonicalPackageNames(String[] names) {
4187        final int callingUid = Binder.getCallingUid();
4188        if (getInstantAppPackageName(callingUid) != null) {
4189            return names;
4190        }
4191        final String[] out = new String[names.length];
4192        // reader
4193        synchronized (mPackages) {
4194            final int callingUserId = UserHandle.getUserId(callingUid);
4195            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4196            for (int i=names.length-1; i>=0; i--) {
4197                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4198                boolean translateName = false;
4199                if (ps != null && ps.realName != null) {
4200                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4201                    translateName = !targetIsInstantApp
4202                            || canViewInstantApps
4203                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4204                                    UserHandle.getAppId(callingUid), ps.appId);
4205                }
4206                out[i] = translateName ? ps.realName : names[i];
4207            }
4208        }
4209        return out;
4210    }
4211
4212    @Override
4213    public String[] canonicalToCurrentPackageNames(String[] names) {
4214        final int callingUid = Binder.getCallingUid();
4215        if (getInstantAppPackageName(callingUid) != null) {
4216            return names;
4217        }
4218        final String[] out = new String[names.length];
4219        // reader
4220        synchronized (mPackages) {
4221            final int callingUserId = UserHandle.getUserId(callingUid);
4222            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4223            for (int i=names.length-1; i>=0; i--) {
4224                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4225                boolean translateName = false;
4226                if (cur != null) {
4227                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4228                    final boolean targetIsInstantApp =
4229                            ps != null && ps.getInstantApp(callingUserId);
4230                    translateName = !targetIsInstantApp
4231                            || canViewInstantApps
4232                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4233                                    UserHandle.getAppId(callingUid), ps.appId);
4234                }
4235                out[i] = translateName ? cur : names[i];
4236            }
4237        }
4238        return out;
4239    }
4240
4241    @Override
4242    public int getPackageUid(String packageName, int flags, int userId) {
4243        if (!sUserManager.exists(userId)) return -1;
4244        final int callingUid = Binder.getCallingUid();
4245        flags = updateFlagsForPackage(flags, userId, packageName);
4246        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4247                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4248
4249        // reader
4250        synchronized (mPackages) {
4251            final PackageParser.Package p = mPackages.get(packageName);
4252            if (p != null && p.isMatch(flags)) {
4253                PackageSetting ps = (PackageSetting) p.mExtras;
4254                if (filterAppAccessLPr(ps, callingUid, userId)) {
4255                    return -1;
4256                }
4257                return UserHandle.getUid(userId, p.applicationInfo.uid);
4258            }
4259            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4260                final PackageSetting ps = mSettings.mPackages.get(packageName);
4261                if (ps != null && ps.isMatch(flags)
4262                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4263                    return UserHandle.getUid(userId, ps.appId);
4264                }
4265            }
4266        }
4267
4268        return -1;
4269    }
4270
4271    @Override
4272    public int[] getPackageGids(String packageName, int flags, int userId) {
4273        if (!sUserManager.exists(userId)) return null;
4274        final int callingUid = Binder.getCallingUid();
4275        flags = updateFlagsForPackage(flags, userId, packageName);
4276        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4277                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4278
4279        // reader
4280        synchronized (mPackages) {
4281            final PackageParser.Package p = mPackages.get(packageName);
4282            if (p != null && p.isMatch(flags)) {
4283                PackageSetting ps = (PackageSetting) p.mExtras;
4284                if (filterAppAccessLPr(ps, callingUid, userId)) {
4285                    return null;
4286                }
4287                // TODO: Shouldn't this be checking for package installed state for userId and
4288                // return null?
4289                return ps.getPermissionsState().computeGids(userId);
4290            }
4291            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4292                final PackageSetting ps = mSettings.mPackages.get(packageName);
4293                if (ps != null && ps.isMatch(flags)
4294                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4295                    return ps.getPermissionsState().computeGids(userId);
4296                }
4297            }
4298        }
4299
4300        return null;
4301    }
4302
4303    @Override
4304    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4305        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4306    }
4307
4308    @Override
4309    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4310            int flags) {
4311        final List<PermissionInfo> permissionList =
4312                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4313        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4314    }
4315
4316    @Override
4317    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4318        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4319    }
4320
4321    @Override
4322    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4323        final List<PermissionGroupInfo> permissionList =
4324                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4325        return (permissionList == null)
4326                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4327    }
4328
4329    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4330            int filterCallingUid, int userId) {
4331        if (!sUserManager.exists(userId)) return null;
4332        PackageSetting ps = mSettings.mPackages.get(packageName);
4333        if (ps != null) {
4334            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4335                return null;
4336            }
4337            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4338                return null;
4339            }
4340            if (ps.pkg == null) {
4341                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4342                if (pInfo != null) {
4343                    return pInfo.applicationInfo;
4344                }
4345                return null;
4346            }
4347            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4348                    ps.readUserState(userId), userId);
4349            if (ai != null) {
4350                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4351            }
4352            return ai;
4353        }
4354        return null;
4355    }
4356
4357    @Override
4358    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4359        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4360    }
4361
4362    /**
4363     * Important: The provided filterCallingUid is used exclusively to filter out applications
4364     * that can be seen based on user state. It's typically the original caller uid prior
4365     * to clearing. Because it can only be provided by trusted code, it's value can be
4366     * trusted and will be used as-is; unlike userId which will be validated by this method.
4367     */
4368    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4369            int filterCallingUid, int userId) {
4370        if (!sUserManager.exists(userId)) return null;
4371        flags = updateFlagsForApplication(flags, userId, packageName);
4372        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4373                false /* requireFullPermission */, false /* checkShell */, "get application info");
4374
4375        // writer
4376        synchronized (mPackages) {
4377            // Normalize package name to handle renamed packages and static libs
4378            packageName = resolveInternalPackageNameLPr(packageName,
4379                    PackageManager.VERSION_CODE_HIGHEST);
4380
4381            PackageParser.Package p = mPackages.get(packageName);
4382            if (DEBUG_PACKAGE_INFO) Log.v(
4383                    TAG, "getApplicationInfo " + packageName
4384                    + ": " + p);
4385            if (p != null) {
4386                PackageSetting ps = mSettings.mPackages.get(packageName);
4387                if (ps == null) return null;
4388                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4389                    return null;
4390                }
4391                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4392                    return null;
4393                }
4394                // Note: isEnabledLP() does not apply here - always return info
4395                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4396                        p, flags, ps.readUserState(userId), userId);
4397                if (ai != null) {
4398                    ai.packageName = resolveExternalPackageNameLPr(p);
4399                }
4400                return ai;
4401            }
4402            if ("android".equals(packageName)||"system".equals(packageName)) {
4403                return mAndroidApplication;
4404            }
4405            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4406                // Already generates the external package name
4407                return generateApplicationInfoFromSettingsLPw(packageName,
4408                        flags, filterCallingUid, userId);
4409            }
4410        }
4411        return null;
4412    }
4413
4414    private String normalizePackageNameLPr(String packageName) {
4415        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4416        return normalizedPackageName != null ? normalizedPackageName : packageName;
4417    }
4418
4419    @Override
4420    public void deletePreloadsFileCache() {
4421        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4422            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4423        }
4424        File dir = Environment.getDataPreloadsFileCacheDirectory();
4425        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4426        FileUtils.deleteContents(dir);
4427    }
4428
4429    @Override
4430    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4431            final int storageFlags, final IPackageDataObserver observer) {
4432        mContext.enforceCallingOrSelfPermission(
4433                android.Manifest.permission.CLEAR_APP_CACHE, null);
4434        mHandler.post(() -> {
4435            boolean success = false;
4436            try {
4437                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4438                success = true;
4439            } catch (IOException e) {
4440                Slog.w(TAG, e);
4441            }
4442            if (observer != null) {
4443                try {
4444                    observer.onRemoveCompleted(null, success);
4445                } catch (RemoteException e) {
4446                    Slog.w(TAG, e);
4447                }
4448            }
4449        });
4450    }
4451
4452    @Override
4453    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4454            final int storageFlags, final IntentSender pi) {
4455        mContext.enforceCallingOrSelfPermission(
4456                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4457        mHandler.post(() -> {
4458            boolean success = false;
4459            try {
4460                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4461                success = true;
4462            } catch (IOException e) {
4463                Slog.w(TAG, e);
4464            }
4465            if (pi != null) {
4466                try {
4467                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4468                } catch (SendIntentException e) {
4469                    Slog.w(TAG, e);
4470                }
4471            }
4472        });
4473    }
4474
4475    /**
4476     * Blocking call to clear various types of cached data across the system
4477     * until the requested bytes are available.
4478     */
4479    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4480        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4481        final File file = storage.findPathForUuid(volumeUuid);
4482        if (file.getUsableSpace() >= bytes) return;
4483
4484        if (ENABLE_FREE_CACHE_V2) {
4485            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4486                    volumeUuid);
4487            final boolean aggressive = (storageFlags
4488                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4489            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4490
4491            // 1. Pre-flight to determine if we have any chance to succeed
4492            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4493            if (internalVolume && (aggressive || SystemProperties
4494                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4495                deletePreloadsFileCache();
4496                if (file.getUsableSpace() >= bytes) return;
4497            }
4498
4499            // 3. Consider parsed APK data (aggressive only)
4500            if (internalVolume && aggressive) {
4501                FileUtils.deleteContents(mCacheDir);
4502                if (file.getUsableSpace() >= bytes) return;
4503            }
4504
4505            // 4. Consider cached app data (above quotas)
4506            try {
4507                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4508                        Installer.FLAG_FREE_CACHE_V2);
4509            } catch (InstallerException ignored) {
4510            }
4511            if (file.getUsableSpace() >= bytes) return;
4512
4513            // 5. Consider shared libraries with refcount=0 and age>min cache period
4514            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4515                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4516                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4517                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4518                return;
4519            }
4520
4521            // 6. Consider dexopt output (aggressive only)
4522            // TODO: Implement
4523
4524            // 7. Consider installed instant apps unused longer than min cache period
4525            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4526                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4527                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4528                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4529                return;
4530            }
4531
4532            // 8. Consider cached app data (below quotas)
4533            try {
4534                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4535                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4536            } catch (InstallerException ignored) {
4537            }
4538            if (file.getUsableSpace() >= bytes) return;
4539
4540            // 9. Consider DropBox entries
4541            // TODO: Implement
4542
4543            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4544            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4545                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4546                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4547                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4548                return;
4549            }
4550        } else {
4551            try {
4552                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4553            } catch (InstallerException ignored) {
4554            }
4555            if (file.getUsableSpace() >= bytes) return;
4556        }
4557
4558        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4559    }
4560
4561    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4562            throws IOException {
4563        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4564        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4565
4566        List<VersionedPackage> packagesToDelete = null;
4567        final long now = System.currentTimeMillis();
4568
4569        synchronized (mPackages) {
4570            final int[] allUsers = sUserManager.getUserIds();
4571            final int libCount = mSharedLibraries.size();
4572            for (int i = 0; i < libCount; i++) {
4573                final LongSparseArray<SharedLibraryEntry> versionedLib
4574                        = mSharedLibraries.valueAt(i);
4575                if (versionedLib == null) {
4576                    continue;
4577                }
4578                final int versionCount = versionedLib.size();
4579                for (int j = 0; j < versionCount; j++) {
4580                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4581                    // Skip packages that are not static shared libs.
4582                    if (!libInfo.isStatic()) {
4583                        break;
4584                    }
4585                    // Important: We skip static shared libs used for some user since
4586                    // in such a case we need to keep the APK on the device. The check for
4587                    // a lib being used for any user is performed by the uninstall call.
4588                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4589                    // Resolve the package name - we use synthetic package names internally
4590                    final String internalPackageName = resolveInternalPackageNameLPr(
4591                            declaringPackage.getPackageName(),
4592                            declaringPackage.getLongVersionCode());
4593                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4594                    // Skip unused static shared libs cached less than the min period
4595                    // to prevent pruning a lib needed by a subsequently installed package.
4596                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4597                        continue;
4598                    }
4599                    if (packagesToDelete == null) {
4600                        packagesToDelete = new ArrayList<>();
4601                    }
4602                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4603                            declaringPackage.getLongVersionCode()));
4604                }
4605            }
4606        }
4607
4608        if (packagesToDelete != null) {
4609            final int packageCount = packagesToDelete.size();
4610            for (int i = 0; i < packageCount; i++) {
4611                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4612                // Delete the package synchronously (will fail of the lib used for any user).
4613                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4614                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4615                                == PackageManager.DELETE_SUCCEEDED) {
4616                    if (volume.getUsableSpace() >= neededSpace) {
4617                        return true;
4618                    }
4619                }
4620            }
4621        }
4622
4623        return false;
4624    }
4625
4626    /**
4627     * Update given flags based on encryption status of current user.
4628     */
4629    private int updateFlags(int flags, int userId) {
4630        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4631                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4632            // Caller expressed an explicit opinion about what encryption
4633            // aware/unaware components they want to see, so fall through and
4634            // give them what they want
4635        } else {
4636            // Caller expressed no opinion, so match based on user state
4637            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4638                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4639            } else {
4640                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4641            }
4642        }
4643        return flags;
4644    }
4645
4646    private UserManagerInternal getUserManagerInternal() {
4647        if (mUserManagerInternal == null) {
4648            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4649        }
4650        return mUserManagerInternal;
4651    }
4652
4653    private ActivityManagerInternal getActivityManagerInternal() {
4654        if (mActivityManagerInternal == null) {
4655            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4656        }
4657        return mActivityManagerInternal;
4658    }
4659
4660
4661    private DeviceIdleController.LocalService getDeviceIdleController() {
4662        if (mDeviceIdleController == null) {
4663            mDeviceIdleController =
4664                    LocalServices.getService(DeviceIdleController.LocalService.class);
4665        }
4666        return mDeviceIdleController;
4667    }
4668
4669    /**
4670     * Update given flags when being used to request {@link PackageInfo}.
4671     */
4672    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4673        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4674        boolean triaged = true;
4675        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4676                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4677            // Caller is asking for component details, so they'd better be
4678            // asking for specific encryption matching behavior, or be triaged
4679            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4680                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4681                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4682                triaged = false;
4683            }
4684        }
4685        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4686                | PackageManager.MATCH_SYSTEM_ONLY
4687                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4688            triaged = false;
4689        }
4690        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4691            mPermissionManager.enforceCrossUserPermission(
4692                    Binder.getCallingUid(), userId, false, false,
4693                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4694                    + Debug.getCallers(5));
4695        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4696                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4697            // If the caller wants all packages and has a restricted profile associated with it,
4698            // then match all users. This is to make sure that launchers that need to access work
4699            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4700            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4701            flags |= PackageManager.MATCH_ANY_USER;
4702        }
4703        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4704            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4705                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4706        }
4707        return updateFlags(flags, userId);
4708    }
4709
4710    /**
4711     * Update given flags when being used to request {@link ApplicationInfo}.
4712     */
4713    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4714        return updateFlagsForPackage(flags, userId, cookie);
4715    }
4716
4717    /**
4718     * Update given flags when being used to request {@link ComponentInfo}.
4719     */
4720    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4721        if (cookie instanceof Intent) {
4722            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4723                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4724            }
4725        }
4726
4727        boolean triaged = true;
4728        // Caller is asking for component details, so they'd better be
4729        // asking for specific encryption matching behavior, or be triaged
4730        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4731                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4732                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4733            triaged = false;
4734        }
4735        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4736            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4737                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4738        }
4739
4740        return updateFlags(flags, userId);
4741    }
4742
4743    /**
4744     * Update given intent when being used to request {@link ResolveInfo}.
4745     */
4746    private Intent updateIntentForResolve(Intent intent) {
4747        if (intent.getSelector() != null) {
4748            intent = intent.getSelector();
4749        }
4750        if (DEBUG_PREFERRED) {
4751            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4752        }
4753        return intent;
4754    }
4755
4756    /**
4757     * Update given flags when being used to request {@link ResolveInfo}.
4758     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4759     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4760     * flag set. However, this flag is only honoured in three circumstances:
4761     * <ul>
4762     * <li>when called from a system process</li>
4763     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4764     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4765     * action and a {@code android.intent.category.BROWSABLE} category</li>
4766     * </ul>
4767     */
4768    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4769        return updateFlagsForResolve(flags, userId, intent, callingUid,
4770                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4771    }
4772    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4773            boolean wantInstantApps) {
4774        return updateFlagsForResolve(flags, userId, intent, callingUid,
4775                wantInstantApps, false /*onlyExposedExplicitly*/);
4776    }
4777    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4778            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4779        // Safe mode means we shouldn't match any third-party components
4780        if (mSafeMode) {
4781            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4782        }
4783        if (getInstantAppPackageName(callingUid) != null) {
4784            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4785            if (onlyExposedExplicitly) {
4786                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4787            }
4788            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4789            flags |= PackageManager.MATCH_INSTANT;
4790        } else {
4791            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4792            final boolean allowMatchInstant = wantInstantApps
4793                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4794            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4795                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4796            if (!allowMatchInstant) {
4797                flags &= ~PackageManager.MATCH_INSTANT;
4798            }
4799        }
4800        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4801    }
4802
4803    @Override
4804    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4805        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4806    }
4807
4808    /**
4809     * Important: The provided filterCallingUid is used exclusively to filter out activities
4810     * that can be seen based on user state. It's typically the original caller uid prior
4811     * to clearing. Because it can only be provided by trusted code, it's value can be
4812     * trusted and will be used as-is; unlike userId which will be validated by this method.
4813     */
4814    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4815            int filterCallingUid, int userId) {
4816        if (!sUserManager.exists(userId)) return null;
4817        flags = updateFlagsForComponent(flags, userId, component);
4818
4819        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4820            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4821                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
4822        }
4823
4824        synchronized (mPackages) {
4825            PackageParser.Activity a = mActivities.mActivities.get(component);
4826
4827            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4828            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4829                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4830                if (ps == null) return null;
4831                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4832                    return null;
4833                }
4834                return PackageParser.generateActivityInfo(
4835                        a, flags, ps.readUserState(userId), userId);
4836            }
4837            if (mResolveComponentName.equals(component)) {
4838                return PackageParser.generateActivityInfo(
4839                        mResolveActivity, flags, new PackageUserState(), userId);
4840            }
4841        }
4842        return null;
4843    }
4844
4845    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4846        if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4847            return false;
4848        }
4849        final long token = Binder.clearCallingIdentity();
4850        try {
4851            final int callingUserId = UserHandle.getUserId(callingUid);
4852            if (ActivityManager.getCurrentUser() != callingUserId) {
4853                return false;
4854            }
4855            return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4856        } finally {
4857            Binder.restoreCallingIdentity(token);
4858        }
4859    }
4860
4861    @Override
4862    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4863            String resolvedType) {
4864        synchronized (mPackages) {
4865            if (component.equals(mResolveComponentName)) {
4866                // The resolver supports EVERYTHING!
4867                return true;
4868            }
4869            final int callingUid = Binder.getCallingUid();
4870            final int callingUserId = UserHandle.getUserId(callingUid);
4871            PackageParser.Activity a = mActivities.mActivities.get(component);
4872            if (a == null) {
4873                return false;
4874            }
4875            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4876            if (ps == null) {
4877                return false;
4878            }
4879            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4880                return false;
4881            }
4882            for (int i=0; i<a.intents.size(); i++) {
4883                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4884                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4885                    return true;
4886                }
4887            }
4888            return false;
4889        }
4890    }
4891
4892    @Override
4893    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4894        if (!sUserManager.exists(userId)) return null;
4895        final int callingUid = Binder.getCallingUid();
4896        flags = updateFlagsForComponent(flags, userId, component);
4897        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4898                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4899        synchronized (mPackages) {
4900            PackageParser.Activity a = mReceivers.mActivities.get(component);
4901            if (DEBUG_PACKAGE_INFO) Log.v(
4902                TAG, "getReceiverInfo " + component + ": " + a);
4903            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4904                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4905                if (ps == null) return null;
4906                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4907                    return null;
4908                }
4909                return PackageParser.generateActivityInfo(
4910                        a, flags, ps.readUserState(userId), userId);
4911            }
4912        }
4913        return null;
4914    }
4915
4916    @Override
4917    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4918            int flags, int userId) {
4919        if (!sUserManager.exists(userId)) return null;
4920        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4921        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4922            return null;
4923        }
4924
4925        flags = updateFlagsForPackage(flags, userId, null);
4926
4927        final boolean canSeeStaticLibraries =
4928                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4929                        == PERMISSION_GRANTED
4930                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4931                        == PERMISSION_GRANTED
4932                || canRequestPackageInstallsInternal(packageName,
4933                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4934                        false  /* throwIfPermNotDeclared*/)
4935                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4936                        == PERMISSION_GRANTED;
4937
4938        synchronized (mPackages) {
4939            List<SharedLibraryInfo> result = null;
4940
4941            final int libCount = mSharedLibraries.size();
4942            for (int i = 0; i < libCount; i++) {
4943                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4944                if (versionedLib == null) {
4945                    continue;
4946                }
4947
4948                final int versionCount = versionedLib.size();
4949                for (int j = 0; j < versionCount; j++) {
4950                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4951                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4952                        break;
4953                    }
4954                    final long identity = Binder.clearCallingIdentity();
4955                    try {
4956                        PackageInfo packageInfo = getPackageInfoVersioned(
4957                                libInfo.getDeclaringPackage(), flags
4958                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4959                        if (packageInfo == null) {
4960                            continue;
4961                        }
4962                    } finally {
4963                        Binder.restoreCallingIdentity(identity);
4964                    }
4965
4966                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4967                            libInfo.getLongVersion(), libInfo.getType(),
4968                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4969                            flags, userId));
4970
4971                    if (result == null) {
4972                        result = new ArrayList<>();
4973                    }
4974                    result.add(resLibInfo);
4975                }
4976            }
4977
4978            return result != null ? new ParceledListSlice<>(result) : null;
4979        }
4980    }
4981
4982    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4983            SharedLibraryInfo libInfo, int flags, int userId) {
4984        List<VersionedPackage> versionedPackages = null;
4985        final int packageCount = mSettings.mPackages.size();
4986        for (int i = 0; i < packageCount; i++) {
4987            PackageSetting ps = mSettings.mPackages.valueAt(i);
4988
4989            if (ps == null) {
4990                continue;
4991            }
4992
4993            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4994                continue;
4995            }
4996
4997            final String libName = libInfo.getName();
4998            if (libInfo.isStatic()) {
4999                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5000                if (libIdx < 0) {
5001                    continue;
5002                }
5003                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5004                    continue;
5005                }
5006                if (versionedPackages == null) {
5007                    versionedPackages = new ArrayList<>();
5008                }
5009                // If the dependent is a static shared lib, use the public package name
5010                String dependentPackageName = ps.name;
5011                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5012                    dependentPackageName = ps.pkg.manifestPackageName;
5013                }
5014                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5015            } else if (ps.pkg != null) {
5016                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5017                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5018                    if (versionedPackages == null) {
5019                        versionedPackages = new ArrayList<>();
5020                    }
5021                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5022                }
5023            }
5024        }
5025
5026        return versionedPackages;
5027    }
5028
5029    @Override
5030    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5031        if (!sUserManager.exists(userId)) return null;
5032        final int callingUid = Binder.getCallingUid();
5033        flags = updateFlagsForComponent(flags, userId, component);
5034        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5035                false /* requireFullPermission */, false /* checkShell */, "get service info");
5036        synchronized (mPackages) {
5037            PackageParser.Service s = mServices.mServices.get(component);
5038            if (DEBUG_PACKAGE_INFO) Log.v(
5039                TAG, "getServiceInfo " + component + ": " + s);
5040            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5041                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5042                if (ps == null) return null;
5043                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5044                    return null;
5045                }
5046                return PackageParser.generateServiceInfo(
5047                        s, flags, ps.readUserState(userId), userId);
5048            }
5049        }
5050        return null;
5051    }
5052
5053    @Override
5054    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5055        if (!sUserManager.exists(userId)) return null;
5056        final int callingUid = Binder.getCallingUid();
5057        flags = updateFlagsForComponent(flags, userId, component);
5058        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5059                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5060        synchronized (mPackages) {
5061            PackageParser.Provider p = mProviders.mProviders.get(component);
5062            if (DEBUG_PACKAGE_INFO) Log.v(
5063                TAG, "getProviderInfo " + component + ": " + p);
5064            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5065                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5066                if (ps == null) return null;
5067                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5068                    return null;
5069                }
5070                return PackageParser.generateProviderInfo(
5071                        p, flags, ps.readUserState(userId), userId);
5072            }
5073        }
5074        return null;
5075    }
5076
5077    @Override
5078    public String[] getSystemSharedLibraryNames() {
5079        // allow instant applications
5080        synchronized (mPackages) {
5081            Set<String> libs = null;
5082            final int libCount = mSharedLibraries.size();
5083            for (int i = 0; i < libCount; i++) {
5084                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5085                if (versionedLib == null) {
5086                    continue;
5087                }
5088                final int versionCount = versionedLib.size();
5089                for (int j = 0; j < versionCount; j++) {
5090                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5091                    if (!libEntry.info.isStatic()) {
5092                        if (libs == null) {
5093                            libs = new ArraySet<>();
5094                        }
5095                        libs.add(libEntry.info.getName());
5096                        break;
5097                    }
5098                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5099                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5100                            UserHandle.getUserId(Binder.getCallingUid()),
5101                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5102                        if (libs == null) {
5103                            libs = new ArraySet<>();
5104                        }
5105                        libs.add(libEntry.info.getName());
5106                        break;
5107                    }
5108                }
5109            }
5110
5111            if (libs != null) {
5112                String[] libsArray = new String[libs.size()];
5113                libs.toArray(libsArray);
5114                return libsArray;
5115            }
5116
5117            return null;
5118        }
5119    }
5120
5121    @Override
5122    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5123        // allow instant applications
5124        synchronized (mPackages) {
5125            return mServicesSystemSharedLibraryPackageName;
5126        }
5127    }
5128
5129    @Override
5130    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5131        // allow instant applications
5132        synchronized (mPackages) {
5133            return mSharedSystemSharedLibraryPackageName;
5134        }
5135    }
5136
5137    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5138        for (int i = userList.length - 1; i >= 0; --i) {
5139            final int userId = userList[i];
5140            // don't add instant app to the list of updates
5141            if (pkgSetting.getInstantApp(userId)) {
5142                continue;
5143            }
5144            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5145            if (changedPackages == null) {
5146                changedPackages = new SparseArray<>();
5147                mChangedPackages.put(userId, changedPackages);
5148            }
5149            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5150            if (sequenceNumbers == null) {
5151                sequenceNumbers = new HashMap<>();
5152                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5153            }
5154            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5155            if (sequenceNumber != null) {
5156                changedPackages.remove(sequenceNumber);
5157            }
5158            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5159            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5160        }
5161        mChangedPackagesSequenceNumber++;
5162    }
5163
5164    @Override
5165    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5166        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5167            return null;
5168        }
5169        synchronized (mPackages) {
5170            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5171                return null;
5172            }
5173            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5174            if (changedPackages == null) {
5175                return null;
5176            }
5177            final List<String> packageNames =
5178                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5179            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5180                final String packageName = changedPackages.get(i);
5181                if (packageName != null) {
5182                    packageNames.add(packageName);
5183                }
5184            }
5185            return packageNames.isEmpty()
5186                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5187        }
5188    }
5189
5190    @Override
5191    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5192        // allow instant applications
5193        ArrayList<FeatureInfo> res;
5194        synchronized (mAvailableFeatures) {
5195            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5196            res.addAll(mAvailableFeatures.values());
5197        }
5198        final FeatureInfo fi = new FeatureInfo();
5199        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5200                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5201        res.add(fi);
5202
5203        return new ParceledListSlice<>(res);
5204    }
5205
5206    @Override
5207    public boolean hasSystemFeature(String name, int version) {
5208        // allow instant applications
5209        synchronized (mAvailableFeatures) {
5210            final FeatureInfo feat = mAvailableFeatures.get(name);
5211            if (feat == null) {
5212                return false;
5213            } else {
5214                return feat.version >= version;
5215            }
5216        }
5217    }
5218
5219    @Override
5220    public int checkPermission(String permName, String pkgName, int userId) {
5221        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5222    }
5223
5224    @Override
5225    public int checkUidPermission(String permName, int uid) {
5226        synchronized (mPackages) {
5227            final String[] packageNames = getPackagesForUid(uid);
5228            final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
5229                    ? mPackages.get(packageNames[0])
5230                    : null;
5231            return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5232        }
5233    }
5234
5235    @Override
5236    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5237        if (UserHandle.getCallingUserId() != userId) {
5238            mContext.enforceCallingPermission(
5239                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5240                    "isPermissionRevokedByPolicy for user " + userId);
5241        }
5242
5243        if (checkPermission(permission, packageName, userId)
5244                == PackageManager.PERMISSION_GRANTED) {
5245            return false;
5246        }
5247
5248        final int callingUid = Binder.getCallingUid();
5249        if (getInstantAppPackageName(callingUid) != null) {
5250            if (!isCallerSameApp(packageName, callingUid)) {
5251                return false;
5252            }
5253        } else {
5254            if (isInstantApp(packageName, userId)) {
5255                return false;
5256            }
5257        }
5258
5259        final long identity = Binder.clearCallingIdentity();
5260        try {
5261            final int flags = getPermissionFlags(permission, packageName, userId);
5262            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5263        } finally {
5264            Binder.restoreCallingIdentity(identity);
5265        }
5266    }
5267
5268    @Override
5269    public String getPermissionControllerPackageName() {
5270        synchronized (mPackages) {
5271            return mRequiredInstallerPackage;
5272        }
5273    }
5274
5275    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5276        return mPermissionManager.addDynamicPermission(
5277                info, async, getCallingUid(), new PermissionCallback() {
5278                    @Override
5279                    public void onPermissionChanged() {
5280                        if (!async) {
5281                            mSettings.writeLPr();
5282                        } else {
5283                            scheduleWriteSettingsLocked();
5284                        }
5285                    }
5286                });
5287    }
5288
5289    @Override
5290    public boolean addPermission(PermissionInfo info) {
5291        synchronized (mPackages) {
5292            return addDynamicPermission(info, false);
5293        }
5294    }
5295
5296    @Override
5297    public boolean addPermissionAsync(PermissionInfo info) {
5298        synchronized (mPackages) {
5299            return addDynamicPermission(info, true);
5300        }
5301    }
5302
5303    @Override
5304    public void removePermission(String permName) {
5305        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5306    }
5307
5308    @Override
5309    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5310        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5311                getCallingUid(), userId, mPermissionCallback);
5312    }
5313
5314    @Override
5315    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5316        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5317                getCallingUid(), userId, mPermissionCallback);
5318    }
5319
5320    @Override
5321    public void resetRuntimePermissions() {
5322        mContext.enforceCallingOrSelfPermission(
5323                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5324                "revokeRuntimePermission");
5325
5326        int callingUid = Binder.getCallingUid();
5327        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5328            mContext.enforceCallingOrSelfPermission(
5329                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5330                    "resetRuntimePermissions");
5331        }
5332
5333        synchronized (mPackages) {
5334            mPermissionManager.updateAllPermissions(
5335                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5336                    mPermissionCallback);
5337            for (int userId : UserManagerService.getInstance().getUserIds()) {
5338                final int packageCount = mPackages.size();
5339                for (int i = 0; i < packageCount; i++) {
5340                    PackageParser.Package pkg = mPackages.valueAt(i);
5341                    if (!(pkg.mExtras instanceof PackageSetting)) {
5342                        continue;
5343                    }
5344                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5345                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5346                }
5347            }
5348        }
5349    }
5350
5351    @Override
5352    public int getPermissionFlags(String permName, String packageName, int userId) {
5353        return mPermissionManager.getPermissionFlags(
5354                permName, packageName, getCallingUid(), userId);
5355    }
5356
5357    @Override
5358    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5359            int flagValues, int userId) {
5360        mPermissionManager.updatePermissionFlags(
5361                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5362                mPermissionCallback);
5363    }
5364
5365    /**
5366     * Update the permission flags for all packages and runtime permissions of a user in order
5367     * to allow device or profile owner to remove POLICY_FIXED.
5368     */
5369    @Override
5370    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5371        synchronized (mPackages) {
5372            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5373                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5374                    mPermissionCallback);
5375            if (changed) {
5376                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5377            }
5378        }
5379    }
5380
5381    @Override
5382    public boolean shouldShowRequestPermissionRationale(String permissionName,
5383            String packageName, int userId) {
5384        if (UserHandle.getCallingUserId() != userId) {
5385            mContext.enforceCallingPermission(
5386                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5387                    "canShowRequestPermissionRationale for user " + userId);
5388        }
5389
5390        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5391        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5392            return false;
5393        }
5394
5395        if (checkPermission(permissionName, packageName, userId)
5396                == PackageManager.PERMISSION_GRANTED) {
5397            return false;
5398        }
5399
5400        final int flags;
5401
5402        final long identity = Binder.clearCallingIdentity();
5403        try {
5404            flags = getPermissionFlags(permissionName,
5405                    packageName, userId);
5406        } finally {
5407            Binder.restoreCallingIdentity(identity);
5408        }
5409
5410        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5411                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5412                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5413
5414        if ((flags & fixedFlags) != 0) {
5415            return false;
5416        }
5417
5418        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5419    }
5420
5421    @Override
5422    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5423        mContext.enforceCallingOrSelfPermission(
5424                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5425                "addOnPermissionsChangeListener");
5426
5427        synchronized (mPackages) {
5428            mOnPermissionChangeListeners.addListenerLocked(listener);
5429        }
5430    }
5431
5432    @Override
5433    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5434        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5435            throw new SecurityException("Instant applications don't have access to this method");
5436        }
5437        synchronized (mPackages) {
5438            mOnPermissionChangeListeners.removeListenerLocked(listener);
5439        }
5440    }
5441
5442    @Override
5443    public boolean isProtectedBroadcast(String actionName) {
5444        // allow instant applications
5445        synchronized (mProtectedBroadcasts) {
5446            if (mProtectedBroadcasts.contains(actionName)) {
5447                return true;
5448            } else if (actionName != null) {
5449                // TODO: remove these terrible hacks
5450                if (actionName.startsWith("android.net.netmon.lingerExpired")
5451                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5452                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5453                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5454                    return true;
5455                }
5456            }
5457        }
5458        return false;
5459    }
5460
5461    @Override
5462    public int checkSignatures(String pkg1, String pkg2) {
5463        synchronized (mPackages) {
5464            final PackageParser.Package p1 = mPackages.get(pkg1);
5465            final PackageParser.Package p2 = mPackages.get(pkg2);
5466            if (p1 == null || p1.mExtras == null
5467                    || p2 == null || p2.mExtras == null) {
5468                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5469            }
5470            final int callingUid = Binder.getCallingUid();
5471            final int callingUserId = UserHandle.getUserId(callingUid);
5472            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5473            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5474            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5475                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5476                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5477            }
5478            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5479        }
5480    }
5481
5482    @Override
5483    public int checkUidSignatures(int uid1, int uid2) {
5484        final int callingUid = Binder.getCallingUid();
5485        final int callingUserId = UserHandle.getUserId(callingUid);
5486        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5487        // Map to base uids.
5488        uid1 = UserHandle.getAppId(uid1);
5489        uid2 = UserHandle.getAppId(uid2);
5490        // reader
5491        synchronized (mPackages) {
5492            Signature[] s1;
5493            Signature[] s2;
5494            Object obj = mSettings.getUserIdLPr(uid1);
5495            if (obj != null) {
5496                if (obj instanceof SharedUserSetting) {
5497                    if (isCallerInstantApp) {
5498                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5499                    }
5500                    s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5501                } else if (obj instanceof PackageSetting) {
5502                    final PackageSetting ps = (PackageSetting) obj;
5503                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5504                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5505                    }
5506                    s1 = ps.signatures.mSigningDetails.signatures;
5507                } else {
5508                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5509                }
5510            } else {
5511                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5512            }
5513            obj = mSettings.getUserIdLPr(uid2);
5514            if (obj != null) {
5515                if (obj instanceof SharedUserSetting) {
5516                    if (isCallerInstantApp) {
5517                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5518                    }
5519                    s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5520                } else if (obj instanceof PackageSetting) {
5521                    final PackageSetting ps = (PackageSetting) obj;
5522                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5523                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5524                    }
5525                    s2 = ps.signatures.mSigningDetails.signatures;
5526                } else {
5527                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5528                }
5529            } else {
5530                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5531            }
5532            return compareSignatures(s1, s2);
5533        }
5534    }
5535
5536    @Override
5537    public boolean hasSigningCertificate(
5538            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5539
5540        synchronized (mPackages) {
5541            final PackageParser.Package p = mPackages.get(packageName);
5542            if (p == null || p.mExtras == null) {
5543                return false;
5544            }
5545            final int callingUid = Binder.getCallingUid();
5546            final int callingUserId = UserHandle.getUserId(callingUid);
5547            final PackageSetting ps = (PackageSetting) p.mExtras;
5548            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5549                return false;
5550            }
5551            switch (type) {
5552                case CERT_INPUT_RAW_X509:
5553                    return p.mSigningDetails.hasCertificate(certificate);
5554                case CERT_INPUT_SHA256:
5555                    return p.mSigningDetails.hasSha256Certificate(certificate);
5556                default:
5557                    return false;
5558            }
5559        }
5560    }
5561
5562    @Override
5563    public boolean hasUidSigningCertificate(
5564            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5565        final int callingUid = Binder.getCallingUid();
5566        final int callingUserId = UserHandle.getUserId(callingUid);
5567        // Map to base uids.
5568        uid = UserHandle.getAppId(uid);
5569        // reader
5570        synchronized (mPackages) {
5571            final PackageParser.SigningDetails signingDetails;
5572            final Object obj = mSettings.getUserIdLPr(uid);
5573            if (obj != null) {
5574                if (obj instanceof SharedUserSetting) {
5575                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5576                    if (isCallerInstantApp) {
5577                        return false;
5578                    }
5579                    signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5580                } else if (obj instanceof PackageSetting) {
5581                    final PackageSetting ps = (PackageSetting) obj;
5582                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5583                        return false;
5584                    }
5585                    signingDetails = ps.signatures.mSigningDetails;
5586                } else {
5587                    return false;
5588                }
5589            } else {
5590                return false;
5591            }
5592            switch (type) {
5593                case CERT_INPUT_RAW_X509:
5594                    return signingDetails.hasCertificate(certificate);
5595                case CERT_INPUT_SHA256:
5596                    return signingDetails.hasSha256Certificate(certificate);
5597                default:
5598                    return false;
5599            }
5600        }
5601    }
5602
5603    /**
5604     * This method should typically only be used when granting or revoking
5605     * permissions, since the app may immediately restart after this call.
5606     * <p>
5607     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5608     * guard your work against the app being relaunched.
5609     */
5610    private void killUid(int appId, int userId, String reason) {
5611        final long identity = Binder.clearCallingIdentity();
5612        try {
5613            IActivityManager am = ActivityManager.getService();
5614            if (am != null) {
5615                try {
5616                    am.killUid(appId, userId, reason);
5617                } catch (RemoteException e) {
5618                    /* ignore - same process */
5619                }
5620            }
5621        } finally {
5622            Binder.restoreCallingIdentity(identity);
5623        }
5624    }
5625
5626    /**
5627     * If the database version for this type of package (internal storage or
5628     * external storage) is less than the version where package signatures
5629     * were updated, return true.
5630     */
5631    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5632        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5633        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5634    }
5635
5636    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5637        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5638        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5639    }
5640
5641    @Override
5642    public List<String> getAllPackages() {
5643        final int callingUid = Binder.getCallingUid();
5644        final int callingUserId = UserHandle.getUserId(callingUid);
5645        synchronized (mPackages) {
5646            if (canViewInstantApps(callingUid, callingUserId)) {
5647                return new ArrayList<String>(mPackages.keySet());
5648            }
5649            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5650            final List<String> result = new ArrayList<>();
5651            if (instantAppPkgName != null) {
5652                // caller is an instant application; filter unexposed applications
5653                for (PackageParser.Package pkg : mPackages.values()) {
5654                    if (!pkg.visibleToInstantApps) {
5655                        continue;
5656                    }
5657                    result.add(pkg.packageName);
5658                }
5659            } else {
5660                // caller is a normal application; filter instant applications
5661                for (PackageParser.Package pkg : mPackages.values()) {
5662                    final PackageSetting ps =
5663                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5664                    if (ps != null
5665                            && ps.getInstantApp(callingUserId)
5666                            && !mInstantAppRegistry.isInstantAccessGranted(
5667                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5668                        continue;
5669                    }
5670                    result.add(pkg.packageName);
5671                }
5672            }
5673            return result;
5674        }
5675    }
5676
5677    @Override
5678    public String[] getPackagesForUid(int uid) {
5679        final int callingUid = Binder.getCallingUid();
5680        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5681        final int userId = UserHandle.getUserId(uid);
5682        uid = UserHandle.getAppId(uid);
5683        // reader
5684        synchronized (mPackages) {
5685            Object obj = mSettings.getUserIdLPr(uid);
5686            if (obj instanceof SharedUserSetting) {
5687                if (isCallerInstantApp) {
5688                    return null;
5689                }
5690                final SharedUserSetting sus = (SharedUserSetting) obj;
5691                final int N = sus.packages.size();
5692                String[] res = new String[N];
5693                final Iterator<PackageSetting> it = sus.packages.iterator();
5694                int i = 0;
5695                while (it.hasNext()) {
5696                    PackageSetting ps = it.next();
5697                    if (ps.getInstalled(userId)) {
5698                        res[i++] = ps.name;
5699                    } else {
5700                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5701                    }
5702                }
5703                return res;
5704            } else if (obj instanceof PackageSetting) {
5705                final PackageSetting ps = (PackageSetting) obj;
5706                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5707                    return new String[]{ps.name};
5708                }
5709            }
5710        }
5711        return null;
5712    }
5713
5714    @Override
5715    public String getNameForUid(int uid) {
5716        final int callingUid = Binder.getCallingUid();
5717        if (getInstantAppPackageName(callingUid) != null) {
5718            return null;
5719        }
5720        synchronized (mPackages) {
5721            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5722            if (obj instanceof SharedUserSetting) {
5723                final SharedUserSetting sus = (SharedUserSetting) obj;
5724                return sus.name + ":" + sus.userId;
5725            } else if (obj instanceof PackageSetting) {
5726                final PackageSetting ps = (PackageSetting) obj;
5727                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5728                    return null;
5729                }
5730                return ps.name;
5731            }
5732            return null;
5733        }
5734    }
5735
5736    @Override
5737    public String[] getNamesForUids(int[] uids) {
5738        if (uids == null || uids.length == 0) {
5739            return null;
5740        }
5741        final int callingUid = Binder.getCallingUid();
5742        if (getInstantAppPackageName(callingUid) != null) {
5743            return null;
5744        }
5745        final String[] names = new String[uids.length];
5746        synchronized (mPackages) {
5747            for (int i = uids.length - 1; i >= 0; i--) {
5748                final int uid = uids[i];
5749                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5750                if (obj instanceof SharedUserSetting) {
5751                    final SharedUserSetting sus = (SharedUserSetting) obj;
5752                    names[i] = "shared:" + sus.name;
5753                } else if (obj instanceof PackageSetting) {
5754                    final PackageSetting ps = (PackageSetting) obj;
5755                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5756                        names[i] = null;
5757                    } else {
5758                        names[i] = ps.name;
5759                    }
5760                } else {
5761                    names[i] = null;
5762                }
5763            }
5764        }
5765        return names;
5766    }
5767
5768    @Override
5769    public int getUidForSharedUser(String sharedUserName) {
5770        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5771            return -1;
5772        }
5773        if (sharedUserName == null) {
5774            return -1;
5775        }
5776        // reader
5777        synchronized (mPackages) {
5778            SharedUserSetting suid;
5779            try {
5780                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5781                if (suid != null) {
5782                    return suid.userId;
5783                }
5784            } catch (PackageManagerException ignore) {
5785                // can't happen, but, still need to catch it
5786            }
5787            return -1;
5788        }
5789    }
5790
5791    @Override
5792    public int getFlagsForUid(int uid) {
5793        final int callingUid = Binder.getCallingUid();
5794        if (getInstantAppPackageName(callingUid) != null) {
5795            return 0;
5796        }
5797        synchronized (mPackages) {
5798            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5799            if (obj instanceof SharedUserSetting) {
5800                final SharedUserSetting sus = (SharedUserSetting) obj;
5801                return sus.pkgFlags;
5802            } else if (obj instanceof PackageSetting) {
5803                final PackageSetting ps = (PackageSetting) obj;
5804                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5805                    return 0;
5806                }
5807                return ps.pkgFlags;
5808            }
5809        }
5810        return 0;
5811    }
5812
5813    @Override
5814    public int getPrivateFlagsForUid(int uid) {
5815        final int callingUid = Binder.getCallingUid();
5816        if (getInstantAppPackageName(callingUid) != null) {
5817            return 0;
5818        }
5819        synchronized (mPackages) {
5820            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5821            if (obj instanceof SharedUserSetting) {
5822                final SharedUserSetting sus = (SharedUserSetting) obj;
5823                return sus.pkgPrivateFlags;
5824            } else if (obj instanceof PackageSetting) {
5825                final PackageSetting ps = (PackageSetting) obj;
5826                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5827                    return 0;
5828                }
5829                return ps.pkgPrivateFlags;
5830            }
5831        }
5832        return 0;
5833    }
5834
5835    @Override
5836    public boolean isUidPrivileged(int uid) {
5837        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5838            return false;
5839        }
5840        uid = UserHandle.getAppId(uid);
5841        // reader
5842        synchronized (mPackages) {
5843            Object obj = mSettings.getUserIdLPr(uid);
5844            if (obj instanceof SharedUserSetting) {
5845                final SharedUserSetting sus = (SharedUserSetting) obj;
5846                final Iterator<PackageSetting> it = sus.packages.iterator();
5847                while (it.hasNext()) {
5848                    if (it.next().isPrivileged()) {
5849                        return true;
5850                    }
5851                }
5852            } else if (obj instanceof PackageSetting) {
5853                final PackageSetting ps = (PackageSetting) obj;
5854                return ps.isPrivileged();
5855            }
5856        }
5857        return false;
5858    }
5859
5860    @Override
5861    public String[] getAppOpPermissionPackages(String permName) {
5862        return mPermissionManager.getAppOpPermissionPackages(permName);
5863    }
5864
5865    @Override
5866    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5867            int flags, int userId) {
5868        return resolveIntentInternal(
5869                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5870    }
5871
5872    /**
5873     * Normally instant apps can only be resolved when they're visible to the caller.
5874     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5875     * since we need to allow the system to start any installed application.
5876     */
5877    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5878            int flags, int userId, boolean resolveForStart) {
5879        try {
5880            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5881
5882            if (!sUserManager.exists(userId)) return null;
5883            final int callingUid = Binder.getCallingUid();
5884            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5885            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5886                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5887
5888            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5889            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5890                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5891            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5892
5893            final ResolveInfo bestChoice =
5894                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5895            return bestChoice;
5896        } finally {
5897            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5898        }
5899    }
5900
5901    @Override
5902    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5903        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5904            throw new SecurityException(
5905                    "findPersistentPreferredActivity can only be run by the system");
5906        }
5907        if (!sUserManager.exists(userId)) {
5908            return null;
5909        }
5910        final int callingUid = Binder.getCallingUid();
5911        intent = updateIntentForResolve(intent);
5912        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5913        final int flags = updateFlagsForResolve(
5914                0, userId, intent, callingUid, false /*includeInstantApps*/);
5915        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5916                userId);
5917        synchronized (mPackages) {
5918            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5919                    userId);
5920        }
5921    }
5922
5923    @Override
5924    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5925            IntentFilter filter, int match, ComponentName activity) {
5926        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5927            return;
5928        }
5929        final int userId = UserHandle.getCallingUserId();
5930        if (DEBUG_PREFERRED) {
5931            Log.v(TAG, "setLastChosenActivity intent=" + intent
5932                + " resolvedType=" + resolvedType
5933                + " flags=" + flags
5934                + " filter=" + filter
5935                + " match=" + match
5936                + " activity=" + activity);
5937            filter.dump(new PrintStreamPrinter(System.out), "    ");
5938        }
5939        intent.setComponent(null);
5940        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5941                userId);
5942        // Find any earlier preferred or last chosen entries and nuke them
5943        findPreferredActivity(intent, resolvedType,
5944                flags, query, 0, false, true, false, userId);
5945        // Add the new activity as the last chosen for this filter
5946        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5947                "Setting last chosen");
5948    }
5949
5950    @Override
5951    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5952        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5953            return null;
5954        }
5955        final int userId = UserHandle.getCallingUserId();
5956        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5957        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5958                userId);
5959        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5960                false, false, false, userId);
5961    }
5962
5963    /**
5964     * Returns whether or not instant apps have been disabled remotely.
5965     */
5966    private boolean areWebInstantAppsDisabled() {
5967        return mWebInstantAppsDisabled;
5968    }
5969
5970    private boolean isInstantAppResolutionAllowed(
5971            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5972            boolean skipPackageCheck) {
5973        if (mInstantAppResolverConnection == null) {
5974            return false;
5975        }
5976        if (mInstantAppInstallerActivity == null) {
5977            return false;
5978        }
5979        if (intent.getComponent() != null) {
5980            return false;
5981        }
5982        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5983            return false;
5984        }
5985        if (!skipPackageCheck && intent.getPackage() != null) {
5986            return false;
5987        }
5988        if (!intent.isWebIntent()) {
5989            // for non web intents, we should not resolve externally if an app already exists to
5990            // handle it or if the caller didn't explicitly request it.
5991            if ((resolvedActivities != null && resolvedActivities.size() != 0)
5992                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
5993                return false;
5994            }
5995        } else {
5996            if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
5997                return false;
5998            } else if (areWebInstantAppsDisabled()) {
5999                return false;
6000            }
6001        }
6002        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6003        // Or if there's already an ephemeral app installed that handles the action
6004        synchronized (mPackages) {
6005            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6006            for (int n = 0; n < count; n++) {
6007                final ResolveInfo info = resolvedActivities.get(n);
6008                final String packageName = info.activityInfo.packageName;
6009                final PackageSetting ps = mSettings.mPackages.get(packageName);
6010                if (ps != null) {
6011                    // only check domain verification status if the app is not a browser
6012                    if (!info.handleAllWebDataURI) {
6013                        // Try to get the status from User settings first
6014                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6015                        final int status = (int) (packedStatus >> 32);
6016                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6017                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6018                            if (DEBUG_INSTANT) {
6019                                Slog.v(TAG, "DENY instant app;"
6020                                    + " pkg: " + packageName + ", status: " + status);
6021                            }
6022                            return false;
6023                        }
6024                    }
6025                    if (ps.getInstantApp(userId)) {
6026                        if (DEBUG_INSTANT) {
6027                            Slog.v(TAG, "DENY instant app installed;"
6028                                    + " pkg: " + packageName);
6029                        }
6030                        return false;
6031                    }
6032                }
6033            }
6034        }
6035        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6036        return true;
6037    }
6038
6039    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6040            Intent origIntent, String resolvedType, String callingPackage,
6041            Bundle verificationBundle, int userId) {
6042        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6043                new InstantAppRequest(responseObj, origIntent, resolvedType,
6044                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6045        mHandler.sendMessage(msg);
6046    }
6047
6048    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6049            int flags, List<ResolveInfo> query, int userId) {
6050        if (query != null) {
6051            final int N = query.size();
6052            if (N == 1) {
6053                return query.get(0);
6054            } else if (N > 1) {
6055                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6056                // If there is more than one activity with the same priority,
6057                // then let the user decide between them.
6058                ResolveInfo r0 = query.get(0);
6059                ResolveInfo r1 = query.get(1);
6060                if (DEBUG_INTENT_MATCHING || debug) {
6061                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6062                            + r1.activityInfo.name + "=" + r1.priority);
6063                }
6064                // If the first activity has a higher priority, or a different
6065                // default, then it is always desirable to pick it.
6066                if (r0.priority != r1.priority
6067                        || r0.preferredOrder != r1.preferredOrder
6068                        || r0.isDefault != r1.isDefault) {
6069                    return query.get(0);
6070                }
6071                // If we have saved a preference for a preferred activity for
6072                // this Intent, use that.
6073                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6074                        flags, query, r0.priority, true, false, debug, userId);
6075                if (ri != null) {
6076                    return ri;
6077                }
6078                // If we have an ephemeral app, use it
6079                for (int i = 0; i < N; i++) {
6080                    ri = query.get(i);
6081                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6082                        final String packageName = ri.activityInfo.packageName;
6083                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6084                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6085                        final int status = (int)(packedStatus >> 32);
6086                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6087                            return ri;
6088                        }
6089                    }
6090                }
6091                ri = new ResolveInfo(mResolveInfo);
6092                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6093                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6094                // If all of the options come from the same package, show the application's
6095                // label and icon instead of the generic resolver's.
6096                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6097                // and then throw away the ResolveInfo itself, meaning that the caller loses
6098                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6099                // a fallback for this case; we only set the target package's resources on
6100                // the ResolveInfo, not the ActivityInfo.
6101                final String intentPackage = intent.getPackage();
6102                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6103                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6104                    ri.resolvePackageName = intentPackage;
6105                    if (userNeedsBadging(userId)) {
6106                        ri.noResourceId = true;
6107                    } else {
6108                        ri.icon = appi.icon;
6109                    }
6110                    ri.iconResourceId = appi.icon;
6111                    ri.labelRes = appi.labelRes;
6112                }
6113                ri.activityInfo.applicationInfo = new ApplicationInfo(
6114                        ri.activityInfo.applicationInfo);
6115                if (userId != 0) {
6116                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6117                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6118                }
6119                // Make sure that the resolver is displayable in car mode
6120                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6121                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6122                return ri;
6123            }
6124        }
6125        return null;
6126    }
6127
6128    /**
6129     * Return true if the given list is not empty and all of its contents have
6130     * an activityInfo with the given package name.
6131     */
6132    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6133        if (ArrayUtils.isEmpty(list)) {
6134            return false;
6135        }
6136        for (int i = 0, N = list.size(); i < N; i++) {
6137            final ResolveInfo ri = list.get(i);
6138            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6139            if (ai == null || !packageName.equals(ai.packageName)) {
6140                return false;
6141            }
6142        }
6143        return true;
6144    }
6145
6146    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6147            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6148        final int N = query.size();
6149        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6150                .get(userId);
6151        // Get the list of persistent preferred activities that handle the intent
6152        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6153        List<PersistentPreferredActivity> pprefs = ppir != null
6154                ? ppir.queryIntent(intent, resolvedType,
6155                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6156                        userId)
6157                : null;
6158        if (pprefs != null && pprefs.size() > 0) {
6159            final int M = pprefs.size();
6160            for (int i=0; i<M; i++) {
6161                final PersistentPreferredActivity ppa = pprefs.get(i);
6162                if (DEBUG_PREFERRED || debug) {
6163                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6164                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6165                            + "\n  component=" + ppa.mComponent);
6166                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6167                }
6168                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6169                        flags | MATCH_DISABLED_COMPONENTS, userId);
6170                if (DEBUG_PREFERRED || debug) {
6171                    Slog.v(TAG, "Found persistent preferred activity:");
6172                    if (ai != null) {
6173                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6174                    } else {
6175                        Slog.v(TAG, "  null");
6176                    }
6177                }
6178                if (ai == null) {
6179                    // This previously registered persistent preferred activity
6180                    // component is no longer known. Ignore it and do NOT remove it.
6181                    continue;
6182                }
6183                for (int j=0; j<N; j++) {
6184                    final ResolveInfo ri = query.get(j);
6185                    if (!ri.activityInfo.applicationInfo.packageName
6186                            .equals(ai.applicationInfo.packageName)) {
6187                        continue;
6188                    }
6189                    if (!ri.activityInfo.name.equals(ai.name)) {
6190                        continue;
6191                    }
6192                    //  Found a persistent preference that can handle the intent.
6193                    if (DEBUG_PREFERRED || debug) {
6194                        Slog.v(TAG, "Returning persistent preferred activity: " +
6195                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6196                    }
6197                    return ri;
6198                }
6199            }
6200        }
6201        return null;
6202    }
6203
6204    // TODO: handle preferred activities missing while user has amnesia
6205    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6206            List<ResolveInfo> query, int priority, boolean always,
6207            boolean removeMatches, boolean debug, int userId) {
6208        if (!sUserManager.exists(userId)) return null;
6209        final int callingUid = Binder.getCallingUid();
6210        flags = updateFlagsForResolve(
6211                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6212        intent = updateIntentForResolve(intent);
6213        // writer
6214        synchronized (mPackages) {
6215            // Try to find a matching persistent preferred activity.
6216            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6217                    debug, userId);
6218
6219            // If a persistent preferred activity matched, use it.
6220            if (pri != null) {
6221                return pri;
6222            }
6223
6224            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6225            // Get the list of preferred activities that handle the intent
6226            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6227            List<PreferredActivity> prefs = pir != null
6228                    ? pir.queryIntent(intent, resolvedType,
6229                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6230                            userId)
6231                    : null;
6232            if (prefs != null && prefs.size() > 0) {
6233                boolean changed = false;
6234                try {
6235                    // First figure out how good the original match set is.
6236                    // We will only allow preferred activities that came
6237                    // from the same match quality.
6238                    int match = 0;
6239
6240                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6241
6242                    final int N = query.size();
6243                    for (int j=0; j<N; j++) {
6244                        final ResolveInfo ri = query.get(j);
6245                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6246                                + ": 0x" + Integer.toHexString(match));
6247                        if (ri.match > match) {
6248                            match = ri.match;
6249                        }
6250                    }
6251
6252                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6253                            + Integer.toHexString(match));
6254
6255                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6256                    final int M = prefs.size();
6257                    for (int i=0; i<M; i++) {
6258                        final PreferredActivity pa = prefs.get(i);
6259                        if (DEBUG_PREFERRED || debug) {
6260                            Slog.v(TAG, "Checking PreferredActivity ds="
6261                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6262                                    + "\n  component=" + pa.mPref.mComponent);
6263                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6264                        }
6265                        if (pa.mPref.mMatch != match) {
6266                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6267                                    + Integer.toHexString(pa.mPref.mMatch));
6268                            continue;
6269                        }
6270                        // If it's not an "always" type preferred activity and that's what we're
6271                        // looking for, skip it.
6272                        if (always && !pa.mPref.mAlways) {
6273                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6274                            continue;
6275                        }
6276                        final ActivityInfo ai = getActivityInfo(
6277                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6278                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6279                                userId);
6280                        if (DEBUG_PREFERRED || debug) {
6281                            Slog.v(TAG, "Found preferred activity:");
6282                            if (ai != null) {
6283                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6284                            } else {
6285                                Slog.v(TAG, "  null");
6286                            }
6287                        }
6288                        if (ai == null) {
6289                            // This previously registered preferred activity
6290                            // component is no longer known.  Most likely an update
6291                            // to the app was installed and in the new version this
6292                            // component no longer exists.  Clean it up by removing
6293                            // it from the preferred activities list, and skip it.
6294                            Slog.w(TAG, "Removing dangling preferred activity: "
6295                                    + pa.mPref.mComponent);
6296                            pir.removeFilter(pa);
6297                            changed = true;
6298                            continue;
6299                        }
6300                        for (int j=0; j<N; j++) {
6301                            final ResolveInfo ri = query.get(j);
6302                            if (!ri.activityInfo.applicationInfo.packageName
6303                                    .equals(ai.applicationInfo.packageName)) {
6304                                continue;
6305                            }
6306                            if (!ri.activityInfo.name.equals(ai.name)) {
6307                                continue;
6308                            }
6309
6310                            if (removeMatches) {
6311                                pir.removeFilter(pa);
6312                                changed = true;
6313                                if (DEBUG_PREFERRED) {
6314                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6315                                }
6316                                break;
6317                            }
6318
6319                            // Okay we found a previously set preferred or last chosen app.
6320                            // If the result set is different from when this
6321                            // was created, and is not a subset of the preferred set, we need to
6322                            // clear it and re-ask the user their preference, if we're looking for
6323                            // an "always" type entry.
6324                            if (always && !pa.mPref.sameSet(query)) {
6325                                if (pa.mPref.isSuperset(query)) {
6326                                    // some components of the set are no longer present in
6327                                    // the query, but the preferred activity can still be reused
6328                                    if (DEBUG_PREFERRED) {
6329                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6330                                                + " still valid as only non-preferred components"
6331                                                + " were removed for " + intent + " type "
6332                                                + resolvedType);
6333                                    }
6334                                    // remove obsolete components and re-add the up-to-date filter
6335                                    PreferredActivity freshPa = new PreferredActivity(pa,
6336                                            pa.mPref.mMatch,
6337                                            pa.mPref.discardObsoleteComponents(query),
6338                                            pa.mPref.mComponent,
6339                                            pa.mPref.mAlways);
6340                                    pir.removeFilter(pa);
6341                                    pir.addFilter(freshPa);
6342                                    changed = true;
6343                                } else {
6344                                    Slog.i(TAG,
6345                                            "Result set changed, dropping preferred activity for "
6346                                                    + intent + " type " + resolvedType);
6347                                    if (DEBUG_PREFERRED) {
6348                                        Slog.v(TAG, "Removing preferred activity since set changed "
6349                                                + pa.mPref.mComponent);
6350                                    }
6351                                    pir.removeFilter(pa);
6352                                    // Re-add the filter as a "last chosen" entry (!always)
6353                                    PreferredActivity lastChosen = new PreferredActivity(
6354                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6355                                    pir.addFilter(lastChosen);
6356                                    changed = true;
6357                                    return null;
6358                                }
6359                            }
6360
6361                            // Yay! Either the set matched or we're looking for the last chosen
6362                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6363                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6364                            return ri;
6365                        }
6366                    }
6367                } finally {
6368                    if (changed) {
6369                        if (DEBUG_PREFERRED) {
6370                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6371                        }
6372                        scheduleWritePackageRestrictionsLocked(userId);
6373                    }
6374                }
6375            }
6376        }
6377        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6378        return null;
6379    }
6380
6381    /*
6382     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6383     */
6384    @Override
6385    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6386            int targetUserId) {
6387        mContext.enforceCallingOrSelfPermission(
6388                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6389        List<CrossProfileIntentFilter> matches =
6390                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6391        if (matches != null) {
6392            int size = matches.size();
6393            for (int i = 0; i < size; i++) {
6394                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6395            }
6396        }
6397        if (intent.hasWebURI()) {
6398            // cross-profile app linking works only towards the parent.
6399            final int callingUid = Binder.getCallingUid();
6400            final UserInfo parent = getProfileParent(sourceUserId);
6401            synchronized(mPackages) {
6402                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6403                        false /*includeInstantApps*/);
6404                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6405                        intent, resolvedType, flags, sourceUserId, parent.id);
6406                return xpDomainInfo != null;
6407            }
6408        }
6409        return false;
6410    }
6411
6412    private UserInfo getProfileParent(int userId) {
6413        final long identity = Binder.clearCallingIdentity();
6414        try {
6415            return sUserManager.getProfileParent(userId);
6416        } finally {
6417            Binder.restoreCallingIdentity(identity);
6418        }
6419    }
6420
6421    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6422            String resolvedType, int userId) {
6423        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6424        if (resolver != null) {
6425            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6426        }
6427        return null;
6428    }
6429
6430    @Override
6431    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6432            String resolvedType, int flags, int userId) {
6433        try {
6434            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6435
6436            return new ParceledListSlice<>(
6437                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6438        } finally {
6439            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6440        }
6441    }
6442
6443    /**
6444     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6445     * instant, returns {@code null}.
6446     */
6447    private String getInstantAppPackageName(int callingUid) {
6448        synchronized (mPackages) {
6449            // If the caller is an isolated app use the owner's uid for the lookup.
6450            if (Process.isIsolated(callingUid)) {
6451                callingUid = mIsolatedOwners.get(callingUid);
6452            }
6453            final int appId = UserHandle.getAppId(callingUid);
6454            final Object obj = mSettings.getUserIdLPr(appId);
6455            if (obj instanceof PackageSetting) {
6456                final PackageSetting ps = (PackageSetting) obj;
6457                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6458                return isInstantApp ? ps.pkg.packageName : null;
6459            }
6460        }
6461        return null;
6462    }
6463
6464    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6465            String resolvedType, int flags, int userId) {
6466        return queryIntentActivitiesInternal(
6467                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6468                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6469    }
6470
6471    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6472            String resolvedType, int flags, int filterCallingUid, int userId,
6473            boolean resolveForStart, boolean allowDynamicSplits) {
6474        if (!sUserManager.exists(userId)) return Collections.emptyList();
6475        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6476        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6477                false /* requireFullPermission */, false /* checkShell */,
6478                "query intent activities");
6479        final String pkgName = intent.getPackage();
6480        ComponentName comp = intent.getComponent();
6481        if (comp == null) {
6482            if (intent.getSelector() != null) {
6483                intent = intent.getSelector();
6484                comp = intent.getComponent();
6485            }
6486        }
6487
6488        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6489                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6490        if (comp != null) {
6491            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6492            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6493            if (ai != null) {
6494                // When specifying an explicit component, we prevent the activity from being
6495                // used when either 1) the calling package is normal and the activity is within
6496                // an ephemeral application or 2) the calling package is ephemeral and the
6497                // activity is not visible to ephemeral applications.
6498                final boolean matchInstantApp =
6499                        (flags & PackageManager.MATCH_INSTANT) != 0;
6500                final boolean matchVisibleToInstantAppOnly =
6501                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6502                final boolean matchExplicitlyVisibleOnly =
6503                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6504                final boolean isCallerInstantApp =
6505                        instantAppPkgName != null;
6506                final boolean isTargetSameInstantApp =
6507                        comp.getPackageName().equals(instantAppPkgName);
6508                final boolean isTargetInstantApp =
6509                        (ai.applicationInfo.privateFlags
6510                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6511                final boolean isTargetVisibleToInstantApp =
6512                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6513                final boolean isTargetExplicitlyVisibleToInstantApp =
6514                        isTargetVisibleToInstantApp
6515                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6516                final boolean isTargetHiddenFromInstantApp =
6517                        !isTargetVisibleToInstantApp
6518                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6519                final boolean blockResolution =
6520                        !isTargetSameInstantApp
6521                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6522                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6523                                        && isTargetHiddenFromInstantApp));
6524                if (!blockResolution) {
6525                    final ResolveInfo ri = new ResolveInfo();
6526                    ri.activityInfo = ai;
6527                    list.add(ri);
6528                }
6529            }
6530            return applyPostResolutionFilter(
6531                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6532        }
6533
6534        // reader
6535        boolean sortResult = false;
6536        boolean addInstant = false;
6537        List<ResolveInfo> result;
6538        synchronized (mPackages) {
6539            if (pkgName == null) {
6540                List<CrossProfileIntentFilter> matchingFilters =
6541                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6542                // Check for results that need to skip the current profile.
6543                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6544                        resolvedType, flags, userId);
6545                if (xpResolveInfo != null) {
6546                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6547                    xpResult.add(xpResolveInfo);
6548                    return applyPostResolutionFilter(
6549                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6550                            allowDynamicSplits, filterCallingUid, userId, intent);
6551                }
6552
6553                // Check for results in the current profile.
6554                result = filterIfNotSystemUser(mActivities.queryIntent(
6555                        intent, resolvedType, flags, userId), userId);
6556                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6557                        false /*skipPackageCheck*/);
6558                // Check for cross profile results.
6559                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6560                xpResolveInfo = queryCrossProfileIntents(
6561                        matchingFilters, intent, resolvedType, flags, userId,
6562                        hasNonNegativePriorityResult);
6563                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6564                    boolean isVisibleToUser = filterIfNotSystemUser(
6565                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6566                    if (isVisibleToUser) {
6567                        result.add(xpResolveInfo);
6568                        sortResult = true;
6569                    }
6570                }
6571                if (intent.hasWebURI()) {
6572                    CrossProfileDomainInfo xpDomainInfo = null;
6573                    final UserInfo parent = getProfileParent(userId);
6574                    if (parent != null) {
6575                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6576                                flags, userId, parent.id);
6577                    }
6578                    if (xpDomainInfo != null) {
6579                        if (xpResolveInfo != null) {
6580                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6581                            // in the result.
6582                            result.remove(xpResolveInfo);
6583                        }
6584                        if (result.size() == 0 && !addInstant) {
6585                            // No result in current profile, but found candidate in parent user.
6586                            // And we are not going to add emphemeral app, so we can return the
6587                            // result straight away.
6588                            result.add(xpDomainInfo.resolveInfo);
6589                            return applyPostResolutionFilter(result, instantAppPkgName,
6590                                    allowDynamicSplits, filterCallingUid, userId, intent);
6591                        }
6592                    } else if (result.size() <= 1 && !addInstant) {
6593                        // No result in parent user and <= 1 result in current profile, and we
6594                        // are not going to add emphemeral app, so we can return the result without
6595                        // further processing.
6596                        return applyPostResolutionFilter(result, instantAppPkgName,
6597                                allowDynamicSplits, filterCallingUid, userId, intent);
6598                    }
6599                    // We have more than one candidate (combining results from current and parent
6600                    // profile), so we need filtering and sorting.
6601                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6602                            intent, flags, result, xpDomainInfo, userId);
6603                    sortResult = true;
6604                }
6605            } else {
6606                final PackageParser.Package pkg = mPackages.get(pkgName);
6607                result = null;
6608                if (pkg != null) {
6609                    result = filterIfNotSystemUser(
6610                            mActivities.queryIntentForPackage(
6611                                    intent, resolvedType, flags, pkg.activities, userId),
6612                            userId);
6613                }
6614                if (result == null || result.size() == 0) {
6615                    // the caller wants to resolve for a particular package; however, there
6616                    // were no installed results, so, try to find an ephemeral result
6617                    addInstant = isInstantAppResolutionAllowed(
6618                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6619                    if (result == null) {
6620                        result = new ArrayList<>();
6621                    }
6622                }
6623            }
6624        }
6625        if (addInstant) {
6626            result = maybeAddInstantAppInstaller(
6627                    result, intent, resolvedType, flags, userId, resolveForStart);
6628        }
6629        if (sortResult) {
6630            Collections.sort(result, mResolvePrioritySorter);
6631        }
6632        return applyPostResolutionFilter(
6633                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6634    }
6635
6636    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6637            String resolvedType, int flags, int userId, boolean resolveForStart) {
6638        // first, check to see if we've got an instant app already installed
6639        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6640        ResolveInfo localInstantApp = null;
6641        boolean blockResolution = false;
6642        if (!alreadyResolvedLocally) {
6643            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6644                    flags
6645                        | PackageManager.GET_RESOLVED_FILTER
6646                        | PackageManager.MATCH_INSTANT
6647                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6648                    userId);
6649            for (int i = instantApps.size() - 1; i >= 0; --i) {
6650                final ResolveInfo info = instantApps.get(i);
6651                final String packageName = info.activityInfo.packageName;
6652                final PackageSetting ps = mSettings.mPackages.get(packageName);
6653                if (ps.getInstantApp(userId)) {
6654                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6655                    final int status = (int)(packedStatus >> 32);
6656                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6657                        // there's a local instant application installed, but, the user has
6658                        // chosen to never use it; skip resolution and don't acknowledge
6659                        // an instant application is even available
6660                        if (DEBUG_INSTANT) {
6661                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6662                        }
6663                        blockResolution = true;
6664                        break;
6665                    } else {
6666                        // we have a locally installed instant application; skip resolution
6667                        // but acknowledge there's an instant application available
6668                        if (DEBUG_INSTANT) {
6669                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6670                        }
6671                        localInstantApp = info;
6672                        break;
6673                    }
6674                }
6675            }
6676        }
6677        // no app installed, let's see if one's available
6678        AuxiliaryResolveInfo auxiliaryResponse = null;
6679        if (!blockResolution) {
6680            if (localInstantApp == null) {
6681                // we don't have an instant app locally, resolve externally
6682                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6683                final InstantAppRequest requestObject = new InstantAppRequest(
6684                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6685                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6686                        resolveForStart);
6687                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
6688                        mInstantAppResolverConnection, requestObject);
6689                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6690            } else {
6691                // we have an instant application locally, but, we can't admit that since
6692                // callers shouldn't be able to determine prior browsing. create a dummy
6693                // auxiliary response so the downstream code behaves as if there's an
6694                // instant application available externally. when it comes time to start
6695                // the instant application, we'll do the right thing.
6696                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6697                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
6698                                        ai.packageName, ai.versionCode, null /* splitName */);
6699            }
6700        }
6701        if (intent.isWebIntent() && auxiliaryResponse == null) {
6702            return result;
6703        }
6704        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6705        if (ps == null
6706                || ps.getUserState().get(userId) == null
6707                || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
6708            return result;
6709        }
6710        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6711        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6712                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6713        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6714                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6715        // add a non-generic filter
6716        ephemeralInstaller.filter = new IntentFilter();
6717        if (intent.getAction() != null) {
6718            ephemeralInstaller.filter.addAction(intent.getAction());
6719        }
6720        if (intent.getData() != null && intent.getData().getPath() != null) {
6721            ephemeralInstaller.filter.addDataPath(
6722                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6723        }
6724        ephemeralInstaller.isInstantAppAvailable = true;
6725        // make sure this resolver is the default
6726        ephemeralInstaller.isDefault = true;
6727        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6728        if (DEBUG_INSTANT) {
6729            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6730        }
6731
6732        result.add(ephemeralInstaller);
6733        return result;
6734    }
6735
6736    private static class CrossProfileDomainInfo {
6737        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6738        ResolveInfo resolveInfo;
6739        /* Best domain verification status of the activities found in the other profile */
6740        int bestDomainVerificationStatus;
6741    }
6742
6743    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6744            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6745        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6746                sourceUserId)) {
6747            return null;
6748        }
6749        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6750                resolvedType, flags, parentUserId);
6751
6752        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6753            return null;
6754        }
6755        CrossProfileDomainInfo result = null;
6756        int size = resultTargetUser.size();
6757        for (int i = 0; i < size; i++) {
6758            ResolveInfo riTargetUser = resultTargetUser.get(i);
6759            // Intent filter verification is only for filters that specify a host. So don't return
6760            // those that handle all web uris.
6761            if (riTargetUser.handleAllWebDataURI) {
6762                continue;
6763            }
6764            String packageName = riTargetUser.activityInfo.packageName;
6765            PackageSetting ps = mSettings.mPackages.get(packageName);
6766            if (ps == null) {
6767                continue;
6768            }
6769            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6770            int status = (int)(verificationState >> 32);
6771            if (result == null) {
6772                result = new CrossProfileDomainInfo();
6773                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6774                        sourceUserId, parentUserId);
6775                result.bestDomainVerificationStatus = status;
6776            } else {
6777                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6778                        result.bestDomainVerificationStatus);
6779            }
6780        }
6781        // Don't consider matches with status NEVER across profiles.
6782        if (result != null && result.bestDomainVerificationStatus
6783                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6784            return null;
6785        }
6786        return result;
6787    }
6788
6789    /**
6790     * Verification statuses are ordered from the worse to the best, except for
6791     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6792     */
6793    private int bestDomainVerificationStatus(int status1, int status2) {
6794        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6795            return status2;
6796        }
6797        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6798            return status1;
6799        }
6800        return (int) MathUtils.max(status1, status2);
6801    }
6802
6803    private boolean isUserEnabled(int userId) {
6804        long callingId = Binder.clearCallingIdentity();
6805        try {
6806            UserInfo userInfo = sUserManager.getUserInfo(userId);
6807            return userInfo != null && userInfo.isEnabled();
6808        } finally {
6809            Binder.restoreCallingIdentity(callingId);
6810        }
6811    }
6812
6813    /**
6814     * Filter out activities with systemUserOnly flag set, when current user is not System.
6815     *
6816     * @return filtered list
6817     */
6818    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6819        if (userId == UserHandle.USER_SYSTEM) {
6820            return resolveInfos;
6821        }
6822        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6823            ResolveInfo info = resolveInfos.get(i);
6824            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6825                resolveInfos.remove(i);
6826            }
6827        }
6828        return resolveInfos;
6829    }
6830
6831    /**
6832     * Filters out ephemeral activities.
6833     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6834     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6835     *
6836     * @param resolveInfos The pre-filtered list of resolved activities
6837     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6838     *          is performed.
6839     * @param intent
6840     * @return A filtered list of resolved activities.
6841     */
6842    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6843            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId,
6844            Intent intent) {
6845        final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled();
6846        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6847            final ResolveInfo info = resolveInfos.get(i);
6848            // remove locally resolved instant app web results when disabled
6849            if (info.isInstantAppAvailable && blockInstant) {
6850                resolveInfos.remove(i);
6851                continue;
6852            }
6853            // allow activities that are defined in the provided package
6854            if (allowDynamicSplits
6855                    && info.activityInfo != null
6856                    && info.activityInfo.splitName != null
6857                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6858                            info.activityInfo.splitName)) {
6859                if (mInstantAppInstallerActivity == null) {
6860                    if (DEBUG_INSTALL) {
6861                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6862                    }
6863                    resolveInfos.remove(i);
6864                    continue;
6865                }
6866                if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
6867                    resolveInfos.remove(i);
6868                    continue;
6869                }
6870                // requested activity is defined in a split that hasn't been installed yet.
6871                // add the installer to the resolve list
6872                if (DEBUG_INSTALL) {
6873                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6874                }
6875                final ResolveInfo installerInfo = new ResolveInfo(
6876                        mInstantAppInstallerInfo);
6877                final ComponentName installFailureActivity = findInstallFailureActivity(
6878                        info.activityInfo.packageName,  filterCallingUid, userId);
6879                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6880                        installFailureActivity,
6881                        info.activityInfo.packageName,
6882                        info.activityInfo.applicationInfo.versionCode,
6883                        info.activityInfo.splitName);
6884                // add a non-generic filter
6885                installerInfo.filter = new IntentFilter();
6886
6887                // This resolve info may appear in the chooser UI, so let us make it
6888                // look as the one it replaces as far as the user is concerned which
6889                // requires loading the correct label and icon for the resolve info.
6890                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6891                installerInfo.labelRes = info.resolveLabelResId();
6892                installerInfo.icon = info.resolveIconResId();
6893                installerInfo.isInstantAppAvailable = true;
6894                resolveInfos.set(i, installerInfo);
6895                continue;
6896            }
6897            // caller is a full app, don't need to apply any other filtering
6898            if (ephemeralPkgName == null) {
6899                continue;
6900            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6901                // caller is same app; don't need to apply any other filtering
6902                continue;
6903            }
6904            // allow activities that have been explicitly exposed to ephemeral apps
6905            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6906            if (!isEphemeralApp
6907                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6908                continue;
6909            }
6910            resolveInfos.remove(i);
6911        }
6912        return resolveInfos;
6913    }
6914
6915    /**
6916     * Returns the activity component that can handle install failures.
6917     * <p>By default, the instant application installer handles failures. However, an
6918     * application may want to handle failures on its own. Applications do this by
6919     * creating an activity with an intent filter that handles the action
6920     * {@link Intent#ACTION_INSTALL_FAILURE}.
6921     */
6922    private @Nullable ComponentName findInstallFailureActivity(
6923            String packageName, int filterCallingUid, int userId) {
6924        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6925        failureActivityIntent.setPackage(packageName);
6926        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6927        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6928                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6929                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6930        final int NR = result.size();
6931        if (NR > 0) {
6932            for (int i = 0; i < NR; i++) {
6933                final ResolveInfo info = result.get(i);
6934                if (info.activityInfo.splitName != null) {
6935                    continue;
6936                }
6937                return new ComponentName(packageName, info.activityInfo.name);
6938            }
6939        }
6940        return null;
6941    }
6942
6943    /**
6944     * @param resolveInfos list of resolve infos in descending priority order
6945     * @return if the list contains a resolve info with non-negative priority
6946     */
6947    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6948        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6949    }
6950
6951    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6952            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6953            int userId) {
6954        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6955
6956        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6957            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6958                    candidates.size());
6959        }
6960
6961        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6962        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6963        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6964        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6965        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6966        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6967
6968        synchronized (mPackages) {
6969            final int count = candidates.size();
6970            // First, try to use linked apps. Partition the candidates into four lists:
6971            // one for the final results, one for the "do not use ever", one for "undefined status"
6972            // and finally one for "browser app type".
6973            for (int n=0; n<count; n++) {
6974                ResolveInfo info = candidates.get(n);
6975                String packageName = info.activityInfo.packageName;
6976                PackageSetting ps = mSettings.mPackages.get(packageName);
6977                if (ps != null) {
6978                    // Add to the special match all list (Browser use case)
6979                    if (info.handleAllWebDataURI) {
6980                        matchAllList.add(info);
6981                        continue;
6982                    }
6983                    // Try to get the status from User settings first
6984                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6985                    int status = (int)(packedStatus >> 32);
6986                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6987                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6988                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6989                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6990                                    + " : linkgen=" + linkGeneration);
6991                        }
6992                        // Use link-enabled generation as preferredOrder, i.e.
6993                        // prefer newly-enabled over earlier-enabled.
6994                        info.preferredOrder = linkGeneration;
6995                        alwaysList.add(info);
6996                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6997                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6998                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6999                        }
7000                        neverList.add(info);
7001                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7002                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7003                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7004                        }
7005                        alwaysAskList.add(info);
7006                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7007                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7008                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7009                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7010                        }
7011                        undefinedList.add(info);
7012                    }
7013                }
7014            }
7015
7016            // We'll want to include browser possibilities in a few cases
7017            boolean includeBrowser = false;
7018
7019            // First try to add the "always" resolution(s) for the current user, if any
7020            if (alwaysList.size() > 0) {
7021                result.addAll(alwaysList);
7022            } else {
7023                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7024                result.addAll(undefinedList);
7025                // Maybe add one for the other profile.
7026                if (xpDomainInfo != null && (
7027                        xpDomainInfo.bestDomainVerificationStatus
7028                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7029                    result.add(xpDomainInfo.resolveInfo);
7030                }
7031                includeBrowser = true;
7032            }
7033
7034            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7035            // If there were 'always' entries their preferred order has been set, so we also
7036            // back that off to make the alternatives equivalent
7037            if (alwaysAskList.size() > 0) {
7038                for (ResolveInfo i : result) {
7039                    i.preferredOrder = 0;
7040                }
7041                result.addAll(alwaysAskList);
7042                includeBrowser = true;
7043            }
7044
7045            if (includeBrowser) {
7046                // Also add browsers (all of them or only the default one)
7047                if (DEBUG_DOMAIN_VERIFICATION) {
7048                    Slog.v(TAG, "   ...including browsers in candidate set");
7049                }
7050                if ((matchFlags & MATCH_ALL) != 0) {
7051                    result.addAll(matchAllList);
7052                } else {
7053                    // Browser/generic handling case.  If there's a default browser, go straight
7054                    // to that (but only if there is no other higher-priority match).
7055                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7056                    int maxMatchPrio = 0;
7057                    ResolveInfo defaultBrowserMatch = null;
7058                    final int numCandidates = matchAllList.size();
7059                    for (int n = 0; n < numCandidates; n++) {
7060                        ResolveInfo info = matchAllList.get(n);
7061                        // track the highest overall match priority...
7062                        if (info.priority > maxMatchPrio) {
7063                            maxMatchPrio = info.priority;
7064                        }
7065                        // ...and the highest-priority default browser match
7066                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7067                            if (defaultBrowserMatch == null
7068                                    || (defaultBrowserMatch.priority < info.priority)) {
7069                                if (debug) {
7070                                    Slog.v(TAG, "Considering default browser match " + info);
7071                                }
7072                                defaultBrowserMatch = info;
7073                            }
7074                        }
7075                    }
7076                    if (defaultBrowserMatch != null
7077                            && defaultBrowserMatch.priority >= maxMatchPrio
7078                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7079                    {
7080                        if (debug) {
7081                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7082                        }
7083                        result.add(defaultBrowserMatch);
7084                    } else {
7085                        result.addAll(matchAllList);
7086                    }
7087                }
7088
7089                // If there is nothing selected, add all candidates and remove the ones that the user
7090                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7091                if (result.size() == 0) {
7092                    result.addAll(candidates);
7093                    result.removeAll(neverList);
7094                }
7095            }
7096        }
7097        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7098            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7099                    result.size());
7100            for (ResolveInfo info : result) {
7101                Slog.v(TAG, "  + " + info.activityInfo);
7102            }
7103        }
7104        return result;
7105    }
7106
7107    // Returns a packed value as a long:
7108    //
7109    // high 'int'-sized word: link status: undefined/ask/never/always.
7110    // low 'int'-sized word: relative priority among 'always' results.
7111    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7112        long result = ps.getDomainVerificationStatusForUser(userId);
7113        // if none available, get the master status
7114        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7115            if (ps.getIntentFilterVerificationInfo() != null) {
7116                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7117            }
7118        }
7119        return result;
7120    }
7121
7122    private ResolveInfo querySkipCurrentProfileIntents(
7123            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7124            int flags, int sourceUserId) {
7125        if (matchingFilters != null) {
7126            int size = matchingFilters.size();
7127            for (int i = 0; i < size; i ++) {
7128                CrossProfileIntentFilter filter = matchingFilters.get(i);
7129                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7130                    // Checking if there are activities in the target user that can handle the
7131                    // intent.
7132                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7133                            resolvedType, flags, sourceUserId);
7134                    if (resolveInfo != null) {
7135                        return resolveInfo;
7136                    }
7137                }
7138            }
7139        }
7140        return null;
7141    }
7142
7143    // Return matching ResolveInfo in target user if any.
7144    private ResolveInfo queryCrossProfileIntents(
7145            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7146            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7147        if (matchingFilters != null) {
7148            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7149            // match the same intent. For performance reasons, it is better not to
7150            // run queryIntent twice for the same userId
7151            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7152            int size = matchingFilters.size();
7153            for (int i = 0; i < size; i++) {
7154                CrossProfileIntentFilter filter = matchingFilters.get(i);
7155                int targetUserId = filter.getTargetUserId();
7156                boolean skipCurrentProfile =
7157                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7158                boolean skipCurrentProfileIfNoMatchFound =
7159                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7160                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7161                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7162                    // Checking if there are activities in the target user that can handle the
7163                    // intent.
7164                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7165                            resolvedType, flags, sourceUserId);
7166                    if (resolveInfo != null) return resolveInfo;
7167                    alreadyTriedUserIds.put(targetUserId, true);
7168                }
7169            }
7170        }
7171        return null;
7172    }
7173
7174    /**
7175     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7176     * will forward the intent to the filter's target user.
7177     * Otherwise, returns null.
7178     */
7179    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7180            String resolvedType, int flags, int sourceUserId) {
7181        int targetUserId = filter.getTargetUserId();
7182        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7183                resolvedType, flags, targetUserId);
7184        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7185            // If all the matches in the target profile are suspended, return null.
7186            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7187                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7188                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7189                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7190                            targetUserId);
7191                }
7192            }
7193        }
7194        return null;
7195    }
7196
7197    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7198            int sourceUserId, int targetUserId) {
7199        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7200        long ident = Binder.clearCallingIdentity();
7201        boolean targetIsProfile;
7202        try {
7203            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7204        } finally {
7205            Binder.restoreCallingIdentity(ident);
7206        }
7207        String className;
7208        if (targetIsProfile) {
7209            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7210        } else {
7211            className = FORWARD_INTENT_TO_PARENT;
7212        }
7213        ComponentName forwardingActivityComponentName = new ComponentName(
7214                mAndroidApplication.packageName, className);
7215        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7216                sourceUserId);
7217        if (!targetIsProfile) {
7218            forwardingActivityInfo.showUserIcon = targetUserId;
7219            forwardingResolveInfo.noResourceId = true;
7220        }
7221        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7222        forwardingResolveInfo.priority = 0;
7223        forwardingResolveInfo.preferredOrder = 0;
7224        forwardingResolveInfo.match = 0;
7225        forwardingResolveInfo.isDefault = true;
7226        forwardingResolveInfo.filter = filter;
7227        forwardingResolveInfo.targetUserId = targetUserId;
7228        return forwardingResolveInfo;
7229    }
7230
7231    @Override
7232    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7233            Intent[] specifics, String[] specificTypes, Intent intent,
7234            String resolvedType, int flags, int userId) {
7235        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7236                specificTypes, intent, resolvedType, flags, userId));
7237    }
7238
7239    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7240            Intent[] specifics, String[] specificTypes, Intent intent,
7241            String resolvedType, int flags, int userId) {
7242        if (!sUserManager.exists(userId)) return Collections.emptyList();
7243        final int callingUid = Binder.getCallingUid();
7244        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7245                false /*includeInstantApps*/);
7246        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7247                false /*requireFullPermission*/, false /*checkShell*/,
7248                "query intent activity options");
7249        final String resultsAction = intent.getAction();
7250
7251        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7252                | PackageManager.GET_RESOLVED_FILTER, userId);
7253
7254        if (DEBUG_INTENT_MATCHING) {
7255            Log.v(TAG, "Query " + intent + ": " + results);
7256        }
7257
7258        int specificsPos = 0;
7259        int N;
7260
7261        // todo: note that the algorithm used here is O(N^2).  This
7262        // isn't a problem in our current environment, but if we start running
7263        // into situations where we have more than 5 or 10 matches then this
7264        // should probably be changed to something smarter...
7265
7266        // First we go through and resolve each of the specific items
7267        // that were supplied, taking care of removing any corresponding
7268        // duplicate items in the generic resolve list.
7269        if (specifics != null) {
7270            for (int i=0; i<specifics.length; i++) {
7271                final Intent sintent = specifics[i];
7272                if (sintent == null) {
7273                    continue;
7274                }
7275
7276                if (DEBUG_INTENT_MATCHING) {
7277                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7278                }
7279
7280                String action = sintent.getAction();
7281                if (resultsAction != null && resultsAction.equals(action)) {
7282                    // If this action was explicitly requested, then don't
7283                    // remove things that have it.
7284                    action = null;
7285                }
7286
7287                ResolveInfo ri = null;
7288                ActivityInfo ai = null;
7289
7290                ComponentName comp = sintent.getComponent();
7291                if (comp == null) {
7292                    ri = resolveIntent(
7293                        sintent,
7294                        specificTypes != null ? specificTypes[i] : null,
7295                            flags, userId);
7296                    if (ri == null) {
7297                        continue;
7298                    }
7299                    if (ri == mResolveInfo) {
7300                        // ACK!  Must do something better with this.
7301                    }
7302                    ai = ri.activityInfo;
7303                    comp = new ComponentName(ai.applicationInfo.packageName,
7304                            ai.name);
7305                } else {
7306                    ai = getActivityInfo(comp, flags, userId);
7307                    if (ai == null) {
7308                        continue;
7309                    }
7310                }
7311
7312                // Look for any generic query activities that are duplicates
7313                // of this specific one, and remove them from the results.
7314                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7315                N = results.size();
7316                int j;
7317                for (j=specificsPos; j<N; j++) {
7318                    ResolveInfo sri = results.get(j);
7319                    if ((sri.activityInfo.name.equals(comp.getClassName())
7320                            && sri.activityInfo.applicationInfo.packageName.equals(
7321                                    comp.getPackageName()))
7322                        || (action != null && sri.filter.matchAction(action))) {
7323                        results.remove(j);
7324                        if (DEBUG_INTENT_MATCHING) Log.v(
7325                            TAG, "Removing duplicate item from " + j
7326                            + " due to specific " + specificsPos);
7327                        if (ri == null) {
7328                            ri = sri;
7329                        }
7330                        j--;
7331                        N--;
7332                    }
7333                }
7334
7335                // Add this specific item to its proper place.
7336                if (ri == null) {
7337                    ri = new ResolveInfo();
7338                    ri.activityInfo = ai;
7339                }
7340                results.add(specificsPos, ri);
7341                ri.specificIndex = i;
7342                specificsPos++;
7343            }
7344        }
7345
7346        // Now we go through the remaining generic results and remove any
7347        // duplicate actions that are found here.
7348        N = results.size();
7349        for (int i=specificsPos; i<N-1; i++) {
7350            final ResolveInfo rii = results.get(i);
7351            if (rii.filter == null) {
7352                continue;
7353            }
7354
7355            // Iterate over all of the actions of this result's intent
7356            // filter...  typically this should be just one.
7357            final Iterator<String> it = rii.filter.actionsIterator();
7358            if (it == null) {
7359                continue;
7360            }
7361            while (it.hasNext()) {
7362                final String action = it.next();
7363                if (resultsAction != null && resultsAction.equals(action)) {
7364                    // If this action was explicitly requested, then don't
7365                    // remove things that have it.
7366                    continue;
7367                }
7368                for (int j=i+1; j<N; j++) {
7369                    final ResolveInfo rij = results.get(j);
7370                    if (rij.filter != null && rij.filter.hasAction(action)) {
7371                        results.remove(j);
7372                        if (DEBUG_INTENT_MATCHING) Log.v(
7373                            TAG, "Removing duplicate item from " + j
7374                            + " due to action " + action + " at " + i);
7375                        j--;
7376                        N--;
7377                    }
7378                }
7379            }
7380
7381            // If the caller didn't request filter information, drop it now
7382            // so we don't have to marshall/unmarshall it.
7383            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7384                rii.filter = null;
7385            }
7386        }
7387
7388        // Filter out the caller activity if so requested.
7389        if (caller != null) {
7390            N = results.size();
7391            for (int i=0; i<N; i++) {
7392                ActivityInfo ainfo = results.get(i).activityInfo;
7393                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7394                        && caller.getClassName().equals(ainfo.name)) {
7395                    results.remove(i);
7396                    break;
7397                }
7398            }
7399        }
7400
7401        // If the caller didn't request filter information,
7402        // drop them now so we don't have to
7403        // marshall/unmarshall it.
7404        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7405            N = results.size();
7406            for (int i=0; i<N; i++) {
7407                results.get(i).filter = null;
7408            }
7409        }
7410
7411        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7412        return results;
7413    }
7414
7415    @Override
7416    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7417            String resolvedType, int flags, int userId) {
7418        return new ParceledListSlice<>(
7419                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7420                        false /*allowDynamicSplits*/));
7421    }
7422
7423    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7424            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7425        if (!sUserManager.exists(userId)) return Collections.emptyList();
7426        final int callingUid = Binder.getCallingUid();
7427        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7428                false /*requireFullPermission*/, false /*checkShell*/,
7429                "query intent receivers");
7430        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7431        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7432                false /*includeInstantApps*/);
7433        ComponentName comp = intent.getComponent();
7434        if (comp == null) {
7435            if (intent.getSelector() != null) {
7436                intent = intent.getSelector();
7437                comp = intent.getComponent();
7438            }
7439        }
7440        if (comp != null) {
7441            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7442            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7443            if (ai != null) {
7444                // When specifying an explicit component, we prevent the activity from being
7445                // used when either 1) the calling package is normal and the activity is within
7446                // an instant application or 2) the calling package is ephemeral and the
7447                // activity is not visible to instant applications.
7448                final boolean matchInstantApp =
7449                        (flags & PackageManager.MATCH_INSTANT) != 0;
7450                final boolean matchVisibleToInstantAppOnly =
7451                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7452                final boolean matchExplicitlyVisibleOnly =
7453                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7454                final boolean isCallerInstantApp =
7455                        instantAppPkgName != null;
7456                final boolean isTargetSameInstantApp =
7457                        comp.getPackageName().equals(instantAppPkgName);
7458                final boolean isTargetInstantApp =
7459                        (ai.applicationInfo.privateFlags
7460                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7461                final boolean isTargetVisibleToInstantApp =
7462                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7463                final boolean isTargetExplicitlyVisibleToInstantApp =
7464                        isTargetVisibleToInstantApp
7465                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7466                final boolean isTargetHiddenFromInstantApp =
7467                        !isTargetVisibleToInstantApp
7468                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7469                final boolean blockResolution =
7470                        !isTargetSameInstantApp
7471                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7472                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7473                                        && isTargetHiddenFromInstantApp));
7474                if (!blockResolution) {
7475                    ResolveInfo ri = new ResolveInfo();
7476                    ri.activityInfo = ai;
7477                    list.add(ri);
7478                }
7479            }
7480            return applyPostResolutionFilter(
7481                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7482        }
7483
7484        // reader
7485        synchronized (mPackages) {
7486            String pkgName = intent.getPackage();
7487            if (pkgName == null) {
7488                final List<ResolveInfo> result =
7489                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7490                return applyPostResolutionFilter(
7491                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7492            }
7493            final PackageParser.Package pkg = mPackages.get(pkgName);
7494            if (pkg != null) {
7495                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7496                        intent, resolvedType, flags, pkg.receivers, userId);
7497                return applyPostResolutionFilter(
7498                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7499            }
7500            return Collections.emptyList();
7501        }
7502    }
7503
7504    @Override
7505    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7506        final int callingUid = Binder.getCallingUid();
7507        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7508    }
7509
7510    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7511            int userId, int callingUid) {
7512        if (!sUserManager.exists(userId)) return null;
7513        flags = updateFlagsForResolve(
7514                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7515        List<ResolveInfo> query = queryIntentServicesInternal(
7516                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7517        if (query != null) {
7518            if (query.size() >= 1) {
7519                // If there is more than one service with the same priority,
7520                // just arbitrarily pick the first one.
7521                return query.get(0);
7522            }
7523        }
7524        return null;
7525    }
7526
7527    @Override
7528    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7529            String resolvedType, int flags, int userId) {
7530        final int callingUid = Binder.getCallingUid();
7531        return new ParceledListSlice<>(queryIntentServicesInternal(
7532                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7533    }
7534
7535    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7536            String resolvedType, int flags, int userId, int callingUid,
7537            boolean includeInstantApps) {
7538        if (!sUserManager.exists(userId)) return Collections.emptyList();
7539        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7540                false /*requireFullPermission*/, false /*checkShell*/,
7541                "query intent receivers");
7542        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7543        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7544        ComponentName comp = intent.getComponent();
7545        if (comp == null) {
7546            if (intent.getSelector() != null) {
7547                intent = intent.getSelector();
7548                comp = intent.getComponent();
7549            }
7550        }
7551        if (comp != null) {
7552            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7553            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7554            if (si != null) {
7555                // When specifying an explicit component, we prevent the service from being
7556                // used when either 1) the service is in an instant application and the
7557                // caller is not the same instant application or 2) the calling package is
7558                // ephemeral and the activity is not visible to ephemeral applications.
7559                final boolean matchInstantApp =
7560                        (flags & PackageManager.MATCH_INSTANT) != 0;
7561                final boolean matchVisibleToInstantAppOnly =
7562                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7563                final boolean isCallerInstantApp =
7564                        instantAppPkgName != null;
7565                final boolean isTargetSameInstantApp =
7566                        comp.getPackageName().equals(instantAppPkgName);
7567                final boolean isTargetInstantApp =
7568                        (si.applicationInfo.privateFlags
7569                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7570                final boolean isTargetHiddenFromInstantApp =
7571                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7572                final boolean blockResolution =
7573                        !isTargetSameInstantApp
7574                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7575                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7576                                        && isTargetHiddenFromInstantApp));
7577                if (!blockResolution) {
7578                    final ResolveInfo ri = new ResolveInfo();
7579                    ri.serviceInfo = si;
7580                    list.add(ri);
7581                }
7582            }
7583            return list;
7584        }
7585
7586        // reader
7587        synchronized (mPackages) {
7588            String pkgName = intent.getPackage();
7589            if (pkgName == null) {
7590                return applyPostServiceResolutionFilter(
7591                        mServices.queryIntent(intent, resolvedType, flags, userId),
7592                        instantAppPkgName);
7593            }
7594            final PackageParser.Package pkg = mPackages.get(pkgName);
7595            if (pkg != null) {
7596                return applyPostServiceResolutionFilter(
7597                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7598                                userId),
7599                        instantAppPkgName);
7600            }
7601            return Collections.emptyList();
7602        }
7603    }
7604
7605    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7606            String instantAppPkgName) {
7607        if (instantAppPkgName == null) {
7608            return resolveInfos;
7609        }
7610        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7611            final ResolveInfo info = resolveInfos.get(i);
7612            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7613            // allow services that are defined in the provided package
7614            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7615                if (info.serviceInfo.splitName != null
7616                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7617                                info.serviceInfo.splitName)) {
7618                    // requested service is defined in a split that hasn't been installed yet.
7619                    // add the installer to the resolve list
7620                    if (DEBUG_INSTANT) {
7621                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7622                    }
7623                    final ResolveInfo installerInfo = new ResolveInfo(
7624                            mInstantAppInstallerInfo);
7625                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7626                            null /* installFailureActivity */,
7627                            info.serviceInfo.packageName,
7628                            info.serviceInfo.applicationInfo.versionCode,
7629                            info.serviceInfo.splitName);
7630                    // add a non-generic filter
7631                    installerInfo.filter = new IntentFilter();
7632                    // load resources from the correct package
7633                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7634                    resolveInfos.set(i, installerInfo);
7635                }
7636                continue;
7637            }
7638            // allow services that have been explicitly exposed to ephemeral apps
7639            if (!isEphemeralApp
7640                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7641                continue;
7642            }
7643            resolveInfos.remove(i);
7644        }
7645        return resolveInfos;
7646    }
7647
7648    @Override
7649    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7650            String resolvedType, int flags, int userId) {
7651        return new ParceledListSlice<>(
7652                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7653    }
7654
7655    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7656            Intent intent, String resolvedType, int flags, int userId) {
7657        if (!sUserManager.exists(userId)) return Collections.emptyList();
7658        final int callingUid = Binder.getCallingUid();
7659        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7660        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7661                false /*includeInstantApps*/);
7662        ComponentName comp = intent.getComponent();
7663        if (comp == null) {
7664            if (intent.getSelector() != null) {
7665                intent = intent.getSelector();
7666                comp = intent.getComponent();
7667            }
7668        }
7669        if (comp != null) {
7670            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7671            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7672            if (pi != null) {
7673                // When specifying an explicit component, we prevent the provider from being
7674                // used when either 1) the provider is in an instant application and the
7675                // caller is not the same instant application or 2) the calling package is an
7676                // instant application and the provider is not visible to instant applications.
7677                final boolean matchInstantApp =
7678                        (flags & PackageManager.MATCH_INSTANT) != 0;
7679                final boolean matchVisibleToInstantAppOnly =
7680                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7681                final boolean isCallerInstantApp =
7682                        instantAppPkgName != null;
7683                final boolean isTargetSameInstantApp =
7684                        comp.getPackageName().equals(instantAppPkgName);
7685                final boolean isTargetInstantApp =
7686                        (pi.applicationInfo.privateFlags
7687                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7688                final boolean isTargetHiddenFromInstantApp =
7689                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7690                final boolean blockResolution =
7691                        !isTargetSameInstantApp
7692                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7693                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7694                                        && isTargetHiddenFromInstantApp));
7695                if (!blockResolution) {
7696                    final ResolveInfo ri = new ResolveInfo();
7697                    ri.providerInfo = pi;
7698                    list.add(ri);
7699                }
7700            }
7701            return list;
7702        }
7703
7704        // reader
7705        synchronized (mPackages) {
7706            String pkgName = intent.getPackage();
7707            if (pkgName == null) {
7708                return applyPostContentProviderResolutionFilter(
7709                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7710                        instantAppPkgName);
7711            }
7712            final PackageParser.Package pkg = mPackages.get(pkgName);
7713            if (pkg != null) {
7714                return applyPostContentProviderResolutionFilter(
7715                        mProviders.queryIntentForPackage(
7716                        intent, resolvedType, flags, pkg.providers, userId),
7717                        instantAppPkgName);
7718            }
7719            return Collections.emptyList();
7720        }
7721    }
7722
7723    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7724            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7725        if (instantAppPkgName == null) {
7726            return resolveInfos;
7727        }
7728        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7729            final ResolveInfo info = resolveInfos.get(i);
7730            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7731            // allow providers that are defined in the provided package
7732            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7733                if (info.providerInfo.splitName != null
7734                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7735                                info.providerInfo.splitName)) {
7736                    // requested provider is defined in a split that hasn't been installed yet.
7737                    // add the installer to the resolve list
7738                    if (DEBUG_INSTANT) {
7739                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7740                    }
7741                    final ResolveInfo installerInfo = new ResolveInfo(
7742                            mInstantAppInstallerInfo);
7743                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7744                            null /*failureActivity*/,
7745                            info.providerInfo.packageName,
7746                            info.providerInfo.applicationInfo.versionCode,
7747                            info.providerInfo.splitName);
7748                    // add a non-generic filter
7749                    installerInfo.filter = new IntentFilter();
7750                    // load resources from the correct package
7751                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7752                    resolveInfos.set(i, installerInfo);
7753                }
7754                continue;
7755            }
7756            // allow providers that have been explicitly exposed to instant applications
7757            if (!isEphemeralApp
7758                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7759                continue;
7760            }
7761            resolveInfos.remove(i);
7762        }
7763        return resolveInfos;
7764    }
7765
7766    @Override
7767    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7768        final int callingUid = Binder.getCallingUid();
7769        if (getInstantAppPackageName(callingUid) != null) {
7770            return ParceledListSlice.emptyList();
7771        }
7772        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7773        flags = updateFlagsForPackage(flags, userId, null);
7774        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7775        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7776                true /* requireFullPermission */, false /* checkShell */,
7777                "get installed packages");
7778
7779        // writer
7780        synchronized (mPackages) {
7781            ArrayList<PackageInfo> list;
7782            if (listUninstalled) {
7783                list = new ArrayList<>(mSettings.mPackages.size());
7784                for (PackageSetting ps : mSettings.mPackages.values()) {
7785                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7786                        continue;
7787                    }
7788                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7789                        continue;
7790                    }
7791                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7792                    if (pi != null) {
7793                        list.add(pi);
7794                    }
7795                }
7796            } else {
7797                list = new ArrayList<>(mPackages.size());
7798                for (PackageParser.Package p : mPackages.values()) {
7799                    final PackageSetting ps = (PackageSetting) p.mExtras;
7800                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7801                        continue;
7802                    }
7803                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7804                        continue;
7805                    }
7806                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7807                            p.mExtras, flags, userId);
7808                    if (pi != null) {
7809                        list.add(pi);
7810                    }
7811                }
7812            }
7813
7814            return new ParceledListSlice<>(list);
7815        }
7816    }
7817
7818    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7819            String[] permissions, boolean[] tmp, int flags, int userId) {
7820        int numMatch = 0;
7821        final PermissionsState permissionsState = ps.getPermissionsState();
7822        for (int i=0; i<permissions.length; i++) {
7823            final String permission = permissions[i];
7824            if (permissionsState.hasPermission(permission, userId)) {
7825                tmp[i] = true;
7826                numMatch++;
7827            } else {
7828                tmp[i] = false;
7829            }
7830        }
7831        if (numMatch == 0) {
7832            return;
7833        }
7834        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7835
7836        // The above might return null in cases of uninstalled apps or install-state
7837        // skew across users/profiles.
7838        if (pi != null) {
7839            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7840                if (numMatch == permissions.length) {
7841                    pi.requestedPermissions = permissions;
7842                } else {
7843                    pi.requestedPermissions = new String[numMatch];
7844                    numMatch = 0;
7845                    for (int i=0; i<permissions.length; i++) {
7846                        if (tmp[i]) {
7847                            pi.requestedPermissions[numMatch] = permissions[i];
7848                            numMatch++;
7849                        }
7850                    }
7851                }
7852            }
7853            list.add(pi);
7854        }
7855    }
7856
7857    @Override
7858    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7859            String[] permissions, int flags, int userId) {
7860        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7861        flags = updateFlagsForPackage(flags, userId, permissions);
7862        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7863                true /* requireFullPermission */, false /* checkShell */,
7864                "get packages holding permissions");
7865        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7866
7867        // writer
7868        synchronized (mPackages) {
7869            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7870            boolean[] tmpBools = new boolean[permissions.length];
7871            if (listUninstalled) {
7872                for (PackageSetting ps : mSettings.mPackages.values()) {
7873                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7874                            userId);
7875                }
7876            } else {
7877                for (PackageParser.Package pkg : mPackages.values()) {
7878                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7879                    if (ps != null) {
7880                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7881                                userId);
7882                    }
7883                }
7884            }
7885
7886            return new ParceledListSlice<PackageInfo>(list);
7887        }
7888    }
7889
7890    @Override
7891    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7892        final int callingUid = Binder.getCallingUid();
7893        if (getInstantAppPackageName(callingUid) != null) {
7894            return ParceledListSlice.emptyList();
7895        }
7896        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7897        flags = updateFlagsForApplication(flags, userId, null);
7898        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7899
7900        // writer
7901        synchronized (mPackages) {
7902            ArrayList<ApplicationInfo> list;
7903            if (listUninstalled) {
7904                list = new ArrayList<>(mSettings.mPackages.size());
7905                for (PackageSetting ps : mSettings.mPackages.values()) {
7906                    ApplicationInfo ai;
7907                    int effectiveFlags = flags;
7908                    if (ps.isSystem()) {
7909                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7910                    }
7911                    if (ps.pkg != null) {
7912                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7913                            continue;
7914                        }
7915                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7916                            continue;
7917                        }
7918                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7919                                ps.readUserState(userId), userId);
7920                        if (ai != null) {
7921                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7922                        }
7923                    } else {
7924                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7925                        // and already converts to externally visible package name
7926                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7927                                callingUid, effectiveFlags, userId);
7928                    }
7929                    if (ai != null) {
7930                        list.add(ai);
7931                    }
7932                }
7933            } else {
7934                list = new ArrayList<>(mPackages.size());
7935                for (PackageParser.Package p : mPackages.values()) {
7936                    if (p.mExtras != null) {
7937                        PackageSetting ps = (PackageSetting) p.mExtras;
7938                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7939                            continue;
7940                        }
7941                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7942                            continue;
7943                        }
7944                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7945                                ps.readUserState(userId), userId);
7946                        if (ai != null) {
7947                            ai.packageName = resolveExternalPackageNameLPr(p);
7948                            list.add(ai);
7949                        }
7950                    }
7951                }
7952            }
7953
7954            return new ParceledListSlice<>(list);
7955        }
7956    }
7957
7958    @Override
7959    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7960        if (HIDE_EPHEMERAL_APIS) {
7961            return null;
7962        }
7963        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7964            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7965                    "getEphemeralApplications");
7966        }
7967        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7968                true /* requireFullPermission */, false /* checkShell */,
7969                "getEphemeralApplications");
7970        synchronized (mPackages) {
7971            List<InstantAppInfo> instantApps = mInstantAppRegistry
7972                    .getInstantAppsLPr(userId);
7973            if (instantApps != null) {
7974                return new ParceledListSlice<>(instantApps);
7975            }
7976        }
7977        return null;
7978    }
7979
7980    @Override
7981    public boolean isInstantApp(String packageName, int userId) {
7982        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7983                true /* requireFullPermission */, false /* checkShell */,
7984                "isInstantApp");
7985        if (HIDE_EPHEMERAL_APIS) {
7986            return false;
7987        }
7988
7989        synchronized (mPackages) {
7990            int callingUid = Binder.getCallingUid();
7991            if (Process.isIsolated(callingUid)) {
7992                callingUid = mIsolatedOwners.get(callingUid);
7993            }
7994            final PackageSetting ps = mSettings.mPackages.get(packageName);
7995            PackageParser.Package pkg = mPackages.get(packageName);
7996            final boolean returnAllowed =
7997                    ps != null
7998                    && (isCallerSameApp(packageName, callingUid)
7999                            || canViewInstantApps(callingUid, userId)
8000                            || mInstantAppRegistry.isInstantAccessGranted(
8001                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8002            if (returnAllowed) {
8003                return ps.getInstantApp(userId);
8004            }
8005        }
8006        return false;
8007    }
8008
8009    @Override
8010    public byte[] getInstantAppCookie(String packageName, int userId) {
8011        if (HIDE_EPHEMERAL_APIS) {
8012            return null;
8013        }
8014
8015        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8016                true /* requireFullPermission */, false /* checkShell */,
8017                "getInstantAppCookie");
8018        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8019            return null;
8020        }
8021        synchronized (mPackages) {
8022            return mInstantAppRegistry.getInstantAppCookieLPw(
8023                    packageName, userId);
8024        }
8025    }
8026
8027    @Override
8028    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8029        if (HIDE_EPHEMERAL_APIS) {
8030            return true;
8031        }
8032
8033        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8034                true /* requireFullPermission */, true /* checkShell */,
8035                "setInstantAppCookie");
8036        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8037            return false;
8038        }
8039        synchronized (mPackages) {
8040            return mInstantAppRegistry.setInstantAppCookieLPw(
8041                    packageName, cookie, userId);
8042        }
8043    }
8044
8045    @Override
8046    public Bitmap getInstantAppIcon(String packageName, int userId) {
8047        if (HIDE_EPHEMERAL_APIS) {
8048            return null;
8049        }
8050
8051        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8052            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8053                    "getInstantAppIcon");
8054        }
8055        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8056                true /* requireFullPermission */, false /* checkShell */,
8057                "getInstantAppIcon");
8058
8059        synchronized (mPackages) {
8060            return mInstantAppRegistry.getInstantAppIconLPw(
8061                    packageName, userId);
8062        }
8063    }
8064
8065    private boolean isCallerSameApp(String packageName, int uid) {
8066        PackageParser.Package pkg = mPackages.get(packageName);
8067        return pkg != null
8068                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8069    }
8070
8071    @Override
8072    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8073        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8074            return ParceledListSlice.emptyList();
8075        }
8076        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8077    }
8078
8079    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8080        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8081
8082        // reader
8083        synchronized (mPackages) {
8084            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8085            final int userId = UserHandle.getCallingUserId();
8086            while (i.hasNext()) {
8087                final PackageParser.Package p = i.next();
8088                if (p.applicationInfo == null) continue;
8089
8090                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8091                        && !p.applicationInfo.isDirectBootAware();
8092                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8093                        && p.applicationInfo.isDirectBootAware();
8094
8095                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8096                        && (!mSafeMode || isSystemApp(p))
8097                        && (matchesUnaware || matchesAware)) {
8098                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8099                    if (ps != null) {
8100                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8101                                ps.readUserState(userId), userId);
8102                        if (ai != null) {
8103                            finalList.add(ai);
8104                        }
8105                    }
8106                }
8107            }
8108        }
8109
8110        return finalList;
8111    }
8112
8113    @Override
8114    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8115        return resolveContentProviderInternal(name, flags, userId);
8116    }
8117
8118    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8119        if (!sUserManager.exists(userId)) return null;
8120        flags = updateFlagsForComponent(flags, userId, name);
8121        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8122        // reader
8123        synchronized (mPackages) {
8124            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8125            PackageSetting ps = provider != null
8126                    ? mSettings.mPackages.get(provider.owner.packageName)
8127                    : null;
8128            if (ps != null) {
8129                final boolean isInstantApp = ps.getInstantApp(userId);
8130                // normal application; filter out instant application provider
8131                if (instantAppPkgName == null && isInstantApp) {
8132                    return null;
8133                }
8134                // instant application; filter out other instant applications
8135                if (instantAppPkgName != null
8136                        && isInstantApp
8137                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8138                    return null;
8139                }
8140                // instant application; filter out non-exposed provider
8141                if (instantAppPkgName != null
8142                        && !isInstantApp
8143                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8144                    return null;
8145                }
8146                // provider not enabled
8147                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8148                    return null;
8149                }
8150                return PackageParser.generateProviderInfo(
8151                        provider, flags, ps.readUserState(userId), userId);
8152            }
8153            return null;
8154        }
8155    }
8156
8157    /**
8158     * @deprecated
8159     */
8160    @Deprecated
8161    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8162        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8163            return;
8164        }
8165        // reader
8166        synchronized (mPackages) {
8167            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8168                    .entrySet().iterator();
8169            final int userId = UserHandle.getCallingUserId();
8170            while (i.hasNext()) {
8171                Map.Entry<String, PackageParser.Provider> entry = i.next();
8172                PackageParser.Provider p = entry.getValue();
8173                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8174
8175                if (ps != null && p.syncable
8176                        && (!mSafeMode || (p.info.applicationInfo.flags
8177                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8178                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8179                            ps.readUserState(userId), userId);
8180                    if (info != null) {
8181                        outNames.add(entry.getKey());
8182                        outInfo.add(info);
8183                    }
8184                }
8185            }
8186        }
8187    }
8188
8189    @Override
8190    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8191            int uid, int flags, String metaDataKey) {
8192        final int callingUid = Binder.getCallingUid();
8193        final int userId = processName != null ? UserHandle.getUserId(uid)
8194                : UserHandle.getCallingUserId();
8195        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8196        flags = updateFlagsForComponent(flags, userId, processName);
8197        ArrayList<ProviderInfo> finalList = null;
8198        // reader
8199        synchronized (mPackages) {
8200            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8201            while (i.hasNext()) {
8202                final PackageParser.Provider p = i.next();
8203                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8204                if (ps != null && p.info.authority != null
8205                        && (processName == null
8206                                || (p.info.processName.equals(processName)
8207                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8208                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8209
8210                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8211                    // parameter.
8212                    if (metaDataKey != null
8213                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8214                        continue;
8215                    }
8216                    final ComponentName component =
8217                            new ComponentName(p.info.packageName, p.info.name);
8218                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8219                        continue;
8220                    }
8221                    if (finalList == null) {
8222                        finalList = new ArrayList<ProviderInfo>(3);
8223                    }
8224                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8225                            ps.readUserState(userId), userId);
8226                    if (info != null) {
8227                        finalList.add(info);
8228                    }
8229                }
8230            }
8231        }
8232
8233        if (finalList != null) {
8234            Collections.sort(finalList, mProviderInitOrderSorter);
8235            return new ParceledListSlice<ProviderInfo>(finalList);
8236        }
8237
8238        return ParceledListSlice.emptyList();
8239    }
8240
8241    @Override
8242    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8243        // reader
8244        synchronized (mPackages) {
8245            final int callingUid = Binder.getCallingUid();
8246            final int callingUserId = UserHandle.getUserId(callingUid);
8247            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8248            if (ps == null) return null;
8249            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8250                return null;
8251            }
8252            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8253            return PackageParser.generateInstrumentationInfo(i, flags);
8254        }
8255    }
8256
8257    @Override
8258    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8259            String targetPackage, int flags) {
8260        final int callingUid = Binder.getCallingUid();
8261        final int callingUserId = UserHandle.getUserId(callingUid);
8262        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8263        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8264            return ParceledListSlice.emptyList();
8265        }
8266        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8267    }
8268
8269    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8270            int flags) {
8271        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8272
8273        // reader
8274        synchronized (mPackages) {
8275            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8276            while (i.hasNext()) {
8277                final PackageParser.Instrumentation p = i.next();
8278                if (targetPackage == null
8279                        || targetPackage.equals(p.info.targetPackage)) {
8280                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8281                            flags);
8282                    if (ii != null) {
8283                        finalList.add(ii);
8284                    }
8285                }
8286            }
8287        }
8288
8289        return finalList;
8290    }
8291
8292    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8293        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8294        try {
8295            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8296        } finally {
8297            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8298        }
8299    }
8300
8301    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8302        final File[] files = scanDir.listFiles();
8303        if (ArrayUtils.isEmpty(files)) {
8304            Log.d(TAG, "No files in app dir " + scanDir);
8305            return;
8306        }
8307
8308        if (DEBUG_PACKAGE_SCANNING) {
8309            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8310                    + " flags=0x" + Integer.toHexString(parseFlags));
8311        }
8312        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8313                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8314                mParallelPackageParserCallback)) {
8315            // Submit files for parsing in parallel
8316            int fileCount = 0;
8317            for (File file : files) {
8318                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8319                        && !PackageInstallerService.isStageName(file.getName());
8320                if (!isPackage) {
8321                    // Ignore entries which are not packages
8322                    continue;
8323                }
8324                parallelPackageParser.submit(file, parseFlags);
8325                fileCount++;
8326            }
8327
8328            // Process results one by one
8329            for (; fileCount > 0; fileCount--) {
8330                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8331                Throwable throwable = parseResult.throwable;
8332                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8333
8334                if (throwable == null) {
8335                    // TODO(toddke): move lower in the scan chain
8336                    // Static shared libraries have synthetic package names
8337                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8338                        renameStaticSharedLibraryPackage(parseResult.pkg);
8339                    }
8340                    try {
8341                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8342                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8343                                    currentTime, null);
8344                        }
8345                    } catch (PackageManagerException e) {
8346                        errorCode = e.error;
8347                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8348                    }
8349                } else if (throwable instanceof PackageParser.PackageParserException) {
8350                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8351                            throwable;
8352                    errorCode = e.error;
8353                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8354                } else {
8355                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8356                            + parseResult.scanFile, throwable);
8357                }
8358
8359                // Delete invalid userdata apps
8360                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8361                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8362                    logCriticalInfo(Log.WARN,
8363                            "Deleting invalid package at " + parseResult.scanFile);
8364                    removeCodePathLI(parseResult.scanFile);
8365                }
8366            }
8367        }
8368    }
8369
8370    public static void reportSettingsProblem(int priority, String msg) {
8371        logCriticalInfo(priority, msg);
8372    }
8373
8374    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8375            boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8376        // When upgrading from pre-N MR1, verify the package time stamp using the package
8377        // directory and not the APK file.
8378        final long lastModifiedTime = mIsPreNMR1Upgrade
8379                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8380        if (ps != null && !forceCollect
8381                && ps.codePathString.equals(pkg.codePath)
8382                && ps.timeStamp == lastModifiedTime
8383                && !isCompatSignatureUpdateNeeded(pkg)
8384                && !isRecoverSignatureUpdateNeeded(pkg)) {
8385            if (ps.signatures.mSigningDetails.signatures != null
8386                    && ps.signatures.mSigningDetails.signatures.length != 0
8387                    && ps.signatures.mSigningDetails.signatureSchemeVersion
8388                            != SignatureSchemeVersion.UNKNOWN) {
8389                // Optimization: reuse the existing cached signing data
8390                // if the package appears to be unchanged.
8391                pkg.mSigningDetails =
8392                        new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
8393                return;
8394            }
8395
8396            Slog.w(TAG, "PackageSetting for " + ps.name
8397                    + " is missing signatures.  Collecting certs again to recover them.");
8398        } else {
8399            Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8400                    (forceCollect ? " (forced)" : ""));
8401        }
8402
8403        try {
8404            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8405            PackageParser.collectCertificates(pkg, skipVerify);
8406        } catch (PackageParserException e) {
8407            throw PackageManagerException.from(e);
8408        } finally {
8409            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8410        }
8411    }
8412
8413    /**
8414     *  Traces a package scan.
8415     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8416     */
8417    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8418            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8419        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8420        try {
8421            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8422        } finally {
8423            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8424        }
8425    }
8426
8427    /**
8428     *  Scans a package and returns the newly parsed package.
8429     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8430     */
8431    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8432            long currentTime, UserHandle user) throws PackageManagerException {
8433        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8434        PackageParser pp = new PackageParser();
8435        pp.setSeparateProcesses(mSeparateProcesses);
8436        pp.setOnlyCoreApps(mOnlyCore);
8437        pp.setDisplayMetrics(mMetrics);
8438        pp.setCallback(mPackageParserCallback);
8439
8440        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8441        final PackageParser.Package pkg;
8442        try {
8443            pkg = pp.parsePackage(scanFile, parseFlags);
8444        } catch (PackageParserException e) {
8445            throw PackageManagerException.from(e);
8446        } finally {
8447            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8448        }
8449
8450        // Static shared libraries have synthetic package names
8451        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8452            renameStaticSharedLibraryPackage(pkg);
8453        }
8454
8455        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8456    }
8457
8458    /**
8459     *  Scans a package and returns the newly parsed package.
8460     *  @throws PackageManagerException on a parse error.
8461     */
8462    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8463            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8464            @Nullable UserHandle user)
8465                    throws PackageManagerException {
8466        // If the package has children and this is the first dive in the function
8467        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8468        // packages (parent and children) would be successfully scanned before the
8469        // actual scan since scanning mutates internal state and we want to atomically
8470        // install the package and its children.
8471        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8472            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8473                scanFlags |= SCAN_CHECK_ONLY;
8474            }
8475        } else {
8476            scanFlags &= ~SCAN_CHECK_ONLY;
8477        }
8478
8479        // Scan the parent
8480        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8481                scanFlags, currentTime, user);
8482
8483        // Scan the children
8484        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8485        for (int i = 0; i < childCount; i++) {
8486            PackageParser.Package childPackage = pkg.childPackages.get(i);
8487            addForInitLI(childPackage, parseFlags, scanFlags,
8488                    currentTime, user);
8489        }
8490
8491
8492        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8493            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8494        }
8495
8496        return scannedPkg;
8497    }
8498
8499    /**
8500     * Returns if full apk verification can be skipped for the whole package, including the splits.
8501     */
8502    private boolean canSkipFullPackageVerification(PackageParser.Package pkg) {
8503        if (!canSkipFullApkVerification(pkg.baseCodePath)) {
8504            return false;
8505        }
8506        // TODO: Allow base and splits to be verified individually.
8507        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8508            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8509                if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) {
8510                    return false;
8511                }
8512            }
8513        }
8514        return true;
8515    }
8516
8517    /**
8518     * Returns if full apk verification can be skipped, depending on current FSVerity setup and
8519     * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
8520     * match one in a trusted source, and should be done separately.
8521     */
8522    private boolean canSkipFullApkVerification(String apkPath) {
8523        byte[] rootHashObserved = null;
8524        try {
8525            rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
8526            if (rootHashObserved == null) {
8527                return false;  // APK does not contain Merkle tree root hash.
8528            }
8529            synchronized (mInstallLock) {
8530                // Returns whether the observed root hash matches what kernel has.
8531                mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8532                return true;
8533            }
8534        } catch (InstallerException | IOException | DigestException |
8535                NoSuchAlgorithmException e) {
8536            Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8537        }
8538        return false;
8539    }
8540
8541    /**
8542     * Adds a new package to the internal data structures during platform initialization.
8543     * <p>After adding, the package is known to the system and available for querying.
8544     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8545     * etc...], additional checks are performed. Basic verification [such as ensuring
8546     * matching signatures, checking version codes, etc...] occurs if the package is
8547     * identical to a previously known package. If the package fails a signature check,
8548     * the version installed on /data will be removed. If the version of the new package
8549     * is less than or equal than the version on /data, it will be ignored.
8550     * <p>Regardless of the package location, the results are applied to the internal
8551     * structures and the package is made available to the rest of the system.
8552     * <p>NOTE: The return value should be removed. It's the passed in package object.
8553     */
8554    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8555            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8556            @Nullable UserHandle user)
8557                    throws PackageManagerException {
8558        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8559        final String renamedPkgName;
8560        final PackageSetting disabledPkgSetting;
8561        final boolean isSystemPkgUpdated;
8562        final boolean pkgAlreadyExists;
8563        PackageSetting pkgSetting;
8564
8565        // NOTE: installPackageLI() has the same code to setup the package's
8566        // application info. This probably should be done lower in the call
8567        // stack [such as scanPackageOnly()]. However, we verify the application
8568        // info prior to that [in scanPackageNew()] and thus have to setup
8569        // the application info early.
8570        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8571        pkg.setApplicationInfoCodePath(pkg.codePath);
8572        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8573        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8574        pkg.setApplicationInfoResourcePath(pkg.codePath);
8575        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8576        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8577
8578        synchronized (mPackages) {
8579            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8580            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8581            if (realPkgName != null) {
8582                ensurePackageRenamed(pkg, renamedPkgName);
8583            }
8584            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8585            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8586            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8587            pkgAlreadyExists = pkgSetting != null;
8588            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8589            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8590            isSystemPkgUpdated = disabledPkgSetting != null;
8591
8592            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8593                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8594            }
8595
8596            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8597                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8598                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8599                    : null;
8600            if (DEBUG_PACKAGE_SCANNING
8601                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8602                    && sharedUserSetting != null) {
8603                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8604                        + " (uid=" + sharedUserSetting.userId + "):"
8605                        + " packages=" + sharedUserSetting.packages);
8606            }
8607
8608            if (scanSystemPartition) {
8609                // Potentially prune child packages. If the application on the /system
8610                // partition has been updated via OTA, but, is still disabled by a
8611                // version on /data, cycle through all of its children packages and
8612                // remove children that are no longer defined.
8613                if (isSystemPkgUpdated) {
8614                    final int scannedChildCount = (pkg.childPackages != null)
8615                            ? pkg.childPackages.size() : 0;
8616                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8617                            ? disabledPkgSetting.childPackageNames.size() : 0;
8618                    for (int i = 0; i < disabledChildCount; i++) {
8619                        String disabledChildPackageName =
8620                                disabledPkgSetting.childPackageNames.get(i);
8621                        boolean disabledPackageAvailable = false;
8622                        for (int j = 0; j < scannedChildCount; j++) {
8623                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8624                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8625                                disabledPackageAvailable = true;
8626                                break;
8627                            }
8628                        }
8629                        if (!disabledPackageAvailable) {
8630                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8631                        }
8632                    }
8633                    // we're updating the disabled package, so, scan it as the package setting
8634                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
8635                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8636                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8637                            (pkg == mPlatformPackage), user);
8638                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8639                }
8640            }
8641        }
8642
8643        final boolean newPkgChangedPaths =
8644                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8645        final boolean newPkgVersionGreater =
8646                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8647        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8648                && newPkgChangedPaths && newPkgVersionGreater;
8649        if (isSystemPkgBetter) {
8650            // The version of the application on /system is greater than the version on
8651            // /data. Switch back to the application on /system.
8652            // It's safe to assume the application on /system will correctly scan. If not,
8653            // there won't be a working copy of the application.
8654            synchronized (mPackages) {
8655                // just remove the loaded entries from package lists
8656                mPackages.remove(pkgSetting.name);
8657            }
8658
8659            logCriticalInfo(Log.WARN,
8660                    "System package updated;"
8661                    + " name: " + pkgSetting.name
8662                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8663                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8664
8665            final InstallArgs args = createInstallArgsForExisting(
8666                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8667                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8668            args.cleanUpResourcesLI();
8669            synchronized (mPackages) {
8670                mSettings.enableSystemPackageLPw(pkgSetting.name);
8671            }
8672        }
8673
8674        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8675            // The version of the application on the /system partition is less than or
8676            // equal to the version on the /data partition. Throw an exception and use
8677            // the application already installed on the /data partition.
8678            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8679                    + pkg.codePath + " ignored: updated version " + disabledPkgSetting.versionCode
8680                    + " better than this " + pkg.getLongVersionCode());
8681        }
8682
8683        // Verify certificates against what was last scanned. If it is an updated priv app, we will
8684        // force re-collecting certificate.
8685        final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
8686                disabledPkgSetting);
8687        // Full APK verification can be skipped during certificate collection, only if the file is
8688        // in verified partition, or can be verified on access (when apk verity is enabled). In both
8689        // cases, only data in Signing Block is verified instead of the whole file.
8690        final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
8691                (forceCollect && canSkipFullPackageVerification(pkg));
8692        collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
8693
8694        boolean shouldHideSystemApp = false;
8695        // A new application appeared on /system, but, we already have a copy of
8696        // the application installed on /data.
8697        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8698                && !pkgSetting.isSystem()) {
8699
8700            if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
8701                    PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
8702                logCriticalInfo(Log.WARN,
8703                        "System package signature mismatch;"
8704                        + " name: " + pkgSetting.name);
8705                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8706                        "scanPackageInternalLI")) {
8707                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8708                }
8709                pkgSetting = null;
8710            } else if (newPkgVersionGreater) {
8711                // The application on /system is newer than the application on /data.
8712                // Simply remove the application on /data [keeping application data]
8713                // and replace it with the version on /system.
8714                logCriticalInfo(Log.WARN,
8715                        "System package enabled;"
8716                        + " name: " + pkgSetting.name
8717                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8718                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8719                InstallArgs args = createInstallArgsForExisting(
8720                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8721                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8722                synchronized (mInstallLock) {
8723                    args.cleanUpResourcesLI();
8724                }
8725            } else {
8726                // The application on /system is older than the application on /data. Hide
8727                // the application on /system and the version on /data will be scanned later
8728                // and re-added like an update.
8729                shouldHideSystemApp = true;
8730                logCriticalInfo(Log.INFO,
8731                        "System package disabled;"
8732                        + " name: " + pkgSetting.name
8733                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8734                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8735            }
8736        }
8737
8738        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8739                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8740
8741        if (shouldHideSystemApp) {
8742            synchronized (mPackages) {
8743                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8744            }
8745        }
8746        return scannedPkg;
8747    }
8748
8749    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8750        // Derive the new package synthetic package name
8751        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8752                + pkg.staticSharedLibVersion);
8753    }
8754
8755    private static String fixProcessName(String defProcessName,
8756            String processName) {
8757        if (processName == null) {
8758            return defProcessName;
8759        }
8760        return processName;
8761    }
8762
8763    /**
8764     * Enforces that only the system UID or root's UID can call a method exposed
8765     * via Binder.
8766     *
8767     * @param message used as message if SecurityException is thrown
8768     * @throws SecurityException if the caller is not system or root
8769     */
8770    private static final void enforceSystemOrRoot(String message) {
8771        final int uid = Binder.getCallingUid();
8772        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8773            throw new SecurityException(message);
8774        }
8775    }
8776
8777    @Override
8778    public void performFstrimIfNeeded() {
8779        enforceSystemOrRoot("Only the system can request fstrim");
8780
8781        // Before everything else, see whether we need to fstrim.
8782        try {
8783            IStorageManager sm = PackageHelper.getStorageManager();
8784            if (sm != null) {
8785                boolean doTrim = false;
8786                final long interval = android.provider.Settings.Global.getLong(
8787                        mContext.getContentResolver(),
8788                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8789                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8790                if (interval > 0) {
8791                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8792                    if (timeSinceLast > interval) {
8793                        doTrim = true;
8794                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8795                                + "; running immediately");
8796                    }
8797                }
8798                if (doTrim) {
8799                    final boolean dexOptDialogShown;
8800                    synchronized (mPackages) {
8801                        dexOptDialogShown = mDexOptDialogShown;
8802                    }
8803                    if (!isFirstBoot() && dexOptDialogShown) {
8804                        try {
8805                            ActivityManager.getService().showBootMessage(
8806                                    mContext.getResources().getString(
8807                                            R.string.android_upgrading_fstrim), true);
8808                        } catch (RemoteException e) {
8809                        }
8810                    }
8811                    sm.runMaintenance();
8812                }
8813            } else {
8814                Slog.e(TAG, "storageManager service unavailable!");
8815            }
8816        } catch (RemoteException e) {
8817            // Can't happen; StorageManagerService is local
8818        }
8819    }
8820
8821    @Override
8822    public void updatePackagesIfNeeded() {
8823        enforceSystemOrRoot("Only the system can request package update");
8824
8825        // We need to re-extract after an OTA.
8826        boolean causeUpgrade = isUpgrade();
8827
8828        // First boot or factory reset.
8829        // Note: we also handle devices that are upgrading to N right now as if it is their
8830        //       first boot, as they do not have profile data.
8831        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8832
8833        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8834        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8835
8836        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8837            return;
8838        }
8839
8840        List<PackageParser.Package> pkgs;
8841        synchronized (mPackages) {
8842            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8843        }
8844
8845        final long startTime = System.nanoTime();
8846        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8847                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
8848                    false /* bootComplete */);
8849
8850        final int elapsedTimeSeconds =
8851                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8852
8853        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8854        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8855        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8856        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8857        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8858    }
8859
8860    /*
8861     * Return the prebuilt profile path given a package base code path.
8862     */
8863    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8864        return pkg.baseCodePath + ".prof";
8865    }
8866
8867    /**
8868     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8869     * containing statistics about the invocation. The array consists of three elements,
8870     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8871     * and {@code numberOfPackagesFailed}.
8872     */
8873    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8874            final int compilationReason, boolean bootComplete) {
8875
8876        int numberOfPackagesVisited = 0;
8877        int numberOfPackagesOptimized = 0;
8878        int numberOfPackagesSkipped = 0;
8879        int numberOfPackagesFailed = 0;
8880        final int numberOfPackagesToDexopt = pkgs.size();
8881
8882        for (PackageParser.Package pkg : pkgs) {
8883            numberOfPackagesVisited++;
8884
8885            boolean useProfileForDexopt = false;
8886
8887            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8888                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8889                // that are already compiled.
8890                File profileFile = new File(getPrebuildProfilePath(pkg));
8891                // Copy profile if it exists.
8892                if (profileFile.exists()) {
8893                    try {
8894                        // We could also do this lazily before calling dexopt in
8895                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8896                        // is that we don't have a good way to say "do this only once".
8897                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8898                                pkg.applicationInfo.uid, pkg.packageName,
8899                                ArtManager.getProfileName(null))) {
8900                            Log.e(TAG, "Installer failed to copy system profile!");
8901                        } else {
8902                            // Disabled as this causes speed-profile compilation during first boot
8903                            // even if things are already compiled.
8904                            // useProfileForDexopt = true;
8905                        }
8906                    } catch (Exception e) {
8907                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8908                                e);
8909                    }
8910                } else {
8911                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8912                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8913                    // minimize the number off apps being speed-profile compiled during first boot.
8914                    // The other paths will not change the filter.
8915                    if (disabledPs != null && disabledPs.pkg.isStub) {
8916                        // The package is the stub one, remove the stub suffix to get the normal
8917                        // package and APK names.
8918                        String systemProfilePath =
8919                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8920                        profileFile = new File(systemProfilePath);
8921                        // If we have a profile for a compressed APK, copy it to the reference
8922                        // location.
8923                        // Note that copying the profile here will cause it to override the
8924                        // reference profile every OTA even though the existing reference profile
8925                        // may have more data. We can't copy during decompression since the
8926                        // directories are not set up at that point.
8927                        if (profileFile.exists()) {
8928                            try {
8929                                // We could also do this lazily before calling dexopt in
8930                                // PackageDexOptimizer to prevent this happening on first boot. The
8931                                // issue is that we don't have a good way to say "do this only
8932                                // once".
8933                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8934                                        pkg.applicationInfo.uid, pkg.packageName,
8935                                        ArtManager.getProfileName(null))) {
8936                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8937                                } else {
8938                                    useProfileForDexopt = true;
8939                                }
8940                            } catch (Exception e) {
8941                                Log.e(TAG, "Failed to copy profile " +
8942                                        profileFile.getAbsolutePath() + " ", e);
8943                            }
8944                        }
8945                    }
8946                }
8947            }
8948
8949            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8950                if (DEBUG_DEXOPT) {
8951                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8952                }
8953                numberOfPackagesSkipped++;
8954                continue;
8955            }
8956
8957            if (DEBUG_DEXOPT) {
8958                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8959                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8960            }
8961
8962            if (showDialog) {
8963                try {
8964                    ActivityManager.getService().showBootMessage(
8965                            mContext.getResources().getString(R.string.android_upgrading_apk,
8966                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8967                } catch (RemoteException e) {
8968                }
8969                synchronized (mPackages) {
8970                    mDexOptDialogShown = true;
8971                }
8972            }
8973
8974            int pkgCompilationReason = compilationReason;
8975            if (useProfileForDexopt) {
8976                // Use background dexopt mode to try and use the profile. Note that this does not
8977                // guarantee usage of the profile.
8978                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
8979            }
8980
8981            // checkProfiles is false to avoid merging profiles during boot which
8982            // might interfere with background compilation (b/28612421).
8983            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8984            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8985            // trade-off worth doing to save boot time work.
8986            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
8987            if (compilationReason == REASON_FIRST_BOOT) {
8988                // TODO: This doesn't cover the upgrade case, we should check for this too.
8989                dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
8990            }
8991            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
8992                    pkg.packageName,
8993                    pkgCompilationReason,
8994                    dexoptFlags));
8995
8996            switch (primaryDexOptStaus) {
8997                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8998                    numberOfPackagesOptimized++;
8999                    break;
9000                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9001                    numberOfPackagesSkipped++;
9002                    break;
9003                case PackageDexOptimizer.DEX_OPT_FAILED:
9004                    numberOfPackagesFailed++;
9005                    break;
9006                default:
9007                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9008                    break;
9009            }
9010        }
9011
9012        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9013                numberOfPackagesFailed };
9014    }
9015
9016    @Override
9017    public void notifyPackageUse(String packageName, int reason) {
9018        synchronized (mPackages) {
9019            final int callingUid = Binder.getCallingUid();
9020            final int callingUserId = UserHandle.getUserId(callingUid);
9021            if (getInstantAppPackageName(callingUid) != null) {
9022                if (!isCallerSameApp(packageName, callingUid)) {
9023                    return;
9024                }
9025            } else {
9026                if (isInstantApp(packageName, callingUserId)) {
9027                    return;
9028                }
9029            }
9030            notifyPackageUseLocked(packageName, reason);
9031        }
9032    }
9033
9034    @GuardedBy("mPackages")
9035    private void notifyPackageUseLocked(String packageName, int reason) {
9036        final PackageParser.Package p = mPackages.get(packageName);
9037        if (p == null) {
9038            return;
9039        }
9040        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9041    }
9042
9043    @Override
9044    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9045            List<String> classPaths, String loaderIsa) {
9046        int userId = UserHandle.getCallingUserId();
9047        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9048        if (ai == null) {
9049            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9050                + loadingPackageName + ", user=" + userId);
9051            return;
9052        }
9053        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9054    }
9055
9056    @Override
9057    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9058            IDexModuleRegisterCallback callback) {
9059        int userId = UserHandle.getCallingUserId();
9060        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9061        DexManager.RegisterDexModuleResult result;
9062        if (ai == null) {
9063            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9064                     " calling user. package=" + packageName + ", user=" + userId);
9065            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9066        } else {
9067            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9068        }
9069
9070        if (callback != null) {
9071            mHandler.post(() -> {
9072                try {
9073                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9074                } catch (RemoteException e) {
9075                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9076                }
9077            });
9078        }
9079    }
9080
9081    /**
9082     * Ask the package manager to perform a dex-opt with the given compiler filter.
9083     *
9084     * Note: exposed only for the shell command to allow moving packages explicitly to a
9085     *       definite state.
9086     */
9087    @Override
9088    public boolean performDexOptMode(String packageName,
9089            boolean checkProfiles, String targetCompilerFilter, boolean force,
9090            boolean bootComplete, String splitName) {
9091        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9092                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9093                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9094        return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9095                targetCompilerFilter, splitName, flags));
9096    }
9097
9098    /**
9099     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9100     * secondary dex files belonging to the given package.
9101     *
9102     * Note: exposed only for the shell command to allow moving packages explicitly to a
9103     *       definite state.
9104     */
9105    @Override
9106    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9107            boolean force) {
9108        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9109                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9110                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9111                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9112        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9113    }
9114
9115    /*package*/ boolean performDexOpt(DexoptOptions options) {
9116        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9117            return false;
9118        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9119            return false;
9120        }
9121
9122        if (options.isDexoptOnlySecondaryDex()) {
9123            return mDexManager.dexoptSecondaryDex(options);
9124        } else {
9125            int dexoptStatus = performDexOptWithStatus(options);
9126            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9127        }
9128    }
9129
9130    /**
9131     * Perform dexopt on the given package and return one of following result:
9132     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9133     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9134     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9135     */
9136    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9137        return performDexOptTraced(options);
9138    }
9139
9140    private int performDexOptTraced(DexoptOptions options) {
9141        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9142        try {
9143            return performDexOptInternal(options);
9144        } finally {
9145            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9146        }
9147    }
9148
9149    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9150    // if the package can now be considered up to date for the given filter.
9151    private int performDexOptInternal(DexoptOptions options) {
9152        PackageParser.Package p;
9153        synchronized (mPackages) {
9154            p = mPackages.get(options.getPackageName());
9155            if (p == null) {
9156                // Package could not be found. Report failure.
9157                return PackageDexOptimizer.DEX_OPT_FAILED;
9158            }
9159            mPackageUsage.maybeWriteAsync(mPackages);
9160            mCompilerStats.maybeWriteAsync();
9161        }
9162        long callingId = Binder.clearCallingIdentity();
9163        try {
9164            synchronized (mInstallLock) {
9165                return performDexOptInternalWithDependenciesLI(p, options);
9166            }
9167        } finally {
9168            Binder.restoreCallingIdentity(callingId);
9169        }
9170    }
9171
9172    public ArraySet<String> getOptimizablePackages() {
9173        ArraySet<String> pkgs = new ArraySet<String>();
9174        synchronized (mPackages) {
9175            for (PackageParser.Package p : mPackages.values()) {
9176                if (PackageDexOptimizer.canOptimizePackage(p)) {
9177                    pkgs.add(p.packageName);
9178                }
9179            }
9180        }
9181        return pkgs;
9182    }
9183
9184    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9185            DexoptOptions options) {
9186        // Select the dex optimizer based on the force parameter.
9187        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9188        //       allocate an object here.
9189        PackageDexOptimizer pdo = options.isForce()
9190                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9191                : mPackageDexOptimizer;
9192
9193        // Dexopt all dependencies first. Note: we ignore the return value and march on
9194        // on errors.
9195        // Note that we are going to call performDexOpt on those libraries as many times as
9196        // they are referenced in packages. When we do a batch of performDexOpt (for example
9197        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9198        // and the first package that uses the library will dexopt it. The
9199        // others will see that the compiled code for the library is up to date.
9200        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9201        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9202        if (!deps.isEmpty()) {
9203            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9204                    options.getCompilationReason(), options.getCompilerFilter(),
9205                    options.getSplitName(),
9206                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9207            for (PackageParser.Package depPackage : deps) {
9208                // TODO: Analyze and investigate if we (should) profile libraries.
9209                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9210                        getOrCreateCompilerPackageStats(depPackage),
9211                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9212            }
9213        }
9214        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9215                getOrCreateCompilerPackageStats(p),
9216                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9217    }
9218
9219    /**
9220     * Reconcile the information we have about the secondary dex files belonging to
9221     * {@code packagName} and the actual dex files. For all dex files that were
9222     * deleted, update the internal records and delete the generated oat files.
9223     */
9224    @Override
9225    public void reconcileSecondaryDexFiles(String packageName) {
9226        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9227            return;
9228        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9229            return;
9230        }
9231        mDexManager.reconcileSecondaryDexFiles(packageName);
9232    }
9233
9234    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9235    // a reference there.
9236    /*package*/ DexManager getDexManager() {
9237        return mDexManager;
9238    }
9239
9240    /**
9241     * Execute the background dexopt job immediately.
9242     */
9243    @Override
9244    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9245        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9246            return false;
9247        }
9248        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9249    }
9250
9251    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9252        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9253                || p.usesStaticLibraries != null) {
9254            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9255            Set<String> collectedNames = new HashSet<>();
9256            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9257
9258            retValue.remove(p);
9259
9260            return retValue;
9261        } else {
9262            return Collections.emptyList();
9263        }
9264    }
9265
9266    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9267            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9268        if (!collectedNames.contains(p.packageName)) {
9269            collectedNames.add(p.packageName);
9270            collected.add(p);
9271
9272            if (p.usesLibraries != null) {
9273                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9274                        null, collected, collectedNames);
9275            }
9276            if (p.usesOptionalLibraries != null) {
9277                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9278                        null, collected, collectedNames);
9279            }
9280            if (p.usesStaticLibraries != null) {
9281                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9282                        p.usesStaticLibrariesVersions, collected, collectedNames);
9283            }
9284        }
9285    }
9286
9287    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9288            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9289        final int libNameCount = libs.size();
9290        for (int i = 0; i < libNameCount; i++) {
9291            String libName = libs.get(i);
9292            long version = (versions != null && versions.length == libNameCount)
9293                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9294            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9295            if (libPkg != null) {
9296                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9297            }
9298        }
9299    }
9300
9301    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9302        synchronized (mPackages) {
9303            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9304            if (libEntry != null) {
9305                return mPackages.get(libEntry.apk);
9306            }
9307            return null;
9308        }
9309    }
9310
9311    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9312        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9313        if (versionedLib == null) {
9314            return null;
9315        }
9316        return versionedLib.get(version);
9317    }
9318
9319    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9320        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9321                pkg.staticSharedLibName);
9322        if (versionedLib == null) {
9323            return null;
9324        }
9325        long previousLibVersion = -1;
9326        final int versionCount = versionedLib.size();
9327        for (int i = 0; i < versionCount; i++) {
9328            final long libVersion = versionedLib.keyAt(i);
9329            if (libVersion < pkg.staticSharedLibVersion) {
9330                previousLibVersion = Math.max(previousLibVersion, libVersion);
9331            }
9332        }
9333        if (previousLibVersion >= 0) {
9334            return versionedLib.get(previousLibVersion);
9335        }
9336        return null;
9337    }
9338
9339    public void shutdown() {
9340        mPackageUsage.writeNow(mPackages);
9341        mCompilerStats.writeNow();
9342        mDexManager.writePackageDexUsageNow();
9343    }
9344
9345    @Override
9346    public void dumpProfiles(String packageName) {
9347        PackageParser.Package pkg;
9348        synchronized (mPackages) {
9349            pkg = mPackages.get(packageName);
9350            if (pkg == null) {
9351                throw new IllegalArgumentException("Unknown package: " + packageName);
9352            }
9353        }
9354        /* Only the shell, root, or the app user should be able to dump profiles. */
9355        int callingUid = Binder.getCallingUid();
9356        if (callingUid != Process.SHELL_UID &&
9357            callingUid != Process.ROOT_UID &&
9358            callingUid != pkg.applicationInfo.uid) {
9359            throw new SecurityException("dumpProfiles");
9360        }
9361
9362        synchronized (mInstallLock) {
9363            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9364            mArtManagerService.dumpProfiles(pkg);
9365            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9366        }
9367    }
9368
9369    @Override
9370    public void forceDexOpt(String packageName) {
9371        enforceSystemOrRoot("forceDexOpt");
9372
9373        PackageParser.Package pkg;
9374        synchronized (mPackages) {
9375            pkg = mPackages.get(packageName);
9376            if (pkg == null) {
9377                throw new IllegalArgumentException("Unknown package: " + packageName);
9378            }
9379        }
9380
9381        synchronized (mInstallLock) {
9382            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9383
9384            // Whoever is calling forceDexOpt wants a compiled package.
9385            // Don't use profiles since that may cause compilation to be skipped.
9386            final int res = performDexOptInternalWithDependenciesLI(
9387                    pkg,
9388                    new DexoptOptions(packageName,
9389                            getDefaultCompilerFilter(),
9390                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9391
9392            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9393            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9394                throw new IllegalStateException("Failed to dexopt: " + res);
9395            }
9396        }
9397    }
9398
9399    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9400        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9401            Slog.w(TAG, "Unable to update from " + oldPkg.name
9402                    + " to " + newPkg.packageName
9403                    + ": old package not in system partition");
9404            return false;
9405        } else if (mPackages.get(oldPkg.name) != null) {
9406            Slog.w(TAG, "Unable to update from " + oldPkg.name
9407                    + " to " + newPkg.packageName
9408                    + ": old package still exists");
9409            return false;
9410        }
9411        return true;
9412    }
9413
9414    void removeCodePathLI(File codePath) {
9415        if (codePath.isDirectory()) {
9416            try {
9417                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9418            } catch (InstallerException e) {
9419                Slog.w(TAG, "Failed to remove code path", e);
9420            }
9421        } else {
9422            codePath.delete();
9423        }
9424    }
9425
9426    private int[] resolveUserIds(int userId) {
9427        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9428    }
9429
9430    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9431        if (pkg == null) {
9432            Slog.wtf(TAG, "Package was null!", new Throwable());
9433            return;
9434        }
9435        clearAppDataLeafLIF(pkg, userId, flags);
9436        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9437        for (int i = 0; i < childCount; i++) {
9438            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9439        }
9440
9441        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9442    }
9443
9444    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9445        final PackageSetting ps;
9446        synchronized (mPackages) {
9447            ps = mSettings.mPackages.get(pkg.packageName);
9448        }
9449        for (int realUserId : resolveUserIds(userId)) {
9450            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9451            try {
9452                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9453                        ceDataInode);
9454            } catch (InstallerException e) {
9455                Slog.w(TAG, String.valueOf(e));
9456            }
9457        }
9458    }
9459
9460    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9461        if (pkg == null) {
9462            Slog.wtf(TAG, "Package was null!", new Throwable());
9463            return;
9464        }
9465        destroyAppDataLeafLIF(pkg, userId, flags);
9466        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9467        for (int i = 0; i < childCount; i++) {
9468            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9469        }
9470    }
9471
9472    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9473        final PackageSetting ps;
9474        synchronized (mPackages) {
9475            ps = mSettings.mPackages.get(pkg.packageName);
9476        }
9477        for (int realUserId : resolveUserIds(userId)) {
9478            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9479            try {
9480                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9481                        ceDataInode);
9482            } catch (InstallerException e) {
9483                Slog.w(TAG, String.valueOf(e));
9484            }
9485            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9486        }
9487    }
9488
9489    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9490        if (pkg == null) {
9491            Slog.wtf(TAG, "Package was null!", new Throwable());
9492            return;
9493        }
9494        destroyAppProfilesLeafLIF(pkg);
9495        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9496        for (int i = 0; i < childCount; i++) {
9497            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9498        }
9499    }
9500
9501    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9502        try {
9503            mInstaller.destroyAppProfiles(pkg.packageName);
9504        } catch (InstallerException e) {
9505            Slog.w(TAG, String.valueOf(e));
9506        }
9507    }
9508
9509    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9510        if (pkg == null) {
9511            Slog.wtf(TAG, "Package was null!", new Throwable());
9512            return;
9513        }
9514        mArtManagerService.clearAppProfiles(pkg);
9515        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9516        for (int i = 0; i < childCount; i++) {
9517            mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
9518        }
9519    }
9520
9521    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9522            long lastUpdateTime) {
9523        // Set parent install/update time
9524        PackageSetting ps = (PackageSetting) pkg.mExtras;
9525        if (ps != null) {
9526            ps.firstInstallTime = firstInstallTime;
9527            ps.lastUpdateTime = lastUpdateTime;
9528        }
9529        // Set children install/update time
9530        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9531        for (int i = 0; i < childCount; i++) {
9532            PackageParser.Package childPkg = pkg.childPackages.get(i);
9533            ps = (PackageSetting) childPkg.mExtras;
9534            if (ps != null) {
9535                ps.firstInstallTime = firstInstallTime;
9536                ps.lastUpdateTime = lastUpdateTime;
9537            }
9538        }
9539    }
9540
9541    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9542            SharedLibraryEntry file,
9543            PackageParser.Package changingLib) {
9544        if (file.path != null) {
9545            usesLibraryFiles.add(file.path);
9546            return;
9547        }
9548        PackageParser.Package p = mPackages.get(file.apk);
9549        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9550            // If we are doing this while in the middle of updating a library apk,
9551            // then we need to make sure to use that new apk for determining the
9552            // dependencies here.  (We haven't yet finished committing the new apk
9553            // to the package manager state.)
9554            if (p == null || p.packageName.equals(changingLib.packageName)) {
9555                p = changingLib;
9556            }
9557        }
9558        if (p != null) {
9559            usesLibraryFiles.addAll(p.getAllCodePaths());
9560            if (p.usesLibraryFiles != null) {
9561                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9562            }
9563        }
9564    }
9565
9566    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9567            PackageParser.Package changingLib) throws PackageManagerException {
9568        if (pkg == null) {
9569            return;
9570        }
9571        // The collection used here must maintain the order of addition (so
9572        // that libraries are searched in the correct order) and must have no
9573        // duplicates.
9574        Set<String> usesLibraryFiles = null;
9575        if (pkg.usesLibraries != null) {
9576            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9577                    null, null, pkg.packageName, changingLib, true,
9578                    pkg.applicationInfo.targetSdkVersion, null);
9579        }
9580        if (pkg.usesStaticLibraries != null) {
9581            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9582                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9583                    pkg.packageName, changingLib, true,
9584                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9585        }
9586        if (pkg.usesOptionalLibraries != null) {
9587            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9588                    null, null, pkg.packageName, changingLib, false,
9589                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9590        }
9591        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9592            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9593        } else {
9594            pkg.usesLibraryFiles = null;
9595        }
9596    }
9597
9598    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9599            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9600            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9601            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9602            throws PackageManagerException {
9603        final int libCount = requestedLibraries.size();
9604        for (int i = 0; i < libCount; i++) {
9605            final String libName = requestedLibraries.get(i);
9606            final long libVersion = requiredVersions != null ? requiredVersions[i]
9607                    : SharedLibraryInfo.VERSION_UNDEFINED;
9608            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9609            if (libEntry == null) {
9610                if (required) {
9611                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9612                            "Package " + packageName + " requires unavailable shared library "
9613                                    + libName + "; failing!");
9614                } else if (DEBUG_SHARED_LIBRARIES) {
9615                    Slog.i(TAG, "Package " + packageName
9616                            + " desires unavailable shared library "
9617                            + libName + "; ignoring!");
9618                }
9619            } else {
9620                if (requiredVersions != null && requiredCertDigests != null) {
9621                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9622                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9623                            "Package " + packageName + " requires unavailable static shared"
9624                                    + " library " + libName + " version "
9625                                    + libEntry.info.getLongVersion() + "; failing!");
9626                    }
9627
9628                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9629                    if (libPkg == null) {
9630                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9631                                "Package " + packageName + " requires unavailable static shared"
9632                                        + " library; failing!");
9633                    }
9634
9635                    final String[] expectedCertDigests = requiredCertDigests[i];
9636
9637
9638                    if (expectedCertDigests.length > 1) {
9639
9640                        // For apps targeting O MR1 we require explicit enumeration of all certs.
9641                        final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9642                                ? PackageUtils.computeSignaturesSha256Digests(
9643                                libPkg.mSigningDetails.signatures)
9644                                : PackageUtils.computeSignaturesSha256Digests(
9645                                        new Signature[]{libPkg.mSigningDetails.signatures[0]});
9646
9647                        // Take a shortcut if sizes don't match. Note that if an app doesn't
9648                        // target O we don't parse the "additional-certificate" tags similarly
9649                        // how we only consider all certs only for apps targeting O (see above).
9650                        // Therefore, the size check is safe to make.
9651                        if (expectedCertDigests.length != libCertDigests.length) {
9652                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9653                                    "Package " + packageName + " requires differently signed" +
9654                                            " static shared library; failing!");
9655                        }
9656
9657                        // Use a predictable order as signature order may vary
9658                        Arrays.sort(libCertDigests);
9659                        Arrays.sort(expectedCertDigests);
9660
9661                        final int certCount = libCertDigests.length;
9662                        for (int j = 0; j < certCount; j++) {
9663                            if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9664                                throw new PackageManagerException(
9665                                        INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9666                                        "Package " + packageName + " requires differently signed" +
9667                                                " static shared library; failing!");
9668                            }
9669                        }
9670                    } else {
9671
9672                        // lib signing cert could have rotated beyond the one expected, check to see
9673                        // if the new one has been blessed by the old
9674                        if (!libPkg.mSigningDetails.hasSha256Certificate(
9675                                ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
9676                            throw new PackageManagerException(
9677                                    INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9678                                    "Package " + packageName + " requires differently signed" +
9679                                            " static shared library; failing!");
9680                        }
9681                    }
9682                }
9683
9684                if (outUsedLibraries == null) {
9685                    // Use LinkedHashSet to preserve the order of files added to
9686                    // usesLibraryFiles while eliminating duplicates.
9687                    outUsedLibraries = new LinkedHashSet<>();
9688                }
9689                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9690            }
9691        }
9692        return outUsedLibraries;
9693    }
9694
9695    private static boolean hasString(List<String> list, List<String> which) {
9696        if (list == null) {
9697            return false;
9698        }
9699        for (int i=list.size()-1; i>=0; i--) {
9700            for (int j=which.size()-1; j>=0; j--) {
9701                if (which.get(j).equals(list.get(i))) {
9702                    return true;
9703                }
9704            }
9705        }
9706        return false;
9707    }
9708
9709    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9710            PackageParser.Package changingPkg) {
9711        ArrayList<PackageParser.Package> res = null;
9712        for (PackageParser.Package pkg : mPackages.values()) {
9713            if (changingPkg != null
9714                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9715                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9716                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9717                            changingPkg.staticSharedLibName)) {
9718                return null;
9719            }
9720            if (res == null) {
9721                res = new ArrayList<>();
9722            }
9723            res.add(pkg);
9724            try {
9725                updateSharedLibrariesLPr(pkg, changingPkg);
9726            } catch (PackageManagerException e) {
9727                // If a system app update or an app and a required lib missing we
9728                // delete the package and for updated system apps keep the data as
9729                // it is better for the user to reinstall than to be in an limbo
9730                // state. Also libs disappearing under an app should never happen
9731                // - just in case.
9732                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9733                    final int flags = pkg.isUpdatedSystemApp()
9734                            ? PackageManager.DELETE_KEEP_DATA : 0;
9735                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9736                            flags , null, true, null);
9737                }
9738                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9739            }
9740        }
9741        return res;
9742    }
9743
9744    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9745            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9746            @Nullable UserHandle user) throws PackageManagerException {
9747        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9748        // If the package has children and this is the first dive in the function
9749        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9750        // whether all packages (parent and children) would be successfully scanned
9751        // before the actual scan since scanning mutates internal state and we want
9752        // to atomically install the package and its children.
9753        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9754            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9755                scanFlags |= SCAN_CHECK_ONLY;
9756            }
9757        } else {
9758            scanFlags &= ~SCAN_CHECK_ONLY;
9759        }
9760
9761        final PackageParser.Package scannedPkg;
9762        try {
9763            // Scan the parent
9764            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9765            // Scan the children
9766            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9767            for (int i = 0; i < childCount; i++) {
9768                PackageParser.Package childPkg = pkg.childPackages.get(i);
9769                scanPackageNewLI(childPkg, parseFlags,
9770                        scanFlags, currentTime, user);
9771            }
9772        } finally {
9773            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9774        }
9775
9776        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9777            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9778        }
9779
9780        return scannedPkg;
9781    }
9782
9783    /** The result of a package scan. */
9784    private static class ScanResult {
9785        /** Whether or not the package scan was successful */
9786        public final boolean success;
9787        /**
9788         * The final package settings. This may be the same object passed in
9789         * the {@link ScanRequest}, but, with modified values.
9790         */
9791        @Nullable public final PackageSetting pkgSetting;
9792        /** ABI code paths that have changed in the package scan */
9793        @Nullable public final List<String> changedAbiCodePath;
9794        public ScanResult(
9795                boolean success,
9796                @Nullable PackageSetting pkgSetting,
9797                @Nullable List<String> changedAbiCodePath) {
9798            this.success = success;
9799            this.pkgSetting = pkgSetting;
9800            this.changedAbiCodePath = changedAbiCodePath;
9801        }
9802    }
9803
9804    /** A package to be scanned */
9805    private static class ScanRequest {
9806        /** The parsed package */
9807        @NonNull public final PackageParser.Package pkg;
9808        /** Shared user settings, if the package has a shared user */
9809        @Nullable public final SharedUserSetting sharedUserSetting;
9810        /**
9811         * Package settings of the currently installed version.
9812         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9813         * during scan.
9814         */
9815        @Nullable public final PackageSetting pkgSetting;
9816        /** A copy of the settings for the currently installed version */
9817        @Nullable public final PackageSetting oldPkgSetting;
9818        /** Package settings for the disabled version on the /system partition */
9819        @Nullable public final PackageSetting disabledPkgSetting;
9820        /** Package settings for the installed version under its original package name */
9821        @Nullable public final PackageSetting originalPkgSetting;
9822        /** The real package name of a renamed application */
9823        @Nullable public final String realPkgName;
9824        public final @ParseFlags int parseFlags;
9825        public final @ScanFlags int scanFlags;
9826        /** The user for which the package is being scanned */
9827        @Nullable public final UserHandle user;
9828        /** Whether or not the platform package is being scanned */
9829        public final boolean isPlatformPackage;
9830        public ScanRequest(
9831                @NonNull PackageParser.Package pkg,
9832                @Nullable SharedUserSetting sharedUserSetting,
9833                @Nullable PackageSetting pkgSetting,
9834                @Nullable PackageSetting disabledPkgSetting,
9835                @Nullable PackageSetting originalPkgSetting,
9836                @Nullable String realPkgName,
9837                @ParseFlags int parseFlags,
9838                @ScanFlags int scanFlags,
9839                boolean isPlatformPackage,
9840                @Nullable UserHandle user) {
9841            this.pkg = pkg;
9842            this.pkgSetting = pkgSetting;
9843            this.sharedUserSetting = sharedUserSetting;
9844            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9845            this.disabledPkgSetting = disabledPkgSetting;
9846            this.originalPkgSetting = originalPkgSetting;
9847            this.realPkgName = realPkgName;
9848            this.parseFlags = parseFlags;
9849            this.scanFlags = scanFlags;
9850            this.isPlatformPackage = isPlatformPackage;
9851            this.user = user;
9852        }
9853    }
9854
9855    /**
9856     * Returns the actual scan flags depending upon the state of the other settings.
9857     * <p>Updated system applications will not have the following flags set
9858     * by default and need to be adjusted after the fact:
9859     * <ul>
9860     * <li>{@link #SCAN_AS_SYSTEM}</li>
9861     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
9862     * <li>{@link #SCAN_AS_OEM}</li>
9863     * <li>{@link #SCAN_AS_VENDOR}</li>
9864     * <li>{@link #SCAN_AS_PRODUCT}</li>
9865     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
9866     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
9867     * </ul>
9868     */
9869    private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
9870            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
9871            PackageParser.Package pkg) {
9872        if (disabledPkgSetting != null) {
9873            // updated system application, must at least have SCAN_AS_SYSTEM
9874            scanFlags |= SCAN_AS_SYSTEM;
9875            if ((disabledPkgSetting.pkgPrivateFlags
9876                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9877                scanFlags |= SCAN_AS_PRIVILEGED;
9878            }
9879            if ((disabledPkgSetting.pkgPrivateFlags
9880                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9881                scanFlags |= SCAN_AS_OEM;
9882            }
9883            if ((disabledPkgSetting.pkgPrivateFlags
9884                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
9885                scanFlags |= SCAN_AS_VENDOR;
9886            }
9887            if ((disabledPkgSetting.pkgPrivateFlags
9888                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
9889                scanFlags |= SCAN_AS_PRODUCT;
9890            }
9891        }
9892        if (pkgSetting != null) {
9893            final int userId = ((user == null) ? 0 : user.getIdentifier());
9894            if (pkgSetting.getInstantApp(userId)) {
9895                scanFlags |= SCAN_AS_INSTANT_APP;
9896            }
9897            if (pkgSetting.getVirtulalPreload(userId)) {
9898                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9899            }
9900        }
9901
9902        // Scan as privileged apps that share a user with a priv-app.
9903        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) && !pkg.isPrivileged()
9904                && (pkg.mSharedUserId != null)) {
9905            SharedUserSetting sharedUserSetting = null;
9906            try {
9907                sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
9908            } catch (PackageManagerException ignore) {}
9909            if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
9910                // Exempt SharedUsers signed with the platform key.
9911                // TODO(b/72378145) Fix this exemption. Force signature apps
9912                // to whitelist their privileged permissions just like other
9913                // priv-apps.
9914                synchronized (mPackages) {
9915                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
9916                    if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
9917                                pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
9918                        scanFlags |= SCAN_AS_PRIVILEGED;
9919                    }
9920                }
9921            }
9922        }
9923
9924        return scanFlags;
9925    }
9926
9927    @GuardedBy("mInstallLock")
9928    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9929            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9930            @Nullable UserHandle user) throws PackageManagerException {
9931
9932        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9933        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9934        if (realPkgName != null) {
9935            ensurePackageRenamed(pkg, renamedPkgName);
9936        }
9937        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9938        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9939        final PackageSetting disabledPkgSetting =
9940                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9941
9942        if (mTransferedPackages.contains(pkg.packageName)) {
9943            Slog.w(TAG, "Package " + pkg.packageName
9944                    + " was transferred to another, but its .apk remains");
9945        }
9946
9947        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
9948        synchronized (mPackages) {
9949            applyPolicy(pkg, parseFlags, scanFlags);
9950            assertPackageIsValid(pkg, parseFlags, scanFlags);
9951
9952            SharedUserSetting sharedUserSetting = null;
9953            if (pkg.mSharedUserId != null) {
9954                // SIDE EFFECTS; may potentially allocate a new shared user
9955                sharedUserSetting = mSettings.getSharedUserLPw(
9956                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9957                if (DEBUG_PACKAGE_SCANNING) {
9958                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9959                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9960                                + " (uid=" + sharedUserSetting.userId + "):"
9961                                + " packages=" + sharedUserSetting.packages);
9962                }
9963            }
9964
9965            boolean scanSucceeded = false;
9966            try {
9967                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
9968                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
9969                        (pkg == mPlatformPackage), user);
9970                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
9971                if (result.success) {
9972                    commitScanResultsLocked(request, result);
9973                }
9974                scanSucceeded = true;
9975            } finally {
9976                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9977                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
9978                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9979                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9980                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9981                  }
9982            }
9983        }
9984        return pkg;
9985    }
9986
9987    /**
9988     * Commits the package scan and modifies system state.
9989     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
9990     * of committing the package, leaving the system in an inconsistent state.
9991     * This needs to be fixed so, once we get to this point, no errors are
9992     * possible and the system is not left in an inconsistent state.
9993     */
9994    @GuardedBy("mPackages")
9995    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
9996            throws PackageManagerException {
9997        final PackageParser.Package pkg = request.pkg;
9998        final @ParseFlags int parseFlags = request.parseFlags;
9999        final @ScanFlags int scanFlags = request.scanFlags;
10000        final PackageSetting oldPkgSetting = request.oldPkgSetting;
10001        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10002        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10003        final UserHandle user = request.user;
10004        final String realPkgName = request.realPkgName;
10005        final PackageSetting pkgSetting = result.pkgSetting;
10006        final List<String> changedAbiCodePath = result.changedAbiCodePath;
10007        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
10008
10009        if (newPkgSettingCreated) {
10010            if (originalPkgSetting != null) {
10011                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
10012            }
10013            // THROWS: when we can't allocate a user id. add call to check if there's
10014            // enough space to ensure we won't throw; otherwise, don't modify state
10015            mSettings.addUserToSettingLPw(pkgSetting);
10016
10017            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
10018                mTransferedPackages.add(originalPkgSetting.name);
10019            }
10020        }
10021        // TODO(toddke): Consider a method specifically for modifying the Package object
10022        // post scan; or, moving this stuff out of the Package object since it has nothing
10023        // to do with the package on disk.
10024        // We need to have this here because addUserToSettingLPw() is sometimes responsible
10025        // for creating the application ID. If we did this earlier, we would be saving the
10026        // correct ID.
10027        pkg.applicationInfo.uid = pkgSetting.appId;
10028
10029        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10030
10031        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
10032            mTransferedPackages.add(pkg.packageName);
10033        }
10034
10035        // THROWS: when requested libraries that can't be found. it only changes
10036        // the state of the passed in pkg object, so, move to the top of the method
10037        // and allow it to abort
10038        if ((scanFlags & SCAN_BOOTING) == 0
10039                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10040            // Check all shared libraries and map to their actual file path.
10041            // We only do this here for apps not on a system dir, because those
10042            // are the only ones that can fail an install due to this.  We
10043            // will take care of the system apps by updating all of their
10044            // library paths after the scan is done. Also during the initial
10045            // scan don't update any libs as we do this wholesale after all
10046            // apps are scanned to avoid dependency based scanning.
10047            updateSharedLibrariesLPr(pkg, null);
10048        }
10049
10050        // All versions of a static shared library are referenced with the same
10051        // package name. Internally, we use a synthetic package name to allow
10052        // multiple versions of the same shared library to be installed. So,
10053        // we need to generate the synthetic package name of the latest shared
10054        // library in order to compare signatures.
10055        PackageSetting signatureCheckPs = pkgSetting;
10056        if (pkg.applicationInfo.isStaticSharedLibrary()) {
10057            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10058            if (libraryEntry != null) {
10059                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10060            }
10061        }
10062
10063        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10064        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
10065            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
10066                // We just determined the app is signed correctly, so bring
10067                // over the latest parsed certs.
10068                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10069            } else {
10070                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10071                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10072                            "Package " + pkg.packageName + " upgrade keys do not match the "
10073                                    + "previously installed version");
10074                } else {
10075                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10076                    String msg = "System package " + pkg.packageName
10077                            + " signature changed; retaining data.";
10078                    reportSettingsProblem(Log.WARN, msg);
10079                }
10080            }
10081        } else {
10082            try {
10083                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
10084                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
10085                final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
10086                        pkg.mSigningDetails, compareCompat, compareRecover);
10087                // The new KeySets will be re-added later in the scanning process.
10088                if (compatMatch) {
10089                    synchronized (mPackages) {
10090                        ksms.removeAppKeySetDataLPw(pkg.packageName);
10091                    }
10092                }
10093                // We just determined the app is signed correctly, so bring
10094                // over the latest parsed certs.
10095                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10096
10097
10098                // if this is is a sharedUser, check to see if the new package is signed by a newer
10099                // signing certificate than the existing one, and if so, copy over the new details
10100                if (signatureCheckPs.sharedUser != null
10101                        && pkg.mSigningDetails.hasAncestor(
10102                                signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
10103                    signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10104                }
10105            } catch (PackageManagerException e) {
10106                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10107                    throw e;
10108                }
10109                // The signature has changed, but this package is in the system
10110                // image...  let's recover!
10111                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10112                // However...  if this package is part of a shared user, but it
10113                // doesn't match the signature of the shared user, let's fail.
10114                // What this means is that you can't change the signatures
10115                // associated with an overall shared user, which doesn't seem all
10116                // that unreasonable.
10117                if (signatureCheckPs.sharedUser != null) {
10118                    if (compareSignatures(
10119                            signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
10120                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
10121                        throw new PackageManagerException(
10122                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10123                                "Signature mismatch for shared user: "
10124                                        + pkgSetting.sharedUser);
10125                    }
10126                }
10127                // File a report about this.
10128                String msg = "System package " + pkg.packageName
10129                        + " signature changed; retaining data.";
10130                reportSettingsProblem(Log.WARN, msg);
10131            } catch (IllegalArgumentException e) {
10132
10133                // should never happen: certs matched when checking, but not when comparing
10134                // old to new for sharedUser
10135                throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10136                        "Signing certificates comparison made on incomparable signing details"
10137                        + " but somehow passed verifySignatures!");
10138            }
10139        }
10140
10141        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10142            // This package wants to adopt ownership of permissions from
10143            // another package.
10144            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10145                final String origName = pkg.mAdoptPermissions.get(i);
10146                final PackageSetting orig = mSettings.getPackageLPr(origName);
10147                if (orig != null) {
10148                    if (verifyPackageUpdateLPr(orig, pkg)) {
10149                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
10150                                + pkg.packageName);
10151                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10152                    }
10153                }
10154            }
10155        }
10156
10157        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10158            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
10159                final String codePathString = changedAbiCodePath.get(i);
10160                try {
10161                    mInstaller.rmdex(codePathString,
10162                            getDexCodeInstructionSet(getPreferredInstructionSet()));
10163                } catch (InstallerException ignored) {
10164                }
10165            }
10166        }
10167
10168        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10169            if (oldPkgSetting != null) {
10170                synchronized (mPackages) {
10171                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10172                }
10173            }
10174        } else {
10175            final int userId = user == null ? 0 : user.getIdentifier();
10176            // Modify state for the given package setting
10177            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10178                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10179            if (pkgSetting.getInstantApp(userId)) {
10180                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10181            }
10182        }
10183    }
10184
10185    /**
10186     * Returns the "real" name of the package.
10187     * <p>This may differ from the package's actual name if the application has already
10188     * been installed under one of this package's original names.
10189     */
10190    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10191            @Nullable String renamedPkgName) {
10192        if (isPackageRenamed(pkg, renamedPkgName)) {
10193            return pkg.mRealPackage;
10194        }
10195        return null;
10196    }
10197
10198    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10199    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10200            @Nullable String renamedPkgName) {
10201        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10202    }
10203
10204    /**
10205     * Returns the original package setting.
10206     * <p>A package can migrate its name during an update. In this scenario, a package
10207     * designates a set of names that it considers as one of its original names.
10208     * <p>An original package must be signed identically and it must have the same
10209     * shared user [if any].
10210     */
10211    @GuardedBy("mPackages")
10212    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10213            @Nullable String renamedPkgName) {
10214        if (!isPackageRenamed(pkg, renamedPkgName)) {
10215            return null;
10216        }
10217        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10218            final PackageSetting originalPs =
10219                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10220            if (originalPs != null) {
10221                // the package is already installed under its original name...
10222                // but, should we use it?
10223                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10224                    // the new package is incompatible with the original
10225                    continue;
10226                } else if (originalPs.sharedUser != null) {
10227                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10228                        // the shared user id is incompatible with the original
10229                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10230                                + " to " + pkg.packageName + ": old uid "
10231                                + originalPs.sharedUser.name
10232                                + " differs from " + pkg.mSharedUserId);
10233                        continue;
10234                    }
10235                    // TODO: Add case when shared user id is added [b/28144775]
10236                } else {
10237                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10238                            + pkg.packageName + " to old name " + originalPs.name);
10239                }
10240                return originalPs;
10241            }
10242        }
10243        return null;
10244    }
10245
10246    /**
10247     * Renames the package if it was installed under a different name.
10248     * <p>When we've already installed the package under an original name, update
10249     * the new package so we can continue to have the old name.
10250     */
10251    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10252            @NonNull String renamedPackageName) {
10253        if (pkg.mOriginalPackages == null
10254                || !pkg.mOriginalPackages.contains(renamedPackageName)
10255                || pkg.packageName.equals(renamedPackageName)) {
10256            return;
10257        }
10258        pkg.setPackageName(renamedPackageName);
10259    }
10260
10261    /**
10262     * Just scans the package without any side effects.
10263     * <p>Not entirely true at the moment. There is still one side effect -- this
10264     * method potentially modifies a live {@link PackageSetting} object representing
10265     * the package being scanned. This will be resolved in the future.
10266     *
10267     * @param request Information about the package to be scanned
10268     * @param isUnderFactoryTest Whether or not the device is under factory test
10269     * @param currentTime The current time, in millis
10270     * @return The results of the scan
10271     */
10272    @GuardedBy("mInstallLock")
10273    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10274            boolean isUnderFactoryTest, long currentTime)
10275                    throws PackageManagerException {
10276        final PackageParser.Package pkg = request.pkg;
10277        PackageSetting pkgSetting = request.pkgSetting;
10278        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10279        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10280        final @ParseFlags int parseFlags = request.parseFlags;
10281        final @ScanFlags int scanFlags = request.scanFlags;
10282        final String realPkgName = request.realPkgName;
10283        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10284        final UserHandle user = request.user;
10285        final boolean isPlatformPackage = request.isPlatformPackage;
10286
10287        List<String> changedAbiCodePath = null;
10288
10289        if (DEBUG_PACKAGE_SCANNING) {
10290            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10291                Log.d(TAG, "Scanning package " + pkg.packageName);
10292        }
10293
10294        if (Build.IS_DEBUGGABLE &&
10295                pkg.isPrivileged() &&
10296                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10297            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10298        }
10299
10300        // Initialize package source and resource directories
10301        final File scanFile = new File(pkg.codePath);
10302        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10303        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10304
10305        // We keep references to the derived CPU Abis from settings in oder to reuse
10306        // them in the case where we're not upgrading or booting for the first time.
10307        String primaryCpuAbiFromSettings = null;
10308        String secondaryCpuAbiFromSettings = null;
10309        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10310
10311        if (!needToDeriveAbi) {
10312            if (pkgSetting != null) {
10313                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10314                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10315            } else {
10316                // Re-scanning a system package after uninstalling updates; need to derive ABI
10317                needToDeriveAbi = true;
10318            }
10319        }
10320
10321        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10322            PackageManagerService.reportSettingsProblem(Log.WARN,
10323                    "Package " + pkg.packageName + " shared user changed from "
10324                            + (pkgSetting.sharedUser != null
10325                            ? pkgSetting.sharedUser.name : "<nothing>")
10326                            + " to "
10327                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10328                            + "; replacing with new");
10329            pkgSetting = null;
10330        }
10331
10332        String[] usesStaticLibraries = null;
10333        if (pkg.usesStaticLibraries != null) {
10334            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10335            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10336        }
10337        final boolean createNewPackage = (pkgSetting == null);
10338        if (createNewPackage) {
10339            final String parentPackageName = (pkg.parentPackage != null)
10340                    ? pkg.parentPackage.packageName : null;
10341            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10342            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10343            // REMOVE SharedUserSetting from method; update in a separate call
10344            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10345                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10346                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10347                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10348                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10349                    user, true /*allowInstall*/, instantApp, virtualPreload,
10350                    parentPackageName, pkg.getChildPackageNames(),
10351                    UserManagerService.getInstance(), usesStaticLibraries,
10352                    pkg.usesStaticLibrariesVersions);
10353        } else {
10354            // REMOVE SharedUserSetting from method; update in a separate call.
10355            //
10356            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10357            // secondaryCpuAbi are not known at this point so we always update them
10358            // to null here, only to reset them at a later point.
10359            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10360                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10361                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10362                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10363                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10364                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10365        }
10366        if (createNewPackage && originalPkgSetting != null) {
10367            // This is the initial transition from the original package, so,
10368            // fix up the new package's name now. We must do this after looking
10369            // up the package under its new name, so getPackageLP takes care of
10370            // fiddling things correctly.
10371            pkg.setPackageName(originalPkgSetting.name);
10372
10373            // File a report about this.
10374            String msg = "New package " + pkgSetting.realName
10375                    + " renamed to replace old package " + pkgSetting.name;
10376            reportSettingsProblem(Log.WARN, msg);
10377        }
10378
10379        if (disabledPkgSetting != null) {
10380            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10381        }
10382
10383        // Apps which share a sharedUserId must be placed in the same selinux domain. If this
10384        // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
10385        // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
10386        // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
10387        // least restrictive selinux domain.
10388        // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
10389        // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
10390        // ensures that all packages continue to run in the same selinux domain.
10391        final int targetSdkVersion =
10392            ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
10393            sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
10394        // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
10395        // They currently can be if the sharedUser apps are signed with the platform key.
10396        final boolean isPrivileged = (sharedUserSetting != null) ?
10397            sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
10398
10399        pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
10400                pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
10401
10402        pkg.mExtras = pkgSetting;
10403        pkg.applicationInfo.processName = fixProcessName(
10404                pkg.applicationInfo.packageName,
10405                pkg.applicationInfo.processName);
10406
10407        if (!isPlatformPackage) {
10408            // Get all of our default paths setup
10409            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10410        }
10411
10412        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10413
10414        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10415            if (needToDeriveAbi) {
10416                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10417                final boolean extractNativeLibs = !pkg.isLibrary();
10418                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10419                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10420
10421                // Some system apps still use directory structure for native libraries
10422                // in which case we might end up not detecting abi solely based on apk
10423                // structure. Try to detect abi based on directory structure.
10424                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10425                        pkg.applicationInfo.primaryCpuAbi == null) {
10426                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10427                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10428                }
10429            } else {
10430                // This is not a first boot or an upgrade, don't bother deriving the
10431                // ABI during the scan. Instead, trust the value that was stored in the
10432                // package setting.
10433                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10434                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10435
10436                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10437
10438                if (DEBUG_ABI_SELECTION) {
10439                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10440                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10441                            pkg.applicationInfo.secondaryCpuAbi);
10442                }
10443            }
10444        } else {
10445            if ((scanFlags & SCAN_MOVE) != 0) {
10446                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10447                // but we already have this packages package info in the PackageSetting. We just
10448                // use that and derive the native library path based on the new codepath.
10449                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10450                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10451            }
10452
10453            // Set native library paths again. For moves, the path will be updated based on the
10454            // ABIs we've determined above. For non-moves, the path will be updated based on the
10455            // ABIs we determined during compilation, but the path will depend on the final
10456            // package path (after the rename away from the stage path).
10457            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10458        }
10459
10460        // This is a special case for the "system" package, where the ABI is
10461        // dictated by the zygote configuration (and init.rc). We should keep track
10462        // of this ABI so that we can deal with "normal" applications that run under
10463        // the same UID correctly.
10464        if (isPlatformPackage) {
10465            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10466                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10467        }
10468
10469        // If there's a mismatch between the abi-override in the package setting
10470        // and the abiOverride specified for the install. Warn about this because we
10471        // would've already compiled the app without taking the package setting into
10472        // account.
10473        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10474            if (cpuAbiOverride == null && pkg.packageName != null) {
10475                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10476                        " for package " + pkg.packageName);
10477            }
10478        }
10479
10480        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10481        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10482        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10483
10484        // Copy the derived override back to the parsed package, so that we can
10485        // update the package settings accordingly.
10486        pkg.cpuAbiOverride = cpuAbiOverride;
10487
10488        if (DEBUG_ABI_SELECTION) {
10489            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10490                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10491                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10492        }
10493
10494        // Push the derived path down into PackageSettings so we know what to
10495        // clean up at uninstall time.
10496        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10497
10498        if (DEBUG_ABI_SELECTION) {
10499            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10500                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10501                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10502        }
10503
10504        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10505            // We don't do this here during boot because we can do it all
10506            // at once after scanning all existing packages.
10507            //
10508            // We also do this *before* we perform dexopt on this package, so that
10509            // we can avoid redundant dexopts, and also to make sure we've got the
10510            // code and package path correct.
10511            changedAbiCodePath =
10512                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10513        }
10514
10515        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10516                android.Manifest.permission.FACTORY_TEST)) {
10517            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10518        }
10519
10520        if (isSystemApp(pkg)) {
10521            pkgSetting.isOrphaned = true;
10522        }
10523
10524        // Take care of first install / last update times.
10525        final long scanFileTime = getLastModifiedTime(pkg);
10526        if (currentTime != 0) {
10527            if (pkgSetting.firstInstallTime == 0) {
10528                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10529            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10530                pkgSetting.lastUpdateTime = currentTime;
10531            }
10532        } else if (pkgSetting.firstInstallTime == 0) {
10533            // We need *something*.  Take time time stamp of the file.
10534            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10535        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10536            if (scanFileTime != pkgSetting.timeStamp) {
10537                // A package on the system image has changed; consider this
10538                // to be an update.
10539                pkgSetting.lastUpdateTime = scanFileTime;
10540            }
10541        }
10542        pkgSetting.setTimeStamp(scanFileTime);
10543
10544        pkgSetting.pkg = pkg;
10545        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10546        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10547            pkgSetting.versionCode = pkg.getLongVersionCode();
10548        }
10549        // Update volume if needed
10550        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10551        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10552            Slog.i(PackageManagerService.TAG,
10553                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10554                    + " package " + pkg.packageName
10555                    + " volume from " + pkgSetting.volumeUuid
10556                    + " to " + volumeUuid);
10557            pkgSetting.volumeUuid = volumeUuid;
10558        }
10559
10560        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10561    }
10562
10563    /**
10564     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10565     */
10566    private static boolean apkHasCode(String fileName) {
10567        StrictJarFile jarFile = null;
10568        try {
10569            jarFile = new StrictJarFile(fileName,
10570                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10571            return jarFile.findEntry("classes.dex") != null;
10572        } catch (IOException ignore) {
10573        } finally {
10574            try {
10575                if (jarFile != null) {
10576                    jarFile.close();
10577                }
10578            } catch (IOException ignore) {}
10579        }
10580        return false;
10581    }
10582
10583    /**
10584     * Enforces code policy for the package. This ensures that if an APK has
10585     * declared hasCode="true" in its manifest that the APK actually contains
10586     * code.
10587     *
10588     * @throws PackageManagerException If bytecode could not be found when it should exist
10589     */
10590    private static void assertCodePolicy(PackageParser.Package pkg)
10591            throws PackageManagerException {
10592        final boolean shouldHaveCode =
10593                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10594        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10595            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10596                    "Package " + pkg.baseCodePath + " code is missing");
10597        }
10598
10599        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10600            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10601                final boolean splitShouldHaveCode =
10602                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10603                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10604                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10605                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10606                }
10607            }
10608        }
10609    }
10610
10611    /**
10612     * Applies policy to the parsed package based upon the given policy flags.
10613     * Ensures the package is in a good state.
10614     * <p>
10615     * Implementation detail: This method must NOT have any side effect. It would
10616     * ideally be static, but, it requires locks to read system state.
10617     */
10618    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10619            final @ScanFlags int scanFlags) {
10620        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10621            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10622            if (pkg.applicationInfo.isDirectBootAware()) {
10623                // we're direct boot aware; set for all components
10624                for (PackageParser.Service s : pkg.services) {
10625                    s.info.encryptionAware = s.info.directBootAware = true;
10626                }
10627                for (PackageParser.Provider p : pkg.providers) {
10628                    p.info.encryptionAware = p.info.directBootAware = true;
10629                }
10630                for (PackageParser.Activity a : pkg.activities) {
10631                    a.info.encryptionAware = a.info.directBootAware = true;
10632                }
10633                for (PackageParser.Activity r : pkg.receivers) {
10634                    r.info.encryptionAware = r.info.directBootAware = true;
10635                }
10636            }
10637            if (compressedFileExists(pkg.codePath)) {
10638                pkg.isStub = true;
10639            }
10640        } else {
10641            // non system apps can't be flagged as core
10642            pkg.coreApp = false;
10643            // clear flags not applicable to regular apps
10644            pkg.applicationInfo.flags &=
10645                    ~ApplicationInfo.FLAG_PERSISTENT;
10646            pkg.applicationInfo.privateFlags &=
10647                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10648            pkg.applicationInfo.privateFlags &=
10649                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10650            // cap permission priorities
10651            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10652                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10653                    pkg.permissionGroups.get(i).info.priority = 0;
10654                }
10655            }
10656        }
10657        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10658            // clear protected broadcasts
10659            pkg.protectedBroadcasts = null;
10660            // ignore export request for single user receivers
10661            if (pkg.receivers != null) {
10662                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10663                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10664                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10665                        receiver.info.exported = false;
10666                    }
10667                }
10668            }
10669            // ignore export request for single user services
10670            if (pkg.services != null) {
10671                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10672                    final PackageParser.Service service = pkg.services.get(i);
10673                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10674                        service.info.exported = false;
10675                    }
10676                }
10677            }
10678            // ignore export request for single user providers
10679            if (pkg.providers != null) {
10680                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10681                    final PackageParser.Provider provider = pkg.providers.get(i);
10682                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10683                        provider.info.exported = false;
10684                    }
10685                }
10686            }
10687        }
10688
10689        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10690            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10691        }
10692
10693        if ((scanFlags & SCAN_AS_OEM) != 0) {
10694            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10695        }
10696
10697        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10698            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10699        }
10700
10701        if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
10702            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
10703        }
10704
10705        if (!isSystemApp(pkg)) {
10706            // Only system apps can use these features.
10707            pkg.mOriginalPackages = null;
10708            pkg.mRealPackage = null;
10709            pkg.mAdoptPermissions = null;
10710        }
10711    }
10712
10713    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
10714            throws PackageManagerException {
10715        if (object == null) {
10716            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
10717        }
10718        return object;
10719    }
10720
10721    /**
10722     * Asserts the parsed package is valid according to the given policy. If the
10723     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10724     * <p>
10725     * Implementation detail: This method must NOT have any side effects. It would
10726     * ideally be static, but, it requires locks to read system state.
10727     *
10728     * @throws PackageManagerException If the package fails any of the validation checks
10729     */
10730    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10731            final @ScanFlags int scanFlags)
10732                    throws PackageManagerException {
10733        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10734            assertCodePolicy(pkg);
10735        }
10736
10737        if (pkg.applicationInfo.getCodePath() == null ||
10738                pkg.applicationInfo.getResourcePath() == null) {
10739            // Bail out. The resource and code paths haven't been set.
10740            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10741                    "Code and resource paths haven't been set correctly");
10742        }
10743
10744        // Make sure we're not adding any bogus keyset info
10745        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10746        ksms.assertScannedPackageValid(pkg);
10747
10748        synchronized (mPackages) {
10749            // The special "android" package can only be defined once
10750            if (pkg.packageName.equals("android")) {
10751                if (mAndroidApplication != null) {
10752                    Slog.w(TAG, "*************************************************");
10753                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10754                    Slog.w(TAG, " codePath=" + pkg.codePath);
10755                    Slog.w(TAG, "*************************************************");
10756                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10757                            "Core android package being redefined.  Skipping.");
10758                }
10759            }
10760
10761            // A package name must be unique; don't allow duplicates
10762            if (mPackages.containsKey(pkg.packageName)) {
10763                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10764                        "Application package " + pkg.packageName
10765                        + " already installed.  Skipping duplicate.");
10766            }
10767
10768            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10769                // Static libs have a synthetic package name containing the version
10770                // but we still want the base name to be unique.
10771                if (mPackages.containsKey(pkg.manifestPackageName)) {
10772                    throw new PackageManagerException(
10773                            "Duplicate static shared lib provider package");
10774                }
10775
10776                // Static shared libraries should have at least O target SDK
10777                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10778                    throw new PackageManagerException(
10779                            "Packages declaring static-shared libs must target O SDK or higher");
10780                }
10781
10782                // Package declaring static a shared lib cannot be instant apps
10783                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10784                    throw new PackageManagerException(
10785                            "Packages declaring static-shared libs cannot be instant apps");
10786                }
10787
10788                // Package declaring static a shared lib cannot be renamed since the package
10789                // name is synthetic and apps can't code around package manager internals.
10790                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10791                    throw new PackageManagerException(
10792                            "Packages declaring static-shared libs cannot be renamed");
10793                }
10794
10795                // Package declaring static a shared lib cannot declare child packages
10796                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10797                    throw new PackageManagerException(
10798                            "Packages declaring static-shared libs cannot have child packages");
10799                }
10800
10801                // Package declaring static a shared lib cannot declare dynamic libs
10802                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10803                    throw new PackageManagerException(
10804                            "Packages declaring static-shared libs cannot declare dynamic libs");
10805                }
10806
10807                // Package declaring static a shared lib cannot declare shared users
10808                if (pkg.mSharedUserId != null) {
10809                    throw new PackageManagerException(
10810                            "Packages declaring static-shared libs cannot declare shared users");
10811                }
10812
10813                // Static shared libs cannot declare activities
10814                if (!pkg.activities.isEmpty()) {
10815                    throw new PackageManagerException(
10816                            "Static shared libs cannot declare activities");
10817                }
10818
10819                // Static shared libs cannot declare services
10820                if (!pkg.services.isEmpty()) {
10821                    throw new PackageManagerException(
10822                            "Static shared libs cannot declare services");
10823                }
10824
10825                // Static shared libs cannot declare providers
10826                if (!pkg.providers.isEmpty()) {
10827                    throw new PackageManagerException(
10828                            "Static shared libs cannot declare content providers");
10829                }
10830
10831                // Static shared libs cannot declare receivers
10832                if (!pkg.receivers.isEmpty()) {
10833                    throw new PackageManagerException(
10834                            "Static shared libs cannot declare broadcast receivers");
10835                }
10836
10837                // Static shared libs cannot declare permission groups
10838                if (!pkg.permissionGroups.isEmpty()) {
10839                    throw new PackageManagerException(
10840                            "Static shared libs cannot declare permission groups");
10841                }
10842
10843                // Static shared libs cannot declare permissions
10844                if (!pkg.permissions.isEmpty()) {
10845                    throw new PackageManagerException(
10846                            "Static shared libs cannot declare permissions");
10847                }
10848
10849                // Static shared libs cannot declare protected broadcasts
10850                if (pkg.protectedBroadcasts != null) {
10851                    throw new PackageManagerException(
10852                            "Static shared libs cannot declare protected broadcasts");
10853                }
10854
10855                // Static shared libs cannot be overlay targets
10856                if (pkg.mOverlayTarget != null) {
10857                    throw new PackageManagerException(
10858                            "Static shared libs cannot be overlay targets");
10859                }
10860
10861                // The version codes must be ordered as lib versions
10862                long minVersionCode = Long.MIN_VALUE;
10863                long maxVersionCode = Long.MAX_VALUE;
10864
10865                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10866                        pkg.staticSharedLibName);
10867                if (versionedLib != null) {
10868                    final int versionCount = versionedLib.size();
10869                    for (int i = 0; i < versionCount; i++) {
10870                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10871                        final long libVersionCode = libInfo.getDeclaringPackage()
10872                                .getLongVersionCode();
10873                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10874                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10875                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10876                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10877                        } else {
10878                            minVersionCode = maxVersionCode = libVersionCode;
10879                            break;
10880                        }
10881                    }
10882                }
10883                if (pkg.getLongVersionCode() < minVersionCode
10884                        || pkg.getLongVersionCode() > maxVersionCode) {
10885                    throw new PackageManagerException("Static shared"
10886                            + " lib version codes must be ordered as lib versions");
10887                }
10888            }
10889
10890            // Only privileged apps and updated privileged apps can add child packages.
10891            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10892                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10893                    throw new PackageManagerException("Only privileged apps can add child "
10894                            + "packages. Ignoring package " + pkg.packageName);
10895                }
10896                final int childCount = pkg.childPackages.size();
10897                for (int i = 0; i < childCount; i++) {
10898                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10899                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10900                            childPkg.packageName)) {
10901                        throw new PackageManagerException("Can't override child of "
10902                                + "another disabled app. Ignoring package " + pkg.packageName);
10903                    }
10904                }
10905            }
10906
10907            // If we're only installing presumed-existing packages, require that the
10908            // scanned APK is both already known and at the path previously established
10909            // for it.  Previously unknown packages we pick up normally, but if we have an
10910            // a priori expectation about this package's install presence, enforce it.
10911            // With a singular exception for new system packages. When an OTA contains
10912            // a new system package, we allow the codepath to change from a system location
10913            // to the user-installed location. If we don't allow this change, any newer,
10914            // user-installed version of the application will be ignored.
10915            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10916                if (mExpectingBetter.containsKey(pkg.packageName)) {
10917                    logCriticalInfo(Log.WARN,
10918                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10919                } else {
10920                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10921                    if (known != null) {
10922                        if (DEBUG_PACKAGE_SCANNING) {
10923                            Log.d(TAG, "Examining " + pkg.codePath
10924                                    + " and requiring known paths " + known.codePathString
10925                                    + " & " + known.resourcePathString);
10926                        }
10927                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10928                                || !pkg.applicationInfo.getResourcePath().equals(
10929                                        known.resourcePathString)) {
10930                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10931                                    "Application package " + pkg.packageName
10932                                    + " found at " + pkg.applicationInfo.getCodePath()
10933                                    + " but expected at " + known.codePathString
10934                                    + "; ignoring.");
10935                        }
10936                    } else {
10937                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10938                                "Application package " + pkg.packageName
10939                                + " not found; ignoring.");
10940                    }
10941                }
10942            }
10943
10944            // Verify that this new package doesn't have any content providers
10945            // that conflict with existing packages.  Only do this if the
10946            // package isn't already installed, since we don't want to break
10947            // things that are installed.
10948            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10949                final int N = pkg.providers.size();
10950                int i;
10951                for (i=0; i<N; i++) {
10952                    PackageParser.Provider p = pkg.providers.get(i);
10953                    if (p.info.authority != null) {
10954                        String names[] = p.info.authority.split(";");
10955                        for (int j = 0; j < names.length; j++) {
10956                            if (mProvidersByAuthority.containsKey(names[j])) {
10957                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10958                                final String otherPackageName =
10959                                        ((other != null && other.getComponentName() != null) ?
10960                                                other.getComponentName().getPackageName() : "?");
10961                                throw new PackageManagerException(
10962                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10963                                        "Can't install because provider name " + names[j]
10964                                                + " (in package " + pkg.applicationInfo.packageName
10965                                                + ") is already used by " + otherPackageName);
10966                            }
10967                        }
10968                    }
10969                }
10970            }
10971
10972            // Verify that packages sharing a user with a privileged app are marked as privileged.
10973            if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
10974                SharedUserSetting sharedUserSetting = null;
10975                try {
10976                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
10977                } catch (PackageManagerException ignore) {}
10978                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10979                    // Exempt SharedUsers signed with the platform key.
10980                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10981                    if ((platformPkgSetting.signatures.mSigningDetails
10982                            != PackageParser.SigningDetails.UNKNOWN)
10983                            && (compareSignatures(
10984                                    platformPkgSetting.signatures.mSigningDetails.signatures,
10985                                    pkg.mSigningDetails.signatures)
10986                                            != PackageManager.SIGNATURE_MATCH)) {
10987                        throw new PackageManagerException("Apps that share a user with a " +
10988                                "privileged app must themselves be marked as privileged. " +
10989                                pkg.packageName + " shares privileged user " +
10990                                pkg.mSharedUserId + ".");
10991                    }
10992                }
10993            }
10994
10995            // Apply policies specific for runtime resource overlays (RROs).
10996            if (pkg.mOverlayTarget != null) {
10997                // System overlays have some restrictions on their use of the 'static' state.
10998                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10999                    // We are scanning a system overlay. This can be the first scan of the
11000                    // system/vendor/oem partition, or an update to the system overlay.
11001                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11002                        // This must be an update to a system overlay.
11003                        final PackageSetting previousPkg = assertNotNull(
11004                                mSettings.getPackageLPr(pkg.packageName),
11005                                "previous package state not present");
11006
11007                        // Static overlays cannot be updated.
11008                        if (previousPkg.pkg.mOverlayIsStatic) {
11009                            throw new PackageManagerException("Overlay " + pkg.packageName +
11010                                    " is static and cannot be upgraded.");
11011                        // Non-static overlays cannot be converted to static overlays.
11012                        } else if (pkg.mOverlayIsStatic) {
11013                            throw new PackageManagerException("Overlay " + pkg.packageName +
11014                                    " cannot be upgraded into a static overlay.");
11015                        }
11016                    }
11017                } else {
11018                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
11019                    if (pkg.mOverlayIsStatic) {
11020                        throw new PackageManagerException("Overlay " + pkg.packageName +
11021                                " is static but not pre-installed.");
11022                    }
11023
11024                    // The only case where we allow installation of a non-system overlay is when
11025                    // its signature is signed with the platform certificate.
11026                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
11027                    if ((platformPkgSetting.signatures.mSigningDetails
11028                            != PackageParser.SigningDetails.UNKNOWN)
11029                            && (compareSignatures(
11030                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11031                                    pkg.mSigningDetails.signatures)
11032                                            != PackageManager.SIGNATURE_MATCH)) {
11033                        throw new PackageManagerException("Overlay " + pkg.packageName +
11034                                " must be signed with the platform certificate.");
11035                    }
11036                }
11037            }
11038        }
11039    }
11040
11041    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
11042            int type, String declaringPackageName, long declaringVersionCode) {
11043        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11044        if (versionedLib == null) {
11045            versionedLib = new LongSparseArray<>();
11046            mSharedLibraries.put(name, versionedLib);
11047            if (type == SharedLibraryInfo.TYPE_STATIC) {
11048                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11049            }
11050        } else if (versionedLib.indexOfKey(version) >= 0) {
11051            return false;
11052        }
11053        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11054                version, type, declaringPackageName, declaringVersionCode);
11055        versionedLib.put(version, libEntry);
11056        return true;
11057    }
11058
11059    private boolean removeSharedLibraryLPw(String name, long version) {
11060        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11061        if (versionedLib == null) {
11062            return false;
11063        }
11064        final int libIdx = versionedLib.indexOfKey(version);
11065        if (libIdx < 0) {
11066            return false;
11067        }
11068        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11069        versionedLib.remove(version);
11070        if (versionedLib.size() <= 0) {
11071            mSharedLibraries.remove(name);
11072            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11073                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11074                        .getPackageName());
11075            }
11076        }
11077        return true;
11078    }
11079
11080    /**
11081     * Adds a scanned package to the system. When this method is finished, the package will
11082     * be available for query, resolution, etc...
11083     */
11084    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11085            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
11086        final String pkgName = pkg.packageName;
11087        if (mCustomResolverComponentName != null &&
11088                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11089            setUpCustomResolverActivity(pkg);
11090        }
11091
11092        if (pkg.packageName.equals("android")) {
11093            synchronized (mPackages) {
11094                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11095                    // Set up information for our fall-back user intent resolution activity.
11096                    mPlatformPackage = pkg;
11097                    pkg.mVersionCode = mSdkVersion;
11098                    pkg.mVersionCodeMajor = 0;
11099                    mAndroidApplication = pkg.applicationInfo;
11100                    if (!mResolverReplaced) {
11101                        mResolveActivity.applicationInfo = mAndroidApplication;
11102                        mResolveActivity.name = ResolverActivity.class.getName();
11103                        mResolveActivity.packageName = mAndroidApplication.packageName;
11104                        mResolveActivity.processName = "system:ui";
11105                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11106                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11107                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11108                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11109                        mResolveActivity.exported = true;
11110                        mResolveActivity.enabled = true;
11111                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11112                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11113                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11114                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11115                                | ActivityInfo.CONFIG_ORIENTATION
11116                                | ActivityInfo.CONFIG_KEYBOARD
11117                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11118                        mResolveInfo.activityInfo = mResolveActivity;
11119                        mResolveInfo.priority = 0;
11120                        mResolveInfo.preferredOrder = 0;
11121                        mResolveInfo.match = 0;
11122                        mResolveComponentName = new ComponentName(
11123                                mAndroidApplication.packageName, mResolveActivity.name);
11124                    }
11125                }
11126            }
11127        }
11128
11129        ArrayList<PackageParser.Package> clientLibPkgs = null;
11130        // writer
11131        synchronized (mPackages) {
11132            boolean hasStaticSharedLibs = false;
11133
11134            // Any app can add new static shared libraries
11135            if (pkg.staticSharedLibName != null) {
11136                // Static shared libs don't allow renaming as they have synthetic package
11137                // names to allow install of multiple versions, so use name from manifest.
11138                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11139                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11140                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
11141                    hasStaticSharedLibs = true;
11142                } else {
11143                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11144                                + pkg.staticSharedLibName + " already exists; skipping");
11145                }
11146                // Static shared libs cannot be updated once installed since they
11147                // use synthetic package name which includes the version code, so
11148                // not need to update other packages's shared lib dependencies.
11149            }
11150
11151            if (!hasStaticSharedLibs
11152                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11153                // Only system apps can add new dynamic shared libraries.
11154                if (pkg.libraryNames != null) {
11155                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11156                        String name = pkg.libraryNames.get(i);
11157                        boolean allowed = false;
11158                        if (pkg.isUpdatedSystemApp()) {
11159                            // New library entries can only be added through the
11160                            // system image.  This is important to get rid of a lot
11161                            // of nasty edge cases: for example if we allowed a non-
11162                            // system update of the app to add a library, then uninstalling
11163                            // the update would make the library go away, and assumptions
11164                            // we made such as through app install filtering would now
11165                            // have allowed apps on the device which aren't compatible
11166                            // with it.  Better to just have the restriction here, be
11167                            // conservative, and create many fewer cases that can negatively
11168                            // impact the user experience.
11169                            final PackageSetting sysPs = mSettings
11170                                    .getDisabledSystemPkgLPr(pkg.packageName);
11171                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11172                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11173                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11174                                        allowed = true;
11175                                        break;
11176                                    }
11177                                }
11178                            }
11179                        } else {
11180                            allowed = true;
11181                        }
11182                        if (allowed) {
11183                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11184                                    SharedLibraryInfo.VERSION_UNDEFINED,
11185                                    SharedLibraryInfo.TYPE_DYNAMIC,
11186                                    pkg.packageName, pkg.getLongVersionCode())) {
11187                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11188                                        + name + " already exists; skipping");
11189                            }
11190                        } else {
11191                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11192                                    + name + " that is not declared on system image; skipping");
11193                        }
11194                    }
11195
11196                    if ((scanFlags & SCAN_BOOTING) == 0) {
11197                        // If we are not booting, we need to update any applications
11198                        // that are clients of our shared library.  If we are booting,
11199                        // this will all be done once the scan is complete.
11200                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11201                    }
11202                }
11203            }
11204        }
11205
11206        if ((scanFlags & SCAN_BOOTING) != 0) {
11207            // No apps can run during boot scan, so they don't need to be frozen
11208        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11209            // Caller asked to not kill app, so it's probably not frozen
11210        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11211            // Caller asked us to ignore frozen check for some reason; they
11212            // probably didn't know the package name
11213        } else {
11214            // We're doing major surgery on this package, so it better be frozen
11215            // right now to keep it from launching
11216            checkPackageFrozen(pkgName);
11217        }
11218
11219        // Also need to kill any apps that are dependent on the library.
11220        if (clientLibPkgs != null) {
11221            for (int i=0; i<clientLibPkgs.size(); i++) {
11222                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11223                killApplication(clientPkg.applicationInfo.packageName,
11224                        clientPkg.applicationInfo.uid, "update lib");
11225            }
11226        }
11227
11228        // writer
11229        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11230
11231        synchronized (mPackages) {
11232            // We don't expect installation to fail beyond this point
11233
11234            // Add the new setting to mSettings
11235            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11236            // Add the new setting to mPackages
11237            mPackages.put(pkg.applicationInfo.packageName, pkg);
11238            // Make sure we don't accidentally delete its data.
11239            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11240            while (iter.hasNext()) {
11241                PackageCleanItem item = iter.next();
11242                if (pkgName.equals(item.packageName)) {
11243                    iter.remove();
11244                }
11245            }
11246
11247            // Add the package's KeySets to the global KeySetManagerService
11248            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11249            ksms.addScannedPackageLPw(pkg);
11250
11251            int N = pkg.providers.size();
11252            StringBuilder r = null;
11253            int i;
11254            for (i=0; i<N; i++) {
11255                PackageParser.Provider p = pkg.providers.get(i);
11256                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11257                        p.info.processName);
11258                mProviders.addProvider(p);
11259                p.syncable = p.info.isSyncable;
11260                if (p.info.authority != null) {
11261                    String names[] = p.info.authority.split(";");
11262                    p.info.authority = null;
11263                    for (int j = 0; j < names.length; j++) {
11264                        if (j == 1 && p.syncable) {
11265                            // We only want the first authority for a provider to possibly be
11266                            // syncable, so if we already added this provider using a different
11267                            // authority clear the syncable flag. We copy the provider before
11268                            // changing it because the mProviders object contains a reference
11269                            // to a provider that we don't want to change.
11270                            // Only do this for the second authority since the resulting provider
11271                            // object can be the same for all future authorities for this provider.
11272                            p = new PackageParser.Provider(p);
11273                            p.syncable = false;
11274                        }
11275                        if (!mProvidersByAuthority.containsKey(names[j])) {
11276                            mProvidersByAuthority.put(names[j], p);
11277                            if (p.info.authority == null) {
11278                                p.info.authority = names[j];
11279                            } else {
11280                                p.info.authority = p.info.authority + ";" + names[j];
11281                            }
11282                            if (DEBUG_PACKAGE_SCANNING) {
11283                                if (chatty)
11284                                    Log.d(TAG, "Registered content provider: " + names[j]
11285                                            + ", className = " + p.info.name + ", isSyncable = "
11286                                            + p.info.isSyncable);
11287                            }
11288                        } else {
11289                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11290                            Slog.w(TAG, "Skipping provider name " + names[j] +
11291                                    " (in package " + pkg.applicationInfo.packageName +
11292                                    "): name already used by "
11293                                    + ((other != null && other.getComponentName() != null)
11294                                            ? other.getComponentName().getPackageName() : "?"));
11295                        }
11296                    }
11297                }
11298                if (chatty) {
11299                    if (r == null) {
11300                        r = new StringBuilder(256);
11301                    } else {
11302                        r.append(' ');
11303                    }
11304                    r.append(p.info.name);
11305                }
11306            }
11307            if (r != null) {
11308                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11309            }
11310
11311            N = pkg.services.size();
11312            r = null;
11313            for (i=0; i<N; i++) {
11314                PackageParser.Service s = pkg.services.get(i);
11315                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11316                        s.info.processName);
11317                mServices.addService(s);
11318                if (chatty) {
11319                    if (r == null) {
11320                        r = new StringBuilder(256);
11321                    } else {
11322                        r.append(' ');
11323                    }
11324                    r.append(s.info.name);
11325                }
11326            }
11327            if (r != null) {
11328                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11329            }
11330
11331            N = pkg.receivers.size();
11332            r = null;
11333            for (i=0; i<N; i++) {
11334                PackageParser.Activity a = pkg.receivers.get(i);
11335                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11336                        a.info.processName);
11337                mReceivers.addActivity(a, "receiver");
11338                if (chatty) {
11339                    if (r == null) {
11340                        r = new StringBuilder(256);
11341                    } else {
11342                        r.append(' ');
11343                    }
11344                    r.append(a.info.name);
11345                }
11346            }
11347            if (r != null) {
11348                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11349            }
11350
11351            N = pkg.activities.size();
11352            r = null;
11353            for (i=0; i<N; i++) {
11354                PackageParser.Activity a = pkg.activities.get(i);
11355                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11356                        a.info.processName);
11357                mActivities.addActivity(a, "activity");
11358                if (chatty) {
11359                    if (r == null) {
11360                        r = new StringBuilder(256);
11361                    } else {
11362                        r.append(' ');
11363                    }
11364                    r.append(a.info.name);
11365                }
11366            }
11367            if (r != null) {
11368                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11369            }
11370
11371            // Don't allow ephemeral applications to define new permissions groups.
11372            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11373                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11374                        + " ignored: instant apps cannot define new permission groups.");
11375            } else {
11376                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11377            }
11378
11379            // Don't allow ephemeral applications to define new permissions.
11380            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11381                Slog.w(TAG, "Permissions from package " + pkg.packageName
11382                        + " ignored: instant apps cannot define new permissions.");
11383            } else {
11384                mPermissionManager.addAllPermissions(pkg, chatty);
11385            }
11386
11387            N = pkg.instrumentation.size();
11388            r = null;
11389            for (i=0; i<N; i++) {
11390                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11391                a.info.packageName = pkg.applicationInfo.packageName;
11392                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11393                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11394                a.info.splitNames = pkg.splitNames;
11395                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11396                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11397                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11398                a.info.dataDir = pkg.applicationInfo.dataDir;
11399                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11400                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11401                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11402                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11403                mInstrumentation.put(a.getComponentName(), a);
11404                if (chatty) {
11405                    if (r == null) {
11406                        r = new StringBuilder(256);
11407                    } else {
11408                        r.append(' ');
11409                    }
11410                    r.append(a.info.name);
11411                }
11412            }
11413            if (r != null) {
11414                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11415            }
11416
11417            if (pkg.protectedBroadcasts != null) {
11418                N = pkg.protectedBroadcasts.size();
11419                synchronized (mProtectedBroadcasts) {
11420                    for (i = 0; i < N; i++) {
11421                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11422                    }
11423                }
11424            }
11425        }
11426
11427        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11428    }
11429
11430    /**
11431     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11432     * is derived purely on the basis of the contents of {@code scanFile} and
11433     * {@code cpuAbiOverride}.
11434     *
11435     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11436     */
11437    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11438            boolean extractLibs)
11439                    throws PackageManagerException {
11440        // Give ourselves some initial paths; we'll come back for another
11441        // pass once we've determined ABI below.
11442        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11443
11444        // We would never need to extract libs for forward-locked and external packages,
11445        // since the container service will do it for us. We shouldn't attempt to
11446        // extract libs from system app when it was not updated.
11447        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11448                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11449            extractLibs = false;
11450        }
11451
11452        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11453        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11454
11455        NativeLibraryHelper.Handle handle = null;
11456        try {
11457            handle = NativeLibraryHelper.Handle.create(pkg);
11458            // TODO(multiArch): This can be null for apps that didn't go through the
11459            // usual installation process. We can calculate it again, like we
11460            // do during install time.
11461            //
11462            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11463            // unnecessary.
11464            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11465
11466            // Null out the abis so that they can be recalculated.
11467            pkg.applicationInfo.primaryCpuAbi = null;
11468            pkg.applicationInfo.secondaryCpuAbi = null;
11469            if (isMultiArch(pkg.applicationInfo)) {
11470                // Warn if we've set an abiOverride for multi-lib packages..
11471                // By definition, we need to copy both 32 and 64 bit libraries for
11472                // such packages.
11473                if (pkg.cpuAbiOverride != null
11474                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11475                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11476                }
11477
11478                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11479                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11480                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11481                    if (extractLibs) {
11482                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11483                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11484                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11485                                useIsaSpecificSubdirs);
11486                    } else {
11487                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11488                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11489                    }
11490                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11491                }
11492
11493                // Shared library native code should be in the APK zip aligned
11494                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11495                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11496                            "Shared library native lib extraction not supported");
11497                }
11498
11499                maybeThrowExceptionForMultiArchCopy(
11500                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11501
11502                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11503                    if (extractLibs) {
11504                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11505                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11506                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11507                                useIsaSpecificSubdirs);
11508                    } else {
11509                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11510                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11511                    }
11512                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11513                }
11514
11515                maybeThrowExceptionForMultiArchCopy(
11516                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11517
11518                if (abi64 >= 0) {
11519                    // Shared library native libs should be in the APK zip aligned
11520                    if (extractLibs && pkg.isLibrary()) {
11521                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11522                                "Shared library native lib extraction not supported");
11523                    }
11524                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11525                }
11526
11527                if (abi32 >= 0) {
11528                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11529                    if (abi64 >= 0) {
11530                        if (pkg.use32bitAbi) {
11531                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11532                            pkg.applicationInfo.primaryCpuAbi = abi;
11533                        } else {
11534                            pkg.applicationInfo.secondaryCpuAbi = abi;
11535                        }
11536                    } else {
11537                        pkg.applicationInfo.primaryCpuAbi = abi;
11538                    }
11539                }
11540            } else {
11541                String[] abiList = (cpuAbiOverride != null) ?
11542                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11543
11544                // Enable gross and lame hacks for apps that are built with old
11545                // SDK tools. We must scan their APKs for renderscript bitcode and
11546                // not launch them if it's present. Don't bother checking on devices
11547                // that don't have 64 bit support.
11548                boolean needsRenderScriptOverride = false;
11549                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11550                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11551                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11552                    needsRenderScriptOverride = true;
11553                }
11554
11555                final int copyRet;
11556                if (extractLibs) {
11557                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11558                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11559                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11560                } else {
11561                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11562                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11563                }
11564                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11565
11566                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11567                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11568                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11569                }
11570
11571                if (copyRet >= 0) {
11572                    // Shared libraries that have native libs must be multi-architecture
11573                    if (pkg.isLibrary()) {
11574                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11575                                "Shared library with native libs must be multiarch");
11576                    }
11577                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11578                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11579                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11580                } else if (needsRenderScriptOverride) {
11581                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11582                }
11583            }
11584        } catch (IOException ioe) {
11585            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11586        } finally {
11587            IoUtils.closeQuietly(handle);
11588        }
11589
11590        // Now that we've calculated the ABIs and determined if it's an internal app,
11591        // we will go ahead and populate the nativeLibraryPath.
11592        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11593    }
11594
11595    /**
11596     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11597     * i.e, so that all packages can be run inside a single process if required.
11598     *
11599     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11600     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11601     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11602     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11603     * updating a package that belongs to a shared user.
11604     *
11605     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11606     * adds unnecessary complexity.
11607     */
11608    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11609            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11610        List<String> changedAbiCodePath = null;
11611        String requiredInstructionSet = null;
11612        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11613            requiredInstructionSet = VMRuntime.getInstructionSet(
11614                     scannedPackage.applicationInfo.primaryCpuAbi);
11615        }
11616
11617        PackageSetting requirer = null;
11618        for (PackageSetting ps : packagesForUser) {
11619            // If packagesForUser contains scannedPackage, we skip it. This will happen
11620            // when scannedPackage is an update of an existing package. Without this check,
11621            // we will never be able to change the ABI of any package belonging to a shared
11622            // user, even if it's compatible with other packages.
11623            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11624                if (ps.primaryCpuAbiString == null) {
11625                    continue;
11626                }
11627
11628                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11629                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11630                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11631                    // this but there's not much we can do.
11632                    String errorMessage = "Instruction set mismatch, "
11633                            + ((requirer == null) ? "[caller]" : requirer)
11634                            + " requires " + requiredInstructionSet + " whereas " + ps
11635                            + " requires " + instructionSet;
11636                    Slog.w(TAG, errorMessage);
11637                }
11638
11639                if (requiredInstructionSet == null) {
11640                    requiredInstructionSet = instructionSet;
11641                    requirer = ps;
11642                }
11643            }
11644        }
11645
11646        if (requiredInstructionSet != null) {
11647            String adjustedAbi;
11648            if (requirer != null) {
11649                // requirer != null implies that either scannedPackage was null or that scannedPackage
11650                // did not require an ABI, in which case we have to adjust scannedPackage to match
11651                // the ABI of the set (which is the same as requirer's ABI)
11652                adjustedAbi = requirer.primaryCpuAbiString;
11653                if (scannedPackage != null) {
11654                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11655                }
11656            } else {
11657                // requirer == null implies that we're updating all ABIs in the set to
11658                // match scannedPackage.
11659                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11660            }
11661
11662            for (PackageSetting ps : packagesForUser) {
11663                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11664                    if (ps.primaryCpuAbiString != null) {
11665                        continue;
11666                    }
11667
11668                    ps.primaryCpuAbiString = adjustedAbi;
11669                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11670                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11671                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11672                        if (DEBUG_ABI_SELECTION) {
11673                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11674                                    + " (requirer="
11675                                    + (requirer != null ? requirer.pkg : "null")
11676                                    + ", scannedPackage="
11677                                    + (scannedPackage != null ? scannedPackage : "null")
11678                                    + ")");
11679                        }
11680                        if (changedAbiCodePath == null) {
11681                            changedAbiCodePath = new ArrayList<>();
11682                        }
11683                        changedAbiCodePath.add(ps.codePathString);
11684                    }
11685                }
11686            }
11687        }
11688        return changedAbiCodePath;
11689    }
11690
11691    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11692        synchronized (mPackages) {
11693            mResolverReplaced = true;
11694            // Set up information for custom user intent resolution activity.
11695            mResolveActivity.applicationInfo = pkg.applicationInfo;
11696            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11697            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11698            mResolveActivity.processName = pkg.applicationInfo.packageName;
11699            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11700            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11701                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11702            mResolveActivity.theme = 0;
11703            mResolveActivity.exported = true;
11704            mResolveActivity.enabled = true;
11705            mResolveInfo.activityInfo = mResolveActivity;
11706            mResolveInfo.priority = 0;
11707            mResolveInfo.preferredOrder = 0;
11708            mResolveInfo.match = 0;
11709            mResolveComponentName = mCustomResolverComponentName;
11710            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11711                    mResolveComponentName);
11712        }
11713    }
11714
11715    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11716        if (installerActivity == null) {
11717            if (DEBUG_INSTANT) {
11718                Slog.d(TAG, "Clear ephemeral installer activity");
11719            }
11720            mInstantAppInstallerActivity = null;
11721            return;
11722        }
11723
11724        if (DEBUG_INSTANT) {
11725            Slog.d(TAG, "Set ephemeral installer activity: "
11726                    + installerActivity.getComponentName());
11727        }
11728        // Set up information for ephemeral installer activity
11729        mInstantAppInstallerActivity = installerActivity;
11730        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11731                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11732        mInstantAppInstallerActivity.exported = true;
11733        mInstantAppInstallerActivity.enabled = true;
11734        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11735        mInstantAppInstallerInfo.priority = 1;
11736        mInstantAppInstallerInfo.preferredOrder = 1;
11737        mInstantAppInstallerInfo.isDefault = true;
11738        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11739                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11740    }
11741
11742    private static String calculateBundledApkRoot(final String codePathString) {
11743        final File codePath = new File(codePathString);
11744        final File codeRoot;
11745        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11746            codeRoot = Environment.getRootDirectory();
11747        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11748            codeRoot = Environment.getOemDirectory();
11749        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11750            codeRoot = Environment.getVendorDirectory();
11751        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
11752            codeRoot = Environment.getProductDirectory();
11753        } else {
11754            // Unrecognized code path; take its top real segment as the apk root:
11755            // e.g. /something/app/blah.apk => /something
11756            try {
11757                File f = codePath.getCanonicalFile();
11758                File parent = f.getParentFile();    // non-null because codePath is a file
11759                File tmp;
11760                while ((tmp = parent.getParentFile()) != null) {
11761                    f = parent;
11762                    parent = tmp;
11763                }
11764                codeRoot = f;
11765                Slog.w(TAG, "Unrecognized code path "
11766                        + codePath + " - using " + codeRoot);
11767            } catch (IOException e) {
11768                // Can't canonicalize the code path -- shenanigans?
11769                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11770                return Environment.getRootDirectory().getPath();
11771            }
11772        }
11773        return codeRoot.getPath();
11774    }
11775
11776    /**
11777     * Derive and set the location of native libraries for the given package,
11778     * which varies depending on where and how the package was installed.
11779     */
11780    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11781        final ApplicationInfo info = pkg.applicationInfo;
11782        final String codePath = pkg.codePath;
11783        final File codeFile = new File(codePath);
11784        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11785        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11786
11787        info.nativeLibraryRootDir = null;
11788        info.nativeLibraryRootRequiresIsa = false;
11789        info.nativeLibraryDir = null;
11790        info.secondaryNativeLibraryDir = null;
11791
11792        if (isApkFile(codeFile)) {
11793            // Monolithic install
11794            if (bundledApp) {
11795                // If "/system/lib64/apkname" exists, assume that is the per-package
11796                // native library directory to use; otherwise use "/system/lib/apkname".
11797                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11798                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11799                        getPrimaryInstructionSet(info));
11800
11801                // This is a bundled system app so choose the path based on the ABI.
11802                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11803                // is just the default path.
11804                final String apkName = deriveCodePathName(codePath);
11805                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11806                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11807                        apkName).getAbsolutePath();
11808
11809                if (info.secondaryCpuAbi != null) {
11810                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11811                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11812                            secondaryLibDir, apkName).getAbsolutePath();
11813                }
11814            } else if (asecApp) {
11815                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11816                        .getAbsolutePath();
11817            } else {
11818                final String apkName = deriveCodePathName(codePath);
11819                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11820                        .getAbsolutePath();
11821            }
11822
11823            info.nativeLibraryRootRequiresIsa = false;
11824            info.nativeLibraryDir = info.nativeLibraryRootDir;
11825        } else {
11826            // Cluster install
11827            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11828            info.nativeLibraryRootRequiresIsa = true;
11829
11830            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11831                    getPrimaryInstructionSet(info)).getAbsolutePath();
11832
11833            if (info.secondaryCpuAbi != null) {
11834                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11835                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11836            }
11837        }
11838    }
11839
11840    /**
11841     * Calculate the abis and roots for a bundled app. These can uniquely
11842     * be determined from the contents of the system partition, i.e whether
11843     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11844     * of this information, and instead assume that the system was built
11845     * sensibly.
11846     */
11847    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11848                                           PackageSetting pkgSetting) {
11849        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11850
11851        // If "/system/lib64/apkname" exists, assume that is the per-package
11852        // native library directory to use; otherwise use "/system/lib/apkname".
11853        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11854        setBundledAppAbi(pkg, apkRoot, apkName);
11855        // pkgSetting might be null during rescan following uninstall of updates
11856        // to a bundled app, so accommodate that possibility.  The settings in
11857        // that case will be established later from the parsed package.
11858        //
11859        // If the settings aren't null, sync them up with what we've just derived.
11860        // note that apkRoot isn't stored in the package settings.
11861        if (pkgSetting != null) {
11862            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11863            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11864        }
11865    }
11866
11867    /**
11868     * Deduces the ABI of a bundled app and sets the relevant fields on the
11869     * parsed pkg object.
11870     *
11871     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11872     *        under which system libraries are installed.
11873     * @param apkName the name of the installed package.
11874     */
11875    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11876        final File codeFile = new File(pkg.codePath);
11877
11878        final boolean has64BitLibs;
11879        final boolean has32BitLibs;
11880        if (isApkFile(codeFile)) {
11881            // Monolithic install
11882            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11883            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11884        } else {
11885            // Cluster install
11886            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11887            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11888                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11889                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11890                has64BitLibs = (new File(rootDir, isa)).exists();
11891            } else {
11892                has64BitLibs = false;
11893            }
11894            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11895                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11896                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11897                has32BitLibs = (new File(rootDir, isa)).exists();
11898            } else {
11899                has32BitLibs = false;
11900            }
11901        }
11902
11903        if (has64BitLibs && !has32BitLibs) {
11904            // The package has 64 bit libs, but not 32 bit libs. Its primary
11905            // ABI should be 64 bit. We can safely assume here that the bundled
11906            // native libraries correspond to the most preferred ABI in the list.
11907
11908            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11909            pkg.applicationInfo.secondaryCpuAbi = null;
11910        } else if (has32BitLibs && !has64BitLibs) {
11911            // The package has 32 bit libs but not 64 bit libs. Its primary
11912            // ABI should be 32 bit.
11913
11914            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11915            pkg.applicationInfo.secondaryCpuAbi = null;
11916        } else if (has32BitLibs && has64BitLibs) {
11917            // The application has both 64 and 32 bit bundled libraries. We check
11918            // here that the app declares multiArch support, and warn if it doesn't.
11919            //
11920            // We will be lenient here and record both ABIs. The primary will be the
11921            // ABI that's higher on the list, i.e, a device that's configured to prefer
11922            // 64 bit apps will see a 64 bit primary ABI,
11923
11924            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11925                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11926            }
11927
11928            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11929                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11930                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11931            } else {
11932                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11933                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11934            }
11935        } else {
11936            pkg.applicationInfo.primaryCpuAbi = null;
11937            pkg.applicationInfo.secondaryCpuAbi = null;
11938        }
11939    }
11940
11941    private void killApplication(String pkgName, int appId, String reason) {
11942        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11943    }
11944
11945    private void killApplication(String pkgName, int appId, int userId, String reason) {
11946        // Request the ActivityManager to kill the process(only for existing packages)
11947        // so that we do not end up in a confused state while the user is still using the older
11948        // version of the application while the new one gets installed.
11949        final long token = Binder.clearCallingIdentity();
11950        try {
11951            IActivityManager am = ActivityManager.getService();
11952            if (am != null) {
11953                try {
11954                    am.killApplication(pkgName, appId, userId, reason);
11955                } catch (RemoteException e) {
11956                }
11957            }
11958        } finally {
11959            Binder.restoreCallingIdentity(token);
11960        }
11961    }
11962
11963    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11964        // Remove the parent package setting
11965        PackageSetting ps = (PackageSetting) pkg.mExtras;
11966        if (ps != null) {
11967            removePackageLI(ps, chatty);
11968        }
11969        // Remove the child package setting
11970        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11971        for (int i = 0; i < childCount; i++) {
11972            PackageParser.Package childPkg = pkg.childPackages.get(i);
11973            ps = (PackageSetting) childPkg.mExtras;
11974            if (ps != null) {
11975                removePackageLI(ps, chatty);
11976            }
11977        }
11978    }
11979
11980    void removePackageLI(PackageSetting ps, boolean chatty) {
11981        if (DEBUG_INSTALL) {
11982            if (chatty)
11983                Log.d(TAG, "Removing package " + ps.name);
11984        }
11985
11986        // writer
11987        synchronized (mPackages) {
11988            mPackages.remove(ps.name);
11989            final PackageParser.Package pkg = ps.pkg;
11990            if (pkg != null) {
11991                cleanPackageDataStructuresLILPw(pkg, chatty);
11992            }
11993        }
11994    }
11995
11996    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11997        if (DEBUG_INSTALL) {
11998            if (chatty)
11999                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12000        }
12001
12002        // writer
12003        synchronized (mPackages) {
12004            // Remove the parent package
12005            mPackages.remove(pkg.applicationInfo.packageName);
12006            cleanPackageDataStructuresLILPw(pkg, chatty);
12007
12008            // Remove the child packages
12009            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12010            for (int i = 0; i < childCount; i++) {
12011                PackageParser.Package childPkg = pkg.childPackages.get(i);
12012                mPackages.remove(childPkg.applicationInfo.packageName);
12013                cleanPackageDataStructuresLILPw(childPkg, chatty);
12014            }
12015        }
12016    }
12017
12018    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12019        int N = pkg.providers.size();
12020        StringBuilder r = null;
12021        int i;
12022        for (i=0; i<N; i++) {
12023            PackageParser.Provider p = pkg.providers.get(i);
12024            mProviders.removeProvider(p);
12025            if (p.info.authority == null) {
12026
12027                /* There was another ContentProvider with this authority when
12028                 * this app was installed so this authority is null,
12029                 * Ignore it as we don't have to unregister the provider.
12030                 */
12031                continue;
12032            }
12033            String names[] = p.info.authority.split(";");
12034            for (int j = 0; j < names.length; j++) {
12035                if (mProvidersByAuthority.get(names[j]) == p) {
12036                    mProvidersByAuthority.remove(names[j]);
12037                    if (DEBUG_REMOVE) {
12038                        if (chatty)
12039                            Log.d(TAG, "Unregistered content provider: " + names[j]
12040                                    + ", className = " + p.info.name + ", isSyncable = "
12041                                    + p.info.isSyncable);
12042                    }
12043                }
12044            }
12045            if (DEBUG_REMOVE && chatty) {
12046                if (r == null) {
12047                    r = new StringBuilder(256);
12048                } else {
12049                    r.append(' ');
12050                }
12051                r.append(p.info.name);
12052            }
12053        }
12054        if (r != null) {
12055            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12056        }
12057
12058        N = pkg.services.size();
12059        r = null;
12060        for (i=0; i<N; i++) {
12061            PackageParser.Service s = pkg.services.get(i);
12062            mServices.removeService(s);
12063            if (chatty) {
12064                if (r == null) {
12065                    r = new StringBuilder(256);
12066                } else {
12067                    r.append(' ');
12068                }
12069                r.append(s.info.name);
12070            }
12071        }
12072        if (r != null) {
12073            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12074        }
12075
12076        N = pkg.receivers.size();
12077        r = null;
12078        for (i=0; i<N; i++) {
12079            PackageParser.Activity a = pkg.receivers.get(i);
12080            mReceivers.removeActivity(a, "receiver");
12081            if (DEBUG_REMOVE && chatty) {
12082                if (r == null) {
12083                    r = new StringBuilder(256);
12084                } else {
12085                    r.append(' ');
12086                }
12087                r.append(a.info.name);
12088            }
12089        }
12090        if (r != null) {
12091            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12092        }
12093
12094        N = pkg.activities.size();
12095        r = null;
12096        for (i=0; i<N; i++) {
12097            PackageParser.Activity a = pkg.activities.get(i);
12098            mActivities.removeActivity(a, "activity");
12099            if (DEBUG_REMOVE && chatty) {
12100                if (r == null) {
12101                    r = new StringBuilder(256);
12102                } else {
12103                    r.append(' ');
12104                }
12105                r.append(a.info.name);
12106            }
12107        }
12108        if (r != null) {
12109            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12110        }
12111
12112        mPermissionManager.removeAllPermissions(pkg, chatty);
12113
12114        N = pkg.instrumentation.size();
12115        r = null;
12116        for (i=0; i<N; i++) {
12117            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12118            mInstrumentation.remove(a.getComponentName());
12119            if (DEBUG_REMOVE && chatty) {
12120                if (r == null) {
12121                    r = new StringBuilder(256);
12122                } else {
12123                    r.append(' ');
12124                }
12125                r.append(a.info.name);
12126            }
12127        }
12128        if (r != null) {
12129            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12130        }
12131
12132        r = null;
12133        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12134            // Only system apps can hold shared libraries.
12135            if (pkg.libraryNames != null) {
12136                for (i = 0; i < pkg.libraryNames.size(); i++) {
12137                    String name = pkg.libraryNames.get(i);
12138                    if (removeSharedLibraryLPw(name, 0)) {
12139                        if (DEBUG_REMOVE && chatty) {
12140                            if (r == null) {
12141                                r = new StringBuilder(256);
12142                            } else {
12143                                r.append(' ');
12144                            }
12145                            r.append(name);
12146                        }
12147                    }
12148                }
12149            }
12150        }
12151
12152        r = null;
12153
12154        // Any package can hold static shared libraries.
12155        if (pkg.staticSharedLibName != null) {
12156            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12157                if (DEBUG_REMOVE && chatty) {
12158                    if (r == null) {
12159                        r = new StringBuilder(256);
12160                    } else {
12161                        r.append(' ');
12162                    }
12163                    r.append(pkg.staticSharedLibName);
12164                }
12165            }
12166        }
12167
12168        if (r != null) {
12169            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12170        }
12171    }
12172
12173
12174    final class ActivityIntentResolver
12175            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12176        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12177                boolean defaultOnly, int userId) {
12178            if (!sUserManager.exists(userId)) return null;
12179            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12180            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12181        }
12182
12183        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12184                int userId) {
12185            if (!sUserManager.exists(userId)) return null;
12186            mFlags = flags;
12187            return super.queryIntent(intent, resolvedType,
12188                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12189                    userId);
12190        }
12191
12192        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12193                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12194            if (!sUserManager.exists(userId)) return null;
12195            if (packageActivities == null) {
12196                return null;
12197            }
12198            mFlags = flags;
12199            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12200            final int N = packageActivities.size();
12201            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12202                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12203
12204            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12205            for (int i = 0; i < N; ++i) {
12206                intentFilters = packageActivities.get(i).intents;
12207                if (intentFilters != null && intentFilters.size() > 0) {
12208                    PackageParser.ActivityIntentInfo[] array =
12209                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12210                    intentFilters.toArray(array);
12211                    listCut.add(array);
12212                }
12213            }
12214            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12215        }
12216
12217        /**
12218         * Finds a privileged activity that matches the specified activity names.
12219         */
12220        private PackageParser.Activity findMatchingActivity(
12221                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12222            for (PackageParser.Activity sysActivity : activityList) {
12223                if (sysActivity.info.name.equals(activityInfo.name)) {
12224                    return sysActivity;
12225                }
12226                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12227                    return sysActivity;
12228                }
12229                if (sysActivity.info.targetActivity != null) {
12230                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12231                        return sysActivity;
12232                    }
12233                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12234                        return sysActivity;
12235                    }
12236                }
12237            }
12238            return null;
12239        }
12240
12241        public class IterGenerator<E> {
12242            public Iterator<E> generate(ActivityIntentInfo info) {
12243                return null;
12244            }
12245        }
12246
12247        public class ActionIterGenerator extends IterGenerator<String> {
12248            @Override
12249            public Iterator<String> generate(ActivityIntentInfo info) {
12250                return info.actionsIterator();
12251            }
12252        }
12253
12254        public class CategoriesIterGenerator extends IterGenerator<String> {
12255            @Override
12256            public Iterator<String> generate(ActivityIntentInfo info) {
12257                return info.categoriesIterator();
12258            }
12259        }
12260
12261        public class SchemesIterGenerator extends IterGenerator<String> {
12262            @Override
12263            public Iterator<String> generate(ActivityIntentInfo info) {
12264                return info.schemesIterator();
12265            }
12266        }
12267
12268        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12269            @Override
12270            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12271                return info.authoritiesIterator();
12272            }
12273        }
12274
12275        /**
12276         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12277         * MODIFIED. Do not pass in a list that should not be changed.
12278         */
12279        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12280                IterGenerator<T> generator, Iterator<T> searchIterator) {
12281            // loop through the set of actions; every one must be found in the intent filter
12282            while (searchIterator.hasNext()) {
12283                // we must have at least one filter in the list to consider a match
12284                if (intentList.size() == 0) {
12285                    break;
12286                }
12287
12288                final T searchAction = searchIterator.next();
12289
12290                // loop through the set of intent filters
12291                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12292                while (intentIter.hasNext()) {
12293                    final ActivityIntentInfo intentInfo = intentIter.next();
12294                    boolean selectionFound = false;
12295
12296                    // loop through the intent filter's selection criteria; at least one
12297                    // of them must match the searched criteria
12298                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12299                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12300                        final T intentSelection = intentSelectionIter.next();
12301                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12302                            selectionFound = true;
12303                            break;
12304                        }
12305                    }
12306
12307                    // the selection criteria wasn't found in this filter's set; this filter
12308                    // is not a potential match
12309                    if (!selectionFound) {
12310                        intentIter.remove();
12311                    }
12312                }
12313            }
12314        }
12315
12316        private boolean isProtectedAction(ActivityIntentInfo filter) {
12317            final Iterator<String> actionsIter = filter.actionsIterator();
12318            while (actionsIter != null && actionsIter.hasNext()) {
12319                final String filterAction = actionsIter.next();
12320                if (PROTECTED_ACTIONS.contains(filterAction)) {
12321                    return true;
12322                }
12323            }
12324            return false;
12325        }
12326
12327        /**
12328         * Adjusts the priority of the given intent filter according to policy.
12329         * <p>
12330         * <ul>
12331         * <li>The priority for non privileged applications is capped to '0'</li>
12332         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12333         * <li>The priority for unbundled updates to privileged applications is capped to the
12334         *      priority defined on the system partition</li>
12335         * </ul>
12336         * <p>
12337         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12338         * allowed to obtain any priority on any action.
12339         */
12340        private void adjustPriority(
12341                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12342            // nothing to do; priority is fine as-is
12343            if (intent.getPriority() <= 0) {
12344                return;
12345            }
12346
12347            final ActivityInfo activityInfo = intent.activity.info;
12348            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12349
12350            final boolean privilegedApp =
12351                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12352            if (!privilegedApp) {
12353                // non-privileged applications can never define a priority >0
12354                if (DEBUG_FILTERS) {
12355                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12356                            + " package: " + applicationInfo.packageName
12357                            + " activity: " + intent.activity.className
12358                            + " origPrio: " + intent.getPriority());
12359                }
12360                intent.setPriority(0);
12361                return;
12362            }
12363
12364            if (systemActivities == null) {
12365                // the system package is not disabled; we're parsing the system partition
12366                if (isProtectedAction(intent)) {
12367                    if (mDeferProtectedFilters) {
12368                        // We can't deal with these just yet. No component should ever obtain a
12369                        // >0 priority for a protected actions, with ONE exception -- the setup
12370                        // wizard. The setup wizard, however, cannot be known until we're able to
12371                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12372                        // until all intent filters have been processed. Chicken, meet egg.
12373                        // Let the filter temporarily have a high priority and rectify the
12374                        // priorities after all system packages have been scanned.
12375                        mProtectedFilters.add(intent);
12376                        if (DEBUG_FILTERS) {
12377                            Slog.i(TAG, "Protected action; save for later;"
12378                                    + " package: " + applicationInfo.packageName
12379                                    + " activity: " + intent.activity.className
12380                                    + " origPrio: " + intent.getPriority());
12381                        }
12382                        return;
12383                    } else {
12384                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12385                            Slog.i(TAG, "No setup wizard;"
12386                                + " All protected intents capped to priority 0");
12387                        }
12388                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12389                            if (DEBUG_FILTERS) {
12390                                Slog.i(TAG, "Found setup wizard;"
12391                                    + " allow priority " + intent.getPriority() + ";"
12392                                    + " package: " + intent.activity.info.packageName
12393                                    + " activity: " + intent.activity.className
12394                                    + " priority: " + intent.getPriority());
12395                            }
12396                            // setup wizard gets whatever it wants
12397                            return;
12398                        }
12399                        if (DEBUG_FILTERS) {
12400                            Slog.i(TAG, "Protected action; cap priority to 0;"
12401                                    + " package: " + intent.activity.info.packageName
12402                                    + " activity: " + intent.activity.className
12403                                    + " origPrio: " + intent.getPriority());
12404                        }
12405                        intent.setPriority(0);
12406                        return;
12407                    }
12408                }
12409                // privileged apps on the system image get whatever priority they request
12410                return;
12411            }
12412
12413            // privileged app unbundled update ... try to find the same activity
12414            final PackageParser.Activity foundActivity =
12415                    findMatchingActivity(systemActivities, activityInfo);
12416            if (foundActivity == null) {
12417                // this is a new activity; it cannot obtain >0 priority
12418                if (DEBUG_FILTERS) {
12419                    Slog.i(TAG, "New activity; cap priority to 0;"
12420                            + " package: " + applicationInfo.packageName
12421                            + " activity: " + intent.activity.className
12422                            + " origPrio: " + intent.getPriority());
12423                }
12424                intent.setPriority(0);
12425                return;
12426            }
12427
12428            // found activity, now check for filter equivalence
12429
12430            // a shallow copy is enough; we modify the list, not its contents
12431            final List<ActivityIntentInfo> intentListCopy =
12432                    new ArrayList<>(foundActivity.intents);
12433            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12434
12435            // find matching action subsets
12436            final Iterator<String> actionsIterator = intent.actionsIterator();
12437            if (actionsIterator != null) {
12438                getIntentListSubset(
12439                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12440                if (intentListCopy.size() == 0) {
12441                    // no more intents to match; we're not equivalent
12442                    if (DEBUG_FILTERS) {
12443                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12444                                + " package: " + applicationInfo.packageName
12445                                + " activity: " + intent.activity.className
12446                                + " origPrio: " + intent.getPriority());
12447                    }
12448                    intent.setPriority(0);
12449                    return;
12450                }
12451            }
12452
12453            // find matching category subsets
12454            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12455            if (categoriesIterator != null) {
12456                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12457                        categoriesIterator);
12458                if (intentListCopy.size() == 0) {
12459                    // no more intents to match; we're not equivalent
12460                    if (DEBUG_FILTERS) {
12461                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12462                                + " package: " + applicationInfo.packageName
12463                                + " activity: " + intent.activity.className
12464                                + " origPrio: " + intent.getPriority());
12465                    }
12466                    intent.setPriority(0);
12467                    return;
12468                }
12469            }
12470
12471            // find matching schemes subsets
12472            final Iterator<String> schemesIterator = intent.schemesIterator();
12473            if (schemesIterator != null) {
12474                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12475                        schemesIterator);
12476                if (intentListCopy.size() == 0) {
12477                    // no more intents to match; we're not equivalent
12478                    if (DEBUG_FILTERS) {
12479                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12480                                + " package: " + applicationInfo.packageName
12481                                + " activity: " + intent.activity.className
12482                                + " origPrio: " + intent.getPriority());
12483                    }
12484                    intent.setPriority(0);
12485                    return;
12486                }
12487            }
12488
12489            // find matching authorities subsets
12490            final Iterator<IntentFilter.AuthorityEntry>
12491                    authoritiesIterator = intent.authoritiesIterator();
12492            if (authoritiesIterator != null) {
12493                getIntentListSubset(intentListCopy,
12494                        new AuthoritiesIterGenerator(),
12495                        authoritiesIterator);
12496                if (intentListCopy.size() == 0) {
12497                    // no more intents to match; we're not equivalent
12498                    if (DEBUG_FILTERS) {
12499                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12500                                + " package: " + applicationInfo.packageName
12501                                + " activity: " + intent.activity.className
12502                                + " origPrio: " + intent.getPriority());
12503                    }
12504                    intent.setPriority(0);
12505                    return;
12506                }
12507            }
12508
12509            // we found matching filter(s); app gets the max priority of all intents
12510            int cappedPriority = 0;
12511            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12512                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12513            }
12514            if (intent.getPriority() > cappedPriority) {
12515                if (DEBUG_FILTERS) {
12516                    Slog.i(TAG, "Found matching filter(s);"
12517                            + " cap priority to " + cappedPriority + ";"
12518                            + " package: " + applicationInfo.packageName
12519                            + " activity: " + intent.activity.className
12520                            + " origPrio: " + intent.getPriority());
12521                }
12522                intent.setPriority(cappedPriority);
12523                return;
12524            }
12525            // all this for nothing; the requested priority was <= what was on the system
12526        }
12527
12528        public final void addActivity(PackageParser.Activity a, String type) {
12529            mActivities.put(a.getComponentName(), a);
12530            if (DEBUG_SHOW_INFO)
12531                Log.v(
12532                TAG, "  " + type + " " +
12533                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12534            if (DEBUG_SHOW_INFO)
12535                Log.v(TAG, "    Class=" + a.info.name);
12536            final int NI = a.intents.size();
12537            for (int j=0; j<NI; j++) {
12538                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12539                if ("activity".equals(type)) {
12540                    final PackageSetting ps =
12541                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12542                    final List<PackageParser.Activity> systemActivities =
12543                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12544                    adjustPriority(systemActivities, intent);
12545                }
12546                if (DEBUG_SHOW_INFO) {
12547                    Log.v(TAG, "    IntentFilter:");
12548                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12549                }
12550                if (!intent.debugCheck()) {
12551                    Log.w(TAG, "==> For Activity " + a.info.name);
12552                }
12553                addFilter(intent);
12554            }
12555        }
12556
12557        public final void removeActivity(PackageParser.Activity a, String type) {
12558            mActivities.remove(a.getComponentName());
12559            if (DEBUG_SHOW_INFO) {
12560                Log.v(TAG, "  " + type + " "
12561                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12562                                : a.info.name) + ":");
12563                Log.v(TAG, "    Class=" + a.info.name);
12564            }
12565            final int NI = a.intents.size();
12566            for (int j=0; j<NI; j++) {
12567                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12568                if (DEBUG_SHOW_INFO) {
12569                    Log.v(TAG, "    IntentFilter:");
12570                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12571                }
12572                removeFilter(intent);
12573            }
12574        }
12575
12576        @Override
12577        protected boolean allowFilterResult(
12578                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12579            ActivityInfo filterAi = filter.activity.info;
12580            for (int i=dest.size()-1; i>=0; i--) {
12581                ActivityInfo destAi = dest.get(i).activityInfo;
12582                if (destAi.name == filterAi.name
12583                        && destAi.packageName == filterAi.packageName) {
12584                    return false;
12585                }
12586            }
12587            return true;
12588        }
12589
12590        @Override
12591        protected ActivityIntentInfo[] newArray(int size) {
12592            return new ActivityIntentInfo[size];
12593        }
12594
12595        @Override
12596        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12597            if (!sUserManager.exists(userId)) return true;
12598            PackageParser.Package p = filter.activity.owner;
12599            if (p != null) {
12600                PackageSetting ps = (PackageSetting)p.mExtras;
12601                if (ps != null) {
12602                    // System apps are never considered stopped for purposes of
12603                    // filtering, because there may be no way for the user to
12604                    // actually re-launch them.
12605                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12606                            && ps.getStopped(userId);
12607                }
12608            }
12609            return false;
12610        }
12611
12612        @Override
12613        protected boolean isPackageForFilter(String packageName,
12614                PackageParser.ActivityIntentInfo info) {
12615            return packageName.equals(info.activity.owner.packageName);
12616        }
12617
12618        @Override
12619        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12620                int match, int userId) {
12621            if (!sUserManager.exists(userId)) return null;
12622            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12623                return null;
12624            }
12625            final PackageParser.Activity activity = info.activity;
12626            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12627            if (ps == null) {
12628                return null;
12629            }
12630            final PackageUserState userState = ps.readUserState(userId);
12631            ActivityInfo ai =
12632                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12633            if (ai == null) {
12634                return null;
12635            }
12636            final boolean matchExplicitlyVisibleOnly =
12637                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12638            final boolean matchVisibleToInstantApp =
12639                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12640            final boolean componentVisible =
12641                    matchVisibleToInstantApp
12642                    && info.isVisibleToInstantApp()
12643                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12644            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12645            // throw out filters that aren't visible to ephemeral apps
12646            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12647                return null;
12648            }
12649            // throw out instant app filters if we're not explicitly requesting them
12650            if (!matchInstantApp && userState.instantApp) {
12651                return null;
12652            }
12653            // throw out instant app filters if updates are available; will trigger
12654            // instant app resolution
12655            if (userState.instantApp && ps.isUpdateAvailable()) {
12656                return null;
12657            }
12658            final ResolveInfo res = new ResolveInfo();
12659            res.activityInfo = ai;
12660            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12661                res.filter = info;
12662            }
12663            if (info != null) {
12664                res.handleAllWebDataURI = info.handleAllWebDataURI();
12665            }
12666            res.priority = info.getPriority();
12667            res.preferredOrder = activity.owner.mPreferredOrder;
12668            //System.out.println("Result: " + res.activityInfo.className +
12669            //                   " = " + res.priority);
12670            res.match = match;
12671            res.isDefault = info.hasDefault;
12672            res.labelRes = info.labelRes;
12673            res.nonLocalizedLabel = info.nonLocalizedLabel;
12674            if (userNeedsBadging(userId)) {
12675                res.noResourceId = true;
12676            } else {
12677                res.icon = info.icon;
12678            }
12679            res.iconResourceId = info.icon;
12680            res.system = res.activityInfo.applicationInfo.isSystemApp();
12681            res.isInstantAppAvailable = userState.instantApp;
12682            return res;
12683        }
12684
12685        @Override
12686        protected void sortResults(List<ResolveInfo> results) {
12687            Collections.sort(results, mResolvePrioritySorter);
12688        }
12689
12690        @Override
12691        protected void dumpFilter(PrintWriter out, String prefix,
12692                PackageParser.ActivityIntentInfo filter) {
12693            out.print(prefix); out.print(
12694                    Integer.toHexString(System.identityHashCode(filter.activity)));
12695                    out.print(' ');
12696                    filter.activity.printComponentShortName(out);
12697                    out.print(" filter ");
12698                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12699        }
12700
12701        @Override
12702        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12703            return filter.activity;
12704        }
12705
12706        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12707            PackageParser.Activity activity = (PackageParser.Activity)label;
12708            out.print(prefix); out.print(
12709                    Integer.toHexString(System.identityHashCode(activity)));
12710                    out.print(' ');
12711                    activity.printComponentShortName(out);
12712            if (count > 1) {
12713                out.print(" ("); out.print(count); out.print(" filters)");
12714            }
12715            out.println();
12716        }
12717
12718        // Keys are String (activity class name), values are Activity.
12719        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12720                = new ArrayMap<ComponentName, PackageParser.Activity>();
12721        private int mFlags;
12722    }
12723
12724    private final class ServiceIntentResolver
12725            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12726        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12727                boolean defaultOnly, int userId) {
12728            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12729            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12730        }
12731
12732        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12733                int userId) {
12734            if (!sUserManager.exists(userId)) return null;
12735            mFlags = flags;
12736            return super.queryIntent(intent, resolvedType,
12737                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12738                    userId);
12739        }
12740
12741        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12742                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12743            if (!sUserManager.exists(userId)) return null;
12744            if (packageServices == null) {
12745                return null;
12746            }
12747            mFlags = flags;
12748            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12749            final int N = packageServices.size();
12750            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12751                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12752
12753            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12754            for (int i = 0; i < N; ++i) {
12755                intentFilters = packageServices.get(i).intents;
12756                if (intentFilters != null && intentFilters.size() > 0) {
12757                    PackageParser.ServiceIntentInfo[] array =
12758                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12759                    intentFilters.toArray(array);
12760                    listCut.add(array);
12761                }
12762            }
12763            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12764        }
12765
12766        public final void addService(PackageParser.Service s) {
12767            mServices.put(s.getComponentName(), s);
12768            if (DEBUG_SHOW_INFO) {
12769                Log.v(TAG, "  "
12770                        + (s.info.nonLocalizedLabel != null
12771                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12772                Log.v(TAG, "    Class=" + s.info.name);
12773            }
12774            final int NI = s.intents.size();
12775            int j;
12776            for (j=0; j<NI; j++) {
12777                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12778                if (DEBUG_SHOW_INFO) {
12779                    Log.v(TAG, "    IntentFilter:");
12780                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12781                }
12782                if (!intent.debugCheck()) {
12783                    Log.w(TAG, "==> For Service " + s.info.name);
12784                }
12785                addFilter(intent);
12786            }
12787        }
12788
12789        public final void removeService(PackageParser.Service s) {
12790            mServices.remove(s.getComponentName());
12791            if (DEBUG_SHOW_INFO) {
12792                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12793                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12794                Log.v(TAG, "    Class=" + s.info.name);
12795            }
12796            final int NI = s.intents.size();
12797            int j;
12798            for (j=0; j<NI; j++) {
12799                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12800                if (DEBUG_SHOW_INFO) {
12801                    Log.v(TAG, "    IntentFilter:");
12802                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12803                }
12804                removeFilter(intent);
12805            }
12806        }
12807
12808        @Override
12809        protected boolean allowFilterResult(
12810                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12811            ServiceInfo filterSi = filter.service.info;
12812            for (int i=dest.size()-1; i>=0; i--) {
12813                ServiceInfo destAi = dest.get(i).serviceInfo;
12814                if (destAi.name == filterSi.name
12815                        && destAi.packageName == filterSi.packageName) {
12816                    return false;
12817                }
12818            }
12819            return true;
12820        }
12821
12822        @Override
12823        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12824            return new PackageParser.ServiceIntentInfo[size];
12825        }
12826
12827        @Override
12828        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12829            if (!sUserManager.exists(userId)) return true;
12830            PackageParser.Package p = filter.service.owner;
12831            if (p != null) {
12832                PackageSetting ps = (PackageSetting)p.mExtras;
12833                if (ps != null) {
12834                    // System apps are never considered stopped for purposes of
12835                    // filtering, because there may be no way for the user to
12836                    // actually re-launch them.
12837                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12838                            && ps.getStopped(userId);
12839                }
12840            }
12841            return false;
12842        }
12843
12844        @Override
12845        protected boolean isPackageForFilter(String packageName,
12846                PackageParser.ServiceIntentInfo info) {
12847            return packageName.equals(info.service.owner.packageName);
12848        }
12849
12850        @Override
12851        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12852                int match, int userId) {
12853            if (!sUserManager.exists(userId)) return null;
12854            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12855            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12856                return null;
12857            }
12858            final PackageParser.Service service = info.service;
12859            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12860            if (ps == null) {
12861                return null;
12862            }
12863            final PackageUserState userState = ps.readUserState(userId);
12864            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12865                    userState, userId);
12866            if (si == null) {
12867                return null;
12868            }
12869            final boolean matchVisibleToInstantApp =
12870                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12871            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12872            // throw out filters that aren't visible to ephemeral apps
12873            if (matchVisibleToInstantApp
12874                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12875                return null;
12876            }
12877            // throw out ephemeral filters if we're not explicitly requesting them
12878            if (!isInstantApp && userState.instantApp) {
12879                return null;
12880            }
12881            // throw out instant app filters if updates are available; will trigger
12882            // instant app resolution
12883            if (userState.instantApp && ps.isUpdateAvailable()) {
12884                return null;
12885            }
12886            final ResolveInfo res = new ResolveInfo();
12887            res.serviceInfo = si;
12888            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12889                res.filter = filter;
12890            }
12891            res.priority = info.getPriority();
12892            res.preferredOrder = service.owner.mPreferredOrder;
12893            res.match = match;
12894            res.isDefault = info.hasDefault;
12895            res.labelRes = info.labelRes;
12896            res.nonLocalizedLabel = info.nonLocalizedLabel;
12897            res.icon = info.icon;
12898            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12899            return res;
12900        }
12901
12902        @Override
12903        protected void sortResults(List<ResolveInfo> results) {
12904            Collections.sort(results, mResolvePrioritySorter);
12905        }
12906
12907        @Override
12908        protected void dumpFilter(PrintWriter out, String prefix,
12909                PackageParser.ServiceIntentInfo filter) {
12910            out.print(prefix); out.print(
12911                    Integer.toHexString(System.identityHashCode(filter.service)));
12912                    out.print(' ');
12913                    filter.service.printComponentShortName(out);
12914                    out.print(" filter ");
12915                    out.print(Integer.toHexString(System.identityHashCode(filter)));
12916                    if (filter.service.info.permission != null) {
12917                        out.print(" permission "); out.println(filter.service.info.permission);
12918                    } else {
12919                        out.println();
12920                    }
12921        }
12922
12923        @Override
12924        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12925            return filter.service;
12926        }
12927
12928        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12929            PackageParser.Service service = (PackageParser.Service)label;
12930            out.print(prefix); out.print(
12931                    Integer.toHexString(System.identityHashCode(service)));
12932                    out.print(' ');
12933                    service.printComponentShortName(out);
12934            if (count > 1) {
12935                out.print(" ("); out.print(count); out.print(" filters)");
12936            }
12937            out.println();
12938        }
12939
12940//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12941//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12942//            final List<ResolveInfo> retList = Lists.newArrayList();
12943//            while (i.hasNext()) {
12944//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12945//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12946//                    retList.add(resolveInfo);
12947//                }
12948//            }
12949//            return retList;
12950//        }
12951
12952        // Keys are String (activity class name), values are Activity.
12953        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12954                = new ArrayMap<ComponentName, PackageParser.Service>();
12955        private int mFlags;
12956    }
12957
12958    private final class ProviderIntentResolver
12959            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12960        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12961                boolean defaultOnly, int userId) {
12962            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12963            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12964        }
12965
12966        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12967                int userId) {
12968            if (!sUserManager.exists(userId))
12969                return null;
12970            mFlags = flags;
12971            return super.queryIntent(intent, resolvedType,
12972                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12973                    userId);
12974        }
12975
12976        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12977                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12978            if (!sUserManager.exists(userId))
12979                return null;
12980            if (packageProviders == null) {
12981                return null;
12982            }
12983            mFlags = flags;
12984            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12985            final int N = packageProviders.size();
12986            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12987                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12988
12989            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12990            for (int i = 0; i < N; ++i) {
12991                intentFilters = packageProviders.get(i).intents;
12992                if (intentFilters != null && intentFilters.size() > 0) {
12993                    PackageParser.ProviderIntentInfo[] array =
12994                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12995                    intentFilters.toArray(array);
12996                    listCut.add(array);
12997                }
12998            }
12999            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13000        }
13001
13002        public final void addProvider(PackageParser.Provider p) {
13003            if (mProviders.containsKey(p.getComponentName())) {
13004                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13005                return;
13006            }
13007
13008            mProviders.put(p.getComponentName(), p);
13009            if (DEBUG_SHOW_INFO) {
13010                Log.v(TAG, "  "
13011                        + (p.info.nonLocalizedLabel != null
13012                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13013                Log.v(TAG, "    Class=" + p.info.name);
13014            }
13015            final int NI = p.intents.size();
13016            int j;
13017            for (j = 0; j < NI; j++) {
13018                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13019                if (DEBUG_SHOW_INFO) {
13020                    Log.v(TAG, "    IntentFilter:");
13021                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13022                }
13023                if (!intent.debugCheck()) {
13024                    Log.w(TAG, "==> For Provider " + p.info.name);
13025                }
13026                addFilter(intent);
13027            }
13028        }
13029
13030        public final void removeProvider(PackageParser.Provider p) {
13031            mProviders.remove(p.getComponentName());
13032            if (DEBUG_SHOW_INFO) {
13033                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13034                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13035                Log.v(TAG, "    Class=" + p.info.name);
13036            }
13037            final int NI = p.intents.size();
13038            int j;
13039            for (j = 0; j < NI; j++) {
13040                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13041                if (DEBUG_SHOW_INFO) {
13042                    Log.v(TAG, "    IntentFilter:");
13043                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13044                }
13045                removeFilter(intent);
13046            }
13047        }
13048
13049        @Override
13050        protected boolean allowFilterResult(
13051                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13052            ProviderInfo filterPi = filter.provider.info;
13053            for (int i = dest.size() - 1; i >= 0; i--) {
13054                ProviderInfo destPi = dest.get(i).providerInfo;
13055                if (destPi.name == filterPi.name
13056                        && destPi.packageName == filterPi.packageName) {
13057                    return false;
13058                }
13059            }
13060            return true;
13061        }
13062
13063        @Override
13064        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13065            return new PackageParser.ProviderIntentInfo[size];
13066        }
13067
13068        @Override
13069        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13070            if (!sUserManager.exists(userId))
13071                return true;
13072            PackageParser.Package p = filter.provider.owner;
13073            if (p != null) {
13074                PackageSetting ps = (PackageSetting) p.mExtras;
13075                if (ps != null) {
13076                    // System apps are never considered stopped for purposes of
13077                    // filtering, because there may be no way for the user to
13078                    // actually re-launch them.
13079                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13080                            && ps.getStopped(userId);
13081                }
13082            }
13083            return false;
13084        }
13085
13086        @Override
13087        protected boolean isPackageForFilter(String packageName,
13088                PackageParser.ProviderIntentInfo info) {
13089            return packageName.equals(info.provider.owner.packageName);
13090        }
13091
13092        @Override
13093        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13094                int match, int userId) {
13095            if (!sUserManager.exists(userId))
13096                return null;
13097            final PackageParser.ProviderIntentInfo info = filter;
13098            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13099                return null;
13100            }
13101            final PackageParser.Provider provider = info.provider;
13102            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13103            if (ps == null) {
13104                return null;
13105            }
13106            final PackageUserState userState = ps.readUserState(userId);
13107            final boolean matchVisibleToInstantApp =
13108                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13109            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13110            // throw out filters that aren't visible to instant applications
13111            if (matchVisibleToInstantApp
13112                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13113                return null;
13114            }
13115            // throw out instant application filters if we're not explicitly requesting them
13116            if (!isInstantApp && userState.instantApp) {
13117                return null;
13118            }
13119            // throw out instant application filters if updates are available; will trigger
13120            // instant application resolution
13121            if (userState.instantApp && ps.isUpdateAvailable()) {
13122                return null;
13123            }
13124            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13125                    userState, userId);
13126            if (pi == null) {
13127                return null;
13128            }
13129            final ResolveInfo res = new ResolveInfo();
13130            res.providerInfo = pi;
13131            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13132                res.filter = filter;
13133            }
13134            res.priority = info.getPriority();
13135            res.preferredOrder = provider.owner.mPreferredOrder;
13136            res.match = match;
13137            res.isDefault = info.hasDefault;
13138            res.labelRes = info.labelRes;
13139            res.nonLocalizedLabel = info.nonLocalizedLabel;
13140            res.icon = info.icon;
13141            res.system = res.providerInfo.applicationInfo.isSystemApp();
13142            return res;
13143        }
13144
13145        @Override
13146        protected void sortResults(List<ResolveInfo> results) {
13147            Collections.sort(results, mResolvePrioritySorter);
13148        }
13149
13150        @Override
13151        protected void dumpFilter(PrintWriter out, String prefix,
13152                PackageParser.ProviderIntentInfo filter) {
13153            out.print(prefix);
13154            out.print(
13155                    Integer.toHexString(System.identityHashCode(filter.provider)));
13156            out.print(' ');
13157            filter.provider.printComponentShortName(out);
13158            out.print(" filter ");
13159            out.println(Integer.toHexString(System.identityHashCode(filter)));
13160        }
13161
13162        @Override
13163        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13164            return filter.provider;
13165        }
13166
13167        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13168            PackageParser.Provider provider = (PackageParser.Provider)label;
13169            out.print(prefix); out.print(
13170                    Integer.toHexString(System.identityHashCode(provider)));
13171                    out.print(' ');
13172                    provider.printComponentShortName(out);
13173            if (count > 1) {
13174                out.print(" ("); out.print(count); out.print(" filters)");
13175            }
13176            out.println();
13177        }
13178
13179        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13180                = new ArrayMap<ComponentName, PackageParser.Provider>();
13181        private int mFlags;
13182    }
13183
13184    static final class InstantAppIntentResolver
13185            extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
13186            AuxiliaryResolveInfo.AuxiliaryFilter> {
13187        /**
13188         * The result that has the highest defined order. Ordering applies on a
13189         * per-package basis. Mapping is from package name to Pair of order and
13190         * EphemeralResolveInfo.
13191         * <p>
13192         * NOTE: This is implemented as a field variable for convenience and efficiency.
13193         * By having a field variable, we're able to track filter ordering as soon as
13194         * a non-zero order is defined. Otherwise, multiple loops across the result set
13195         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13196         * this needs to be contained entirely within {@link #filterResults}.
13197         */
13198        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13199
13200        @Override
13201        protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
13202            return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
13203        }
13204
13205        @Override
13206        protected boolean isPackageForFilter(String packageName,
13207                AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
13208            return true;
13209        }
13210
13211        @Override
13212        protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
13213                AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
13214            if (!sUserManager.exists(userId)) {
13215                return null;
13216            }
13217            final String packageName = responseObj.resolveInfo.getPackageName();
13218            final Integer order = responseObj.getOrder();
13219            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13220                    mOrderResult.get(packageName);
13221            // ordering is enabled and this item's order isn't high enough
13222            if (lastOrderResult != null && lastOrderResult.first >= order) {
13223                return null;
13224            }
13225            final InstantAppResolveInfo res = responseObj.resolveInfo;
13226            if (order > 0) {
13227                // non-zero order, enable ordering
13228                mOrderResult.put(packageName, new Pair<>(order, res));
13229            }
13230            return responseObj;
13231        }
13232
13233        @Override
13234        protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
13235            // only do work if ordering is enabled [most of the time it won't be]
13236            if (mOrderResult.size() == 0) {
13237                return;
13238            }
13239            int resultSize = results.size();
13240            for (int i = 0; i < resultSize; i++) {
13241                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13242                final String packageName = info.getPackageName();
13243                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13244                if (savedInfo == null) {
13245                    // package doesn't having ordering
13246                    continue;
13247                }
13248                if (savedInfo.second == info) {
13249                    // circled back to the highest ordered item; remove from order list
13250                    mOrderResult.remove(packageName);
13251                    if (mOrderResult.size() == 0) {
13252                        // no more ordered items
13253                        break;
13254                    }
13255                    continue;
13256                }
13257                // item has a worse order, remove it from the result list
13258                results.remove(i);
13259                resultSize--;
13260                i--;
13261            }
13262        }
13263    }
13264
13265    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13266            new Comparator<ResolveInfo>() {
13267        public int compare(ResolveInfo r1, ResolveInfo r2) {
13268            int v1 = r1.priority;
13269            int v2 = r2.priority;
13270            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13271            if (v1 != v2) {
13272                return (v1 > v2) ? -1 : 1;
13273            }
13274            v1 = r1.preferredOrder;
13275            v2 = r2.preferredOrder;
13276            if (v1 != v2) {
13277                return (v1 > v2) ? -1 : 1;
13278            }
13279            if (r1.isDefault != r2.isDefault) {
13280                return r1.isDefault ? -1 : 1;
13281            }
13282            v1 = r1.match;
13283            v2 = r2.match;
13284            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13285            if (v1 != v2) {
13286                return (v1 > v2) ? -1 : 1;
13287            }
13288            if (r1.system != r2.system) {
13289                return r1.system ? -1 : 1;
13290            }
13291            if (r1.activityInfo != null) {
13292                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13293            }
13294            if (r1.serviceInfo != null) {
13295                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13296            }
13297            if (r1.providerInfo != null) {
13298                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13299            }
13300            return 0;
13301        }
13302    };
13303
13304    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13305            new Comparator<ProviderInfo>() {
13306        public int compare(ProviderInfo p1, ProviderInfo p2) {
13307            final int v1 = p1.initOrder;
13308            final int v2 = p2.initOrder;
13309            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13310        }
13311    };
13312
13313    @Override
13314    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13315            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13316            final int[] userIds, int[] instantUserIds) {
13317        mHandler.post(new Runnable() {
13318            @Override
13319            public void run() {
13320                try {
13321                    final IActivityManager am = ActivityManager.getService();
13322                    if (am == null) return;
13323                    final int[] resolvedUserIds;
13324                    if (userIds == null) {
13325                        resolvedUserIds = am.getRunningUserIds();
13326                    } else {
13327                        resolvedUserIds = userIds;
13328                    }
13329                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13330                            resolvedUserIds, false);
13331                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13332                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13333                                instantUserIds, true);
13334                    }
13335                } catch (RemoteException ex) {
13336                }
13337            }
13338        });
13339    }
13340
13341    @Override
13342    public void notifyPackageAdded(String packageName) {
13343        final PackageListObserver[] observers;
13344        synchronized (mPackages) {
13345            if (mPackageListObservers.size() == 0) {
13346                return;
13347            }
13348            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13349        }
13350        for (int i = observers.length - 1; i >= 0; --i) {
13351            observers[i].onPackageAdded(packageName);
13352        }
13353    }
13354
13355    @Override
13356    public void notifyPackageRemoved(String packageName) {
13357        final PackageListObserver[] observers;
13358        synchronized (mPackages) {
13359            if (mPackageListObservers.size() == 0) {
13360                return;
13361            }
13362            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13363        }
13364        for (int i = observers.length - 1; i >= 0; --i) {
13365            observers[i].onPackageRemoved(packageName);
13366        }
13367    }
13368
13369    /**
13370     * Sends a broadcast for the given action.
13371     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13372     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13373     * the system and applications allowed to see instant applications to receive package
13374     * lifecycle events for instant applications.
13375     */
13376    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13377            int flags, String targetPkg, IIntentReceiver finishedReceiver,
13378            int[] userIds, boolean isInstantApp)
13379                    throws RemoteException {
13380        for (int id : userIds) {
13381            final Intent intent = new Intent(action,
13382                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13383            final String[] requiredPermissions =
13384                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13385            if (extras != null) {
13386                intent.putExtras(extras);
13387            }
13388            if (targetPkg != null) {
13389                intent.setPackage(targetPkg);
13390            }
13391            // Modify the UID when posting to other users
13392            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13393            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13394                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13395                intent.putExtra(Intent.EXTRA_UID, uid);
13396            }
13397            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13398            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13399            if (DEBUG_BROADCASTS) {
13400                RuntimeException here = new RuntimeException("here");
13401                here.fillInStackTrace();
13402                Slog.d(TAG, "Sending to user " + id + ": "
13403                        + intent.toShortString(false, true, false, false)
13404                        + " " + intent.getExtras(), here);
13405            }
13406            am.broadcastIntent(null, intent, null, finishedReceiver,
13407                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13408                    null, finishedReceiver != null, false, id);
13409        }
13410    }
13411
13412    /**
13413     * Check if the external storage media is available. This is true if there
13414     * is a mounted external storage medium or if the external storage is
13415     * emulated.
13416     */
13417    private boolean isExternalMediaAvailable() {
13418        return mMediaMounted || Environment.isExternalStorageEmulated();
13419    }
13420
13421    @Override
13422    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13423        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13424            return null;
13425        }
13426        if (!isExternalMediaAvailable()) {
13427                // If the external storage is no longer mounted at this point,
13428                // the caller may not have been able to delete all of this
13429                // packages files and can not delete any more.  Bail.
13430            return null;
13431        }
13432        synchronized (mPackages) {
13433            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13434            if (lastPackage != null) {
13435                pkgs.remove(lastPackage);
13436            }
13437            if (pkgs.size() > 0) {
13438                return pkgs.get(0);
13439            }
13440        }
13441        return null;
13442    }
13443
13444    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13445        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13446                userId, andCode ? 1 : 0, packageName);
13447        if (mSystemReady) {
13448            msg.sendToTarget();
13449        } else {
13450            if (mPostSystemReadyMessages == null) {
13451                mPostSystemReadyMessages = new ArrayList<>();
13452            }
13453            mPostSystemReadyMessages.add(msg);
13454        }
13455    }
13456
13457    void startCleaningPackages() {
13458        // reader
13459        if (!isExternalMediaAvailable()) {
13460            return;
13461        }
13462        synchronized (mPackages) {
13463            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13464                return;
13465            }
13466        }
13467        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13468        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13469        IActivityManager am = ActivityManager.getService();
13470        if (am != null) {
13471            int dcsUid = -1;
13472            synchronized (mPackages) {
13473                if (!mDefaultContainerWhitelisted) {
13474                    mDefaultContainerWhitelisted = true;
13475                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13476                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13477                }
13478            }
13479            try {
13480                if (dcsUid > 0) {
13481                    am.backgroundWhitelistUid(dcsUid);
13482                }
13483                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13484                        UserHandle.USER_SYSTEM);
13485            } catch (RemoteException e) {
13486            }
13487        }
13488    }
13489
13490    /**
13491     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13492     * it is acting on behalf on an enterprise or the user).
13493     *
13494     * Note that the ordering of the conditionals in this method is important. The checks we perform
13495     * are as follows, in this order:
13496     *
13497     * 1) If the install is being performed by a system app, we can trust the app to have set the
13498     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13499     *    what it is.
13500     * 2) If the install is being performed by a device or profile owner app, the install reason
13501     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13502     *    set the install reason correctly. If the app targets an older SDK version where install
13503     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13504     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13505     * 3) In all other cases, the install is being performed by a regular app that is neither part
13506     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13507     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13508     *    set to enterprise policy and if so, change it to unknown instead.
13509     */
13510    private int fixUpInstallReason(String installerPackageName, int installerUid,
13511            int installReason) {
13512        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13513                == PERMISSION_GRANTED) {
13514            // If the install is being performed by a system app, we trust that app to have set the
13515            // install reason correctly.
13516            return installReason;
13517        }
13518
13519        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13520            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13521        if (dpm != null) {
13522            ComponentName owner = null;
13523            try {
13524                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13525                if (owner == null) {
13526                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13527                }
13528            } catch (RemoteException e) {
13529            }
13530            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13531                // If the install is being performed by a device or profile owner, the install
13532                // reason should be enterprise policy.
13533                return PackageManager.INSTALL_REASON_POLICY;
13534            }
13535        }
13536
13537        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13538            // If the install is being performed by a regular app (i.e. neither system app nor
13539            // device or profile owner), we have no reason to believe that the app is acting on
13540            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13541            // change it to unknown instead.
13542            return PackageManager.INSTALL_REASON_UNKNOWN;
13543        }
13544
13545        // If the install is being performed by a regular app and the install reason was set to any
13546        // value but enterprise policy, leave the install reason unchanged.
13547        return installReason;
13548    }
13549
13550    void installStage(String packageName, File stagedDir,
13551            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13552            String installerPackageName, int installerUid, UserHandle user,
13553            PackageParser.SigningDetails signingDetails) {
13554        if (DEBUG_INSTANT) {
13555            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13556                Slog.d(TAG, "Ephemeral install of " + packageName);
13557            }
13558        }
13559        final VerificationInfo verificationInfo = new VerificationInfo(
13560                sessionParams.originatingUri, sessionParams.referrerUri,
13561                sessionParams.originatingUid, installerUid);
13562
13563        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13564
13565        final Message msg = mHandler.obtainMessage(INIT_COPY);
13566        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13567                sessionParams.installReason);
13568        final InstallParams params = new InstallParams(origin, null, observer,
13569                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13570                verificationInfo, user, sessionParams.abiOverride,
13571                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13572        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13573        msg.obj = params;
13574
13575        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13576                System.identityHashCode(msg.obj));
13577        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13578                System.identityHashCode(msg.obj));
13579
13580        mHandler.sendMessage(msg);
13581    }
13582
13583    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13584            int userId) {
13585        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13586        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13587        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13588        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13589        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13590                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13591
13592        // Send a session commit broadcast
13593        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13594        info.installReason = pkgSetting.getInstallReason(userId);
13595        info.appPackageName = packageName;
13596        sendSessionCommitBroadcast(info, userId);
13597    }
13598
13599    @Override
13600    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13601            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13602        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13603            return;
13604        }
13605        Bundle extras = new Bundle(1);
13606        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13607        final int uid = UserHandle.getUid(
13608                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13609        extras.putInt(Intent.EXTRA_UID, uid);
13610
13611        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13612                packageName, extras, 0, null, null, userIds, instantUserIds);
13613        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13614            mHandler.post(() -> {
13615                        for (int userId : userIds) {
13616                            sendBootCompletedBroadcastToSystemApp(
13617                                    packageName, includeStopped, userId);
13618                        }
13619                    }
13620            );
13621        }
13622    }
13623
13624    /**
13625     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13626     * automatically without needing an explicit launch.
13627     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13628     */
13629    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13630            int userId) {
13631        // If user is not running, the app didn't miss any broadcast
13632        if (!mUserManagerInternal.isUserRunning(userId)) {
13633            return;
13634        }
13635        final IActivityManager am = ActivityManager.getService();
13636        try {
13637            // Deliver LOCKED_BOOT_COMPLETED first
13638            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13639                    .setPackage(packageName);
13640            if (includeStopped) {
13641                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13642            }
13643            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13644            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13645                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13646
13647            // Deliver BOOT_COMPLETED only if user is unlocked
13648            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13649                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13650                if (includeStopped) {
13651                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13652                }
13653                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13654                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13655            }
13656        } catch (RemoteException e) {
13657            throw e.rethrowFromSystemServer();
13658        }
13659    }
13660
13661    @Override
13662    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13663            int userId) {
13664        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13665        PackageSetting pkgSetting;
13666        final int callingUid = Binder.getCallingUid();
13667        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13668                true /* requireFullPermission */, true /* checkShell */,
13669                "setApplicationHiddenSetting for user " + userId);
13670
13671        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13672            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13673            return false;
13674        }
13675
13676        long callingId = Binder.clearCallingIdentity();
13677        try {
13678            boolean sendAdded = false;
13679            boolean sendRemoved = false;
13680            // writer
13681            synchronized (mPackages) {
13682                pkgSetting = mSettings.mPackages.get(packageName);
13683                if (pkgSetting == null) {
13684                    return false;
13685                }
13686                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13687                    return false;
13688                }
13689                // Do not allow "android" is being disabled
13690                if ("android".equals(packageName)) {
13691                    Slog.w(TAG, "Cannot hide package: android");
13692                    return false;
13693                }
13694                // Cannot hide static shared libs as they are considered
13695                // a part of the using app (emulating static linking). Also
13696                // static libs are installed always on internal storage.
13697                PackageParser.Package pkg = mPackages.get(packageName);
13698                if (pkg != null && pkg.staticSharedLibName != null) {
13699                    Slog.w(TAG, "Cannot hide package: " + packageName
13700                            + " providing static shared library: "
13701                            + pkg.staticSharedLibName);
13702                    return false;
13703                }
13704                // Only allow protected packages to hide themselves.
13705                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13706                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13707                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13708                    return false;
13709                }
13710
13711                if (pkgSetting.getHidden(userId) != hidden) {
13712                    pkgSetting.setHidden(hidden, userId);
13713                    mSettings.writePackageRestrictionsLPr(userId);
13714                    if (hidden) {
13715                        sendRemoved = true;
13716                    } else {
13717                        sendAdded = true;
13718                    }
13719                }
13720            }
13721            if (sendAdded) {
13722                sendPackageAddedForUser(packageName, pkgSetting, userId);
13723                return true;
13724            }
13725            if (sendRemoved) {
13726                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13727                        "hiding pkg");
13728                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13729                return true;
13730            }
13731        } finally {
13732            Binder.restoreCallingIdentity(callingId);
13733        }
13734        return false;
13735    }
13736
13737    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13738            int userId) {
13739        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13740        info.removedPackage = packageName;
13741        info.installerPackageName = pkgSetting.installerPackageName;
13742        info.removedUsers = new int[] {userId};
13743        info.broadcastUsers = new int[] {userId};
13744        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13745        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13746    }
13747
13748    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13749        if (pkgList.length > 0) {
13750            Bundle extras = new Bundle(1);
13751            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13752
13753            sendPackageBroadcast(
13754                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13755                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13756                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13757                    new int[] {userId}, null);
13758        }
13759    }
13760
13761    /**
13762     * Returns true if application is not found or there was an error. Otherwise it returns
13763     * the hidden state of the package for the given user.
13764     */
13765    @Override
13766    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13767        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13768        final int callingUid = Binder.getCallingUid();
13769        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13770                true /* requireFullPermission */, false /* checkShell */,
13771                "getApplicationHidden for user " + userId);
13772        PackageSetting ps;
13773        long callingId = Binder.clearCallingIdentity();
13774        try {
13775            // writer
13776            synchronized (mPackages) {
13777                ps = mSettings.mPackages.get(packageName);
13778                if (ps == null) {
13779                    return true;
13780                }
13781                if (filterAppAccessLPr(ps, callingUid, userId)) {
13782                    return true;
13783                }
13784                return ps.getHidden(userId);
13785            }
13786        } finally {
13787            Binder.restoreCallingIdentity(callingId);
13788        }
13789    }
13790
13791    /**
13792     * @hide
13793     */
13794    @Override
13795    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13796            int installReason) {
13797        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13798                null);
13799        PackageSetting pkgSetting;
13800        final int callingUid = Binder.getCallingUid();
13801        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13802                true /* requireFullPermission */, true /* checkShell */,
13803                "installExistingPackage for user " + userId);
13804        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13805            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13806        }
13807
13808        long callingId = Binder.clearCallingIdentity();
13809        try {
13810            boolean installed = false;
13811            final boolean instantApp =
13812                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13813            final boolean fullApp =
13814                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13815
13816            // writer
13817            synchronized (mPackages) {
13818                pkgSetting = mSettings.mPackages.get(packageName);
13819                if (pkgSetting == null) {
13820                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13821                }
13822                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13823                    // only allow the existing package to be used if it's installed as a full
13824                    // application for at least one user
13825                    boolean installAllowed = false;
13826                    for (int checkUserId : sUserManager.getUserIds()) {
13827                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13828                        if (installAllowed) {
13829                            break;
13830                        }
13831                    }
13832                    if (!installAllowed) {
13833                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13834                    }
13835                }
13836                if (!pkgSetting.getInstalled(userId)) {
13837                    pkgSetting.setInstalled(true, userId);
13838                    pkgSetting.setHidden(false, userId);
13839                    pkgSetting.setInstallReason(installReason, userId);
13840                    mSettings.writePackageRestrictionsLPr(userId);
13841                    mSettings.writeKernelMappingLPr(pkgSetting);
13842                    installed = true;
13843                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13844                    // upgrade app from instant to full; we don't allow app downgrade
13845                    installed = true;
13846                }
13847                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13848            }
13849
13850            if (installed) {
13851                if (pkgSetting.pkg != null) {
13852                    synchronized (mInstallLock) {
13853                        // We don't need to freeze for a brand new install
13854                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13855                    }
13856                }
13857                sendPackageAddedForUser(packageName, pkgSetting, userId);
13858                synchronized (mPackages) {
13859                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13860                }
13861            }
13862        } finally {
13863            Binder.restoreCallingIdentity(callingId);
13864        }
13865
13866        return PackageManager.INSTALL_SUCCEEDED;
13867    }
13868
13869    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13870            boolean instantApp, boolean fullApp) {
13871        // no state specified; do nothing
13872        if (!instantApp && !fullApp) {
13873            return;
13874        }
13875        if (userId != UserHandle.USER_ALL) {
13876            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13877                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13878            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13879                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13880            }
13881        } else {
13882            for (int currentUserId : sUserManager.getUserIds()) {
13883                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13884                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13885                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13886                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13887                }
13888            }
13889        }
13890    }
13891
13892    boolean isUserRestricted(int userId, String restrictionKey) {
13893        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13894        if (restrictions.getBoolean(restrictionKey, false)) {
13895            Log.w(TAG, "User is restricted: " + restrictionKey);
13896            return true;
13897        }
13898        return false;
13899    }
13900
13901    @Override
13902    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13903            int userId) {
13904        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13905        final int callingUid = Binder.getCallingUid();
13906        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13907                true /* requireFullPermission */, true /* checkShell */,
13908                "setPackagesSuspended for user " + userId);
13909
13910        if (ArrayUtils.isEmpty(packageNames)) {
13911            return packageNames;
13912        }
13913
13914        // List of package names for whom the suspended state has changed.
13915        List<String> changedPackages = new ArrayList<>(packageNames.length);
13916        // List of package names for whom the suspended state is not set as requested in this
13917        // method.
13918        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13919        long callingId = Binder.clearCallingIdentity();
13920        try {
13921            for (int i = 0; i < packageNames.length; i++) {
13922                String packageName = packageNames[i];
13923                boolean changed = false;
13924                final int appId;
13925                synchronized (mPackages) {
13926                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13927                    if (pkgSetting == null
13928                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13929                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13930                                + "\". Skipping suspending/un-suspending.");
13931                        unactionedPackages.add(packageName);
13932                        continue;
13933                    }
13934                    appId = pkgSetting.appId;
13935                    if (pkgSetting.getSuspended(userId) != suspended) {
13936                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13937                            unactionedPackages.add(packageName);
13938                            continue;
13939                        }
13940                        pkgSetting.setSuspended(suspended, userId);
13941                        mSettings.writePackageRestrictionsLPr(userId);
13942                        changed = true;
13943                        changedPackages.add(packageName);
13944                    }
13945                }
13946
13947                if (changed && suspended) {
13948                    killApplication(packageName, UserHandle.getUid(userId, appId),
13949                            "suspending package");
13950                }
13951            }
13952        } finally {
13953            Binder.restoreCallingIdentity(callingId);
13954        }
13955
13956        if (!changedPackages.isEmpty()) {
13957            sendPackagesSuspendedForUser(changedPackages.toArray(
13958                    new String[changedPackages.size()]), userId, suspended);
13959        }
13960
13961        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13962    }
13963
13964    @Override
13965    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13966        final int callingUid = Binder.getCallingUid();
13967        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13968                true /* requireFullPermission */, false /* checkShell */,
13969                "isPackageSuspendedForUser for user " + userId);
13970        synchronized (mPackages) {
13971            final PackageSetting ps = mSettings.mPackages.get(packageName);
13972            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13973                throw new IllegalArgumentException("Unknown target package: " + packageName);
13974            }
13975            return ps.getSuspended(userId);
13976        }
13977    }
13978
13979    @GuardedBy("mPackages")
13980    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13981        if (isPackageDeviceAdmin(packageName, userId)) {
13982            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13983                    + "\": has an active device admin");
13984            return false;
13985        }
13986
13987        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13988        if (packageName.equals(activeLauncherPackageName)) {
13989            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13990                    + "\": contains the active launcher");
13991            return false;
13992        }
13993
13994        if (packageName.equals(mRequiredInstallerPackage)) {
13995            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13996                    + "\": required for package installation");
13997            return false;
13998        }
13999
14000        if (packageName.equals(mRequiredUninstallerPackage)) {
14001            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14002                    + "\": required for package uninstallation");
14003            return false;
14004        }
14005
14006        if (packageName.equals(mRequiredVerifierPackage)) {
14007            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14008                    + "\": required for package verification");
14009            return false;
14010        }
14011
14012        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14013            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14014                    + "\": is the default dialer");
14015            return false;
14016        }
14017
14018        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14019            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14020                    + "\": protected package");
14021            return false;
14022        }
14023
14024        // Cannot suspend static shared libs as they are considered
14025        // a part of the using app (emulating static linking). Also
14026        // static libs are installed always on internal storage.
14027        PackageParser.Package pkg = mPackages.get(packageName);
14028        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14029            Slog.w(TAG, "Cannot suspend package: " + packageName
14030                    + " providing static shared library: "
14031                    + pkg.staticSharedLibName);
14032            return false;
14033        }
14034
14035        return true;
14036    }
14037
14038    private String getActiveLauncherPackageName(int userId) {
14039        Intent intent = new Intent(Intent.ACTION_MAIN);
14040        intent.addCategory(Intent.CATEGORY_HOME);
14041        ResolveInfo resolveInfo = resolveIntent(
14042                intent,
14043                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14044                PackageManager.MATCH_DEFAULT_ONLY,
14045                userId);
14046
14047        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14048    }
14049
14050    private String getDefaultDialerPackageName(int userId) {
14051        synchronized (mPackages) {
14052            return mSettings.getDefaultDialerPackageNameLPw(userId);
14053        }
14054    }
14055
14056    @Override
14057    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14058        mContext.enforceCallingOrSelfPermission(
14059                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14060                "Only package verification agents can verify applications");
14061
14062        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14063        final PackageVerificationResponse response = new PackageVerificationResponse(
14064                verificationCode, Binder.getCallingUid());
14065        msg.arg1 = id;
14066        msg.obj = response;
14067        mHandler.sendMessage(msg);
14068    }
14069
14070    @Override
14071    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14072            long millisecondsToDelay) {
14073        mContext.enforceCallingOrSelfPermission(
14074                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14075                "Only package verification agents can extend verification timeouts");
14076
14077        final PackageVerificationState state = mPendingVerification.get(id);
14078        final PackageVerificationResponse response = new PackageVerificationResponse(
14079                verificationCodeAtTimeout, Binder.getCallingUid());
14080
14081        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14082            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14083        }
14084        if (millisecondsToDelay < 0) {
14085            millisecondsToDelay = 0;
14086        }
14087        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14088                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14089            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14090        }
14091
14092        if ((state != null) && !state.timeoutExtended()) {
14093            state.extendTimeout();
14094
14095            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14096            msg.arg1 = id;
14097            msg.obj = response;
14098            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14099        }
14100    }
14101
14102    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14103            int verificationCode, UserHandle user) {
14104        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14105        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14106        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14107        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14108        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14109
14110        mContext.sendBroadcastAsUser(intent, user,
14111                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14112    }
14113
14114    private ComponentName matchComponentForVerifier(String packageName,
14115            List<ResolveInfo> receivers) {
14116        ActivityInfo targetReceiver = null;
14117
14118        final int NR = receivers.size();
14119        for (int i = 0; i < NR; i++) {
14120            final ResolveInfo info = receivers.get(i);
14121            if (info.activityInfo == null) {
14122                continue;
14123            }
14124
14125            if (packageName.equals(info.activityInfo.packageName)) {
14126                targetReceiver = info.activityInfo;
14127                break;
14128            }
14129        }
14130
14131        if (targetReceiver == null) {
14132            return null;
14133        }
14134
14135        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14136    }
14137
14138    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14139            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14140        if (pkgInfo.verifiers.length == 0) {
14141            return null;
14142        }
14143
14144        final int N = pkgInfo.verifiers.length;
14145        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14146        for (int i = 0; i < N; i++) {
14147            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14148
14149            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14150                    receivers);
14151            if (comp == null) {
14152                continue;
14153            }
14154
14155            final int verifierUid = getUidForVerifier(verifierInfo);
14156            if (verifierUid == -1) {
14157                continue;
14158            }
14159
14160            if (DEBUG_VERIFY) {
14161                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14162                        + " with the correct signature");
14163            }
14164            sufficientVerifiers.add(comp);
14165            verificationState.addSufficientVerifier(verifierUid);
14166        }
14167
14168        return sufficientVerifiers;
14169    }
14170
14171    private int getUidForVerifier(VerifierInfo verifierInfo) {
14172        synchronized (mPackages) {
14173            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14174            if (pkg == null) {
14175                return -1;
14176            } else if (pkg.mSigningDetails.signatures.length != 1) {
14177                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14178                        + " has more than one signature; ignoring");
14179                return -1;
14180            }
14181
14182            /*
14183             * If the public key of the package's signature does not match
14184             * our expected public key, then this is a different package and
14185             * we should skip.
14186             */
14187
14188            final byte[] expectedPublicKey;
14189            try {
14190                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14191                final PublicKey publicKey = verifierSig.getPublicKey();
14192                expectedPublicKey = publicKey.getEncoded();
14193            } catch (CertificateException e) {
14194                return -1;
14195            }
14196
14197            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14198
14199            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14200                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14201                        + " does not have the expected public key; ignoring");
14202                return -1;
14203            }
14204
14205            return pkg.applicationInfo.uid;
14206        }
14207    }
14208
14209    @Override
14210    public void finishPackageInstall(int token, boolean didLaunch) {
14211        enforceSystemOrRoot("Only the system is allowed to finish installs");
14212
14213        if (DEBUG_INSTALL) {
14214            Slog.v(TAG, "BM finishing package install for " + token);
14215        }
14216        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14217
14218        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14219        mHandler.sendMessage(msg);
14220    }
14221
14222    /**
14223     * Get the verification agent timeout.  Used for both the APK verifier and the
14224     * intent filter verifier.
14225     *
14226     * @return verification timeout in milliseconds
14227     */
14228    private long getVerificationTimeout() {
14229        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14230                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14231                DEFAULT_VERIFICATION_TIMEOUT);
14232    }
14233
14234    /**
14235     * Get the default verification agent response code.
14236     *
14237     * @return default verification response code
14238     */
14239    private int getDefaultVerificationResponse(UserHandle user) {
14240        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14241            return PackageManager.VERIFICATION_REJECT;
14242        }
14243        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14244                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14245                DEFAULT_VERIFICATION_RESPONSE);
14246    }
14247
14248    /**
14249     * Check whether or not package verification has been enabled.
14250     *
14251     * @return true if verification should be performed
14252     */
14253    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14254        if (!DEFAULT_VERIFY_ENABLE) {
14255            return false;
14256        }
14257
14258        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14259
14260        // Check if installing from ADB
14261        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14262            // Do not run verification in a test harness environment
14263            if (ActivityManager.isRunningInTestHarness()) {
14264                return false;
14265            }
14266            if (ensureVerifyAppsEnabled) {
14267                return true;
14268            }
14269            // Check if the developer does not want package verification for ADB installs
14270            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14271                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14272                return false;
14273            }
14274        } else {
14275            // only when not installed from ADB, skip verification for instant apps when
14276            // the installer and verifier are the same.
14277            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14278                if (mInstantAppInstallerActivity != null
14279                        && mInstantAppInstallerActivity.packageName.equals(
14280                                mRequiredVerifierPackage)) {
14281                    try {
14282                        mContext.getSystemService(AppOpsManager.class)
14283                                .checkPackage(installerUid, mRequiredVerifierPackage);
14284                        if (DEBUG_VERIFY) {
14285                            Slog.i(TAG, "disable verification for instant app");
14286                        }
14287                        return false;
14288                    } catch (SecurityException ignore) { }
14289                }
14290            }
14291        }
14292
14293        if (ensureVerifyAppsEnabled) {
14294            return true;
14295        }
14296
14297        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14298                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14299    }
14300
14301    @Override
14302    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14303            throws RemoteException {
14304        mContext.enforceCallingOrSelfPermission(
14305                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14306                "Only intentfilter verification agents can verify applications");
14307
14308        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14309        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14310                Binder.getCallingUid(), verificationCode, failedDomains);
14311        msg.arg1 = id;
14312        msg.obj = response;
14313        mHandler.sendMessage(msg);
14314    }
14315
14316    @Override
14317    public int getIntentVerificationStatus(String packageName, int userId) {
14318        final int callingUid = Binder.getCallingUid();
14319        if (UserHandle.getUserId(callingUid) != userId) {
14320            mContext.enforceCallingOrSelfPermission(
14321                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14322                    "getIntentVerificationStatus" + userId);
14323        }
14324        if (getInstantAppPackageName(callingUid) != null) {
14325            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14326        }
14327        synchronized (mPackages) {
14328            final PackageSetting ps = mSettings.mPackages.get(packageName);
14329            if (ps == null
14330                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14331                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14332            }
14333            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14334        }
14335    }
14336
14337    @Override
14338    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14339        mContext.enforceCallingOrSelfPermission(
14340                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14341
14342        boolean result = false;
14343        synchronized (mPackages) {
14344            final PackageSetting ps = mSettings.mPackages.get(packageName);
14345            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14346                return false;
14347            }
14348            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14349        }
14350        if (result) {
14351            scheduleWritePackageRestrictionsLocked(userId);
14352        }
14353        return result;
14354    }
14355
14356    @Override
14357    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14358            String packageName) {
14359        final int callingUid = Binder.getCallingUid();
14360        if (getInstantAppPackageName(callingUid) != null) {
14361            return ParceledListSlice.emptyList();
14362        }
14363        synchronized (mPackages) {
14364            final PackageSetting ps = mSettings.mPackages.get(packageName);
14365            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14366                return ParceledListSlice.emptyList();
14367            }
14368            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14369        }
14370    }
14371
14372    @Override
14373    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14374        if (TextUtils.isEmpty(packageName)) {
14375            return ParceledListSlice.emptyList();
14376        }
14377        final int callingUid = Binder.getCallingUid();
14378        final int callingUserId = UserHandle.getUserId(callingUid);
14379        synchronized (mPackages) {
14380            PackageParser.Package pkg = mPackages.get(packageName);
14381            if (pkg == null || pkg.activities == null) {
14382                return ParceledListSlice.emptyList();
14383            }
14384            if (pkg.mExtras == null) {
14385                return ParceledListSlice.emptyList();
14386            }
14387            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14388            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14389                return ParceledListSlice.emptyList();
14390            }
14391            final int count = pkg.activities.size();
14392            ArrayList<IntentFilter> result = new ArrayList<>();
14393            for (int n=0; n<count; n++) {
14394                PackageParser.Activity activity = pkg.activities.get(n);
14395                if (activity.intents != null && activity.intents.size() > 0) {
14396                    result.addAll(activity.intents);
14397                }
14398            }
14399            return new ParceledListSlice<>(result);
14400        }
14401    }
14402
14403    @Override
14404    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14405        mContext.enforceCallingOrSelfPermission(
14406                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14407        if (UserHandle.getCallingUserId() != userId) {
14408            mContext.enforceCallingOrSelfPermission(
14409                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14410        }
14411
14412        synchronized (mPackages) {
14413            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14414            if (packageName != null) {
14415                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14416                        packageName, userId);
14417            }
14418            return result;
14419        }
14420    }
14421
14422    @Override
14423    public String getDefaultBrowserPackageName(int userId) {
14424        if (UserHandle.getCallingUserId() != userId) {
14425            mContext.enforceCallingOrSelfPermission(
14426                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14427        }
14428        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14429            return null;
14430        }
14431        synchronized (mPackages) {
14432            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14433        }
14434    }
14435
14436    /**
14437     * Get the "allow unknown sources" setting.
14438     *
14439     * @return the current "allow unknown sources" setting
14440     */
14441    private int getUnknownSourcesSettings() {
14442        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14443                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14444                -1);
14445    }
14446
14447    @Override
14448    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14449        final int callingUid = Binder.getCallingUid();
14450        if (getInstantAppPackageName(callingUid) != null) {
14451            return;
14452        }
14453        // writer
14454        synchronized (mPackages) {
14455            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14456            if (targetPackageSetting == null
14457                    || filterAppAccessLPr(
14458                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14459                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14460            }
14461
14462            PackageSetting installerPackageSetting;
14463            if (installerPackageName != null) {
14464                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14465                if (installerPackageSetting == null) {
14466                    throw new IllegalArgumentException("Unknown installer package: "
14467                            + installerPackageName);
14468                }
14469            } else {
14470                installerPackageSetting = null;
14471            }
14472
14473            Signature[] callerSignature;
14474            Object obj = mSettings.getUserIdLPr(callingUid);
14475            if (obj != null) {
14476                if (obj instanceof SharedUserSetting) {
14477                    callerSignature =
14478                            ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14479                } else if (obj instanceof PackageSetting) {
14480                    callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14481                } else {
14482                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14483                }
14484            } else {
14485                throw new SecurityException("Unknown calling UID: " + callingUid);
14486            }
14487
14488            // Verify: can't set installerPackageName to a package that is
14489            // not signed with the same cert as the caller.
14490            if (installerPackageSetting != null) {
14491                if (compareSignatures(callerSignature,
14492                        installerPackageSetting.signatures.mSigningDetails.signatures)
14493                        != PackageManager.SIGNATURE_MATCH) {
14494                    throw new SecurityException(
14495                            "Caller does not have same cert as new installer package "
14496                            + installerPackageName);
14497                }
14498            }
14499
14500            // Verify: if target already has an installer package, it must
14501            // be signed with the same cert as the caller.
14502            if (targetPackageSetting.installerPackageName != null) {
14503                PackageSetting setting = mSettings.mPackages.get(
14504                        targetPackageSetting.installerPackageName);
14505                // If the currently set package isn't valid, then it's always
14506                // okay to change it.
14507                if (setting != null) {
14508                    if (compareSignatures(callerSignature,
14509                            setting.signatures.mSigningDetails.signatures)
14510                            != PackageManager.SIGNATURE_MATCH) {
14511                        throw new SecurityException(
14512                                "Caller does not have same cert as old installer package "
14513                                + targetPackageSetting.installerPackageName);
14514                    }
14515                }
14516            }
14517
14518            // Okay!
14519            targetPackageSetting.installerPackageName = installerPackageName;
14520            if (installerPackageName != null) {
14521                mSettings.mInstallerPackages.add(installerPackageName);
14522            }
14523            scheduleWriteSettingsLocked();
14524        }
14525    }
14526
14527    @Override
14528    public void setApplicationCategoryHint(String packageName, int categoryHint,
14529            String callerPackageName) {
14530        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14531            throw new SecurityException("Instant applications don't have access to this method");
14532        }
14533        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14534                callerPackageName);
14535        synchronized (mPackages) {
14536            PackageSetting ps = mSettings.mPackages.get(packageName);
14537            if (ps == null) {
14538                throw new IllegalArgumentException("Unknown target package " + packageName);
14539            }
14540            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14541                throw new IllegalArgumentException("Unknown target package " + packageName);
14542            }
14543            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14544                throw new IllegalArgumentException("Calling package " + callerPackageName
14545                        + " is not installer for " + packageName);
14546            }
14547
14548            if (ps.categoryHint != categoryHint) {
14549                ps.categoryHint = categoryHint;
14550                scheduleWriteSettingsLocked();
14551            }
14552        }
14553    }
14554
14555    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14556        // Queue up an async operation since the package installation may take a little while.
14557        mHandler.post(new Runnable() {
14558            public void run() {
14559                mHandler.removeCallbacks(this);
14560                 // Result object to be returned
14561                PackageInstalledInfo res = new PackageInstalledInfo();
14562                res.setReturnCode(currentStatus);
14563                res.uid = -1;
14564                res.pkg = null;
14565                res.removedInfo = null;
14566                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14567                    args.doPreInstall(res.returnCode);
14568                    synchronized (mInstallLock) {
14569                        installPackageTracedLI(args, res);
14570                    }
14571                    args.doPostInstall(res.returnCode, res.uid);
14572                }
14573
14574                // A restore should be performed at this point if (a) the install
14575                // succeeded, (b) the operation is not an update, and (c) the new
14576                // package has not opted out of backup participation.
14577                final boolean update = res.removedInfo != null
14578                        && res.removedInfo.removedPackage != null;
14579                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14580                boolean doRestore = !update
14581                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14582
14583                // Set up the post-install work request bookkeeping.  This will be used
14584                // and cleaned up by the post-install event handling regardless of whether
14585                // there's a restore pass performed.  Token values are >= 1.
14586                int token;
14587                if (mNextInstallToken < 0) mNextInstallToken = 1;
14588                token = mNextInstallToken++;
14589
14590                PostInstallData data = new PostInstallData(args, res);
14591                mRunningInstalls.put(token, data);
14592                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14593
14594                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14595                    // Pass responsibility to the Backup Manager.  It will perform a
14596                    // restore if appropriate, then pass responsibility back to the
14597                    // Package Manager to run the post-install observer callbacks
14598                    // and broadcasts.
14599                    IBackupManager bm = IBackupManager.Stub.asInterface(
14600                            ServiceManager.getService(Context.BACKUP_SERVICE));
14601                    if (bm != null) {
14602                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14603                                + " to BM for possible restore");
14604                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14605                        try {
14606                            // TODO: http://b/22388012
14607                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14608                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14609                            } else {
14610                                doRestore = false;
14611                            }
14612                        } catch (RemoteException e) {
14613                            // can't happen; the backup manager is local
14614                        } catch (Exception e) {
14615                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14616                            doRestore = false;
14617                        }
14618                    } else {
14619                        Slog.e(TAG, "Backup Manager not found!");
14620                        doRestore = false;
14621                    }
14622                }
14623
14624                if (!doRestore) {
14625                    // No restore possible, or the Backup Manager was mysteriously not
14626                    // available -- just fire the post-install work request directly.
14627                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14628
14629                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14630
14631                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14632                    mHandler.sendMessage(msg);
14633                }
14634            }
14635        });
14636    }
14637
14638    /**
14639     * Callback from PackageSettings whenever an app is first transitioned out of the
14640     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14641     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14642     * here whether the app is the target of an ongoing install, and only send the
14643     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14644     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14645     * handling.
14646     */
14647    void notifyFirstLaunch(final String packageName, final String installerPackage,
14648            final int userId) {
14649        // Serialize this with the rest of the install-process message chain.  In the
14650        // restore-at-install case, this Runnable will necessarily run before the
14651        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14652        // are coherent.  In the non-restore case, the app has already completed install
14653        // and been launched through some other means, so it is not in a problematic
14654        // state for observers to see the FIRST_LAUNCH signal.
14655        mHandler.post(new Runnable() {
14656            @Override
14657            public void run() {
14658                for (int i = 0; i < mRunningInstalls.size(); i++) {
14659                    final PostInstallData data = mRunningInstalls.valueAt(i);
14660                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14661                        continue;
14662                    }
14663                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14664                        // right package; but is it for the right user?
14665                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14666                            if (userId == data.res.newUsers[uIndex]) {
14667                                if (DEBUG_BACKUP) {
14668                                    Slog.i(TAG, "Package " + packageName
14669                                            + " being restored so deferring FIRST_LAUNCH");
14670                                }
14671                                return;
14672                            }
14673                        }
14674                    }
14675                }
14676                // didn't find it, so not being restored
14677                if (DEBUG_BACKUP) {
14678                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14679                }
14680                final boolean isInstantApp = isInstantApp(packageName, userId);
14681                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14682                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14683                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14684            }
14685        });
14686    }
14687
14688    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14689            int[] userIds, int[] instantUserIds) {
14690        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14691                installerPkg, null, userIds, instantUserIds);
14692    }
14693
14694    private abstract class HandlerParams {
14695        private static final int MAX_RETRIES = 4;
14696
14697        /**
14698         * Number of times startCopy() has been attempted and had a non-fatal
14699         * error.
14700         */
14701        private int mRetries = 0;
14702
14703        /** User handle for the user requesting the information or installation. */
14704        private final UserHandle mUser;
14705        String traceMethod;
14706        int traceCookie;
14707
14708        HandlerParams(UserHandle user) {
14709            mUser = user;
14710        }
14711
14712        UserHandle getUser() {
14713            return mUser;
14714        }
14715
14716        HandlerParams setTraceMethod(String traceMethod) {
14717            this.traceMethod = traceMethod;
14718            return this;
14719        }
14720
14721        HandlerParams setTraceCookie(int traceCookie) {
14722            this.traceCookie = traceCookie;
14723            return this;
14724        }
14725
14726        final boolean startCopy() {
14727            boolean res;
14728            try {
14729                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14730
14731                if (++mRetries > MAX_RETRIES) {
14732                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14733                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14734                    handleServiceError();
14735                    return false;
14736                } else {
14737                    handleStartCopy();
14738                    res = true;
14739                }
14740            } catch (RemoteException e) {
14741                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14742                mHandler.sendEmptyMessage(MCS_RECONNECT);
14743                res = false;
14744            }
14745            handleReturnCode();
14746            return res;
14747        }
14748
14749        final void serviceError() {
14750            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14751            handleServiceError();
14752            handleReturnCode();
14753        }
14754
14755        abstract void handleStartCopy() throws RemoteException;
14756        abstract void handleServiceError();
14757        abstract void handleReturnCode();
14758    }
14759
14760    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14761        for (File path : paths) {
14762            try {
14763                mcs.clearDirectory(path.getAbsolutePath());
14764            } catch (RemoteException e) {
14765            }
14766        }
14767    }
14768
14769    static class OriginInfo {
14770        /**
14771         * Location where install is coming from, before it has been
14772         * copied/renamed into place. This could be a single monolithic APK
14773         * file, or a cluster directory. This location may be untrusted.
14774         */
14775        final File file;
14776
14777        /**
14778         * Flag indicating that {@link #file} or {@link #cid} has already been
14779         * staged, meaning downstream users don't need to defensively copy the
14780         * contents.
14781         */
14782        final boolean staged;
14783
14784        /**
14785         * Flag indicating that {@link #file} or {@link #cid} is an already
14786         * installed app that is being moved.
14787         */
14788        final boolean existing;
14789
14790        final String resolvedPath;
14791        final File resolvedFile;
14792
14793        static OriginInfo fromNothing() {
14794            return new OriginInfo(null, false, false);
14795        }
14796
14797        static OriginInfo fromUntrustedFile(File file) {
14798            return new OriginInfo(file, false, false);
14799        }
14800
14801        static OriginInfo fromExistingFile(File file) {
14802            return new OriginInfo(file, false, true);
14803        }
14804
14805        static OriginInfo fromStagedFile(File file) {
14806            return new OriginInfo(file, true, false);
14807        }
14808
14809        private OriginInfo(File file, boolean staged, boolean existing) {
14810            this.file = file;
14811            this.staged = staged;
14812            this.existing = existing;
14813
14814            if (file != null) {
14815                resolvedPath = file.getAbsolutePath();
14816                resolvedFile = file;
14817            } else {
14818                resolvedPath = null;
14819                resolvedFile = null;
14820            }
14821        }
14822    }
14823
14824    static class MoveInfo {
14825        final int moveId;
14826        final String fromUuid;
14827        final String toUuid;
14828        final String packageName;
14829        final String dataAppName;
14830        final int appId;
14831        final String seinfo;
14832        final int targetSdkVersion;
14833
14834        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14835                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14836            this.moveId = moveId;
14837            this.fromUuid = fromUuid;
14838            this.toUuid = toUuid;
14839            this.packageName = packageName;
14840            this.dataAppName = dataAppName;
14841            this.appId = appId;
14842            this.seinfo = seinfo;
14843            this.targetSdkVersion = targetSdkVersion;
14844        }
14845    }
14846
14847    static class VerificationInfo {
14848        /** A constant used to indicate that a uid value is not present. */
14849        public static final int NO_UID = -1;
14850
14851        /** URI referencing where the package was downloaded from. */
14852        final Uri originatingUri;
14853
14854        /** HTTP referrer URI associated with the originatingURI. */
14855        final Uri referrer;
14856
14857        /** UID of the application that the install request originated from. */
14858        final int originatingUid;
14859
14860        /** UID of application requesting the install */
14861        final int installerUid;
14862
14863        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14864            this.originatingUri = originatingUri;
14865            this.referrer = referrer;
14866            this.originatingUid = originatingUid;
14867            this.installerUid = installerUid;
14868        }
14869    }
14870
14871    class InstallParams extends HandlerParams {
14872        final OriginInfo origin;
14873        final MoveInfo move;
14874        final IPackageInstallObserver2 observer;
14875        int installFlags;
14876        final String installerPackageName;
14877        final String volumeUuid;
14878        private InstallArgs mArgs;
14879        private int mRet;
14880        final String packageAbiOverride;
14881        final String[] grantedRuntimePermissions;
14882        final VerificationInfo verificationInfo;
14883        final PackageParser.SigningDetails signingDetails;
14884        final int installReason;
14885
14886        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14887                int installFlags, String installerPackageName, String volumeUuid,
14888                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14889                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
14890            super(user);
14891            this.origin = origin;
14892            this.move = move;
14893            this.observer = observer;
14894            this.installFlags = installFlags;
14895            this.installerPackageName = installerPackageName;
14896            this.volumeUuid = volumeUuid;
14897            this.verificationInfo = verificationInfo;
14898            this.packageAbiOverride = packageAbiOverride;
14899            this.grantedRuntimePermissions = grantedPermissions;
14900            this.signingDetails = signingDetails;
14901            this.installReason = installReason;
14902        }
14903
14904        @Override
14905        public String toString() {
14906            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14907                    + " file=" + origin.file + "}";
14908        }
14909
14910        private int installLocationPolicy(PackageInfoLite pkgLite) {
14911            String packageName = pkgLite.packageName;
14912            int installLocation = pkgLite.installLocation;
14913            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14914            // reader
14915            synchronized (mPackages) {
14916                // Currently installed package which the new package is attempting to replace or
14917                // null if no such package is installed.
14918                PackageParser.Package installedPkg = mPackages.get(packageName);
14919                // Package which currently owns the data which the new package will own if installed.
14920                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14921                // will be null whereas dataOwnerPkg will contain information about the package
14922                // which was uninstalled while keeping its data.
14923                PackageParser.Package dataOwnerPkg = installedPkg;
14924                if (dataOwnerPkg  == null) {
14925                    PackageSetting ps = mSettings.mPackages.get(packageName);
14926                    if (ps != null) {
14927                        dataOwnerPkg = ps.pkg;
14928                    }
14929                }
14930
14931                if (dataOwnerPkg != null) {
14932                    // If installed, the package will get access to data left on the device by its
14933                    // predecessor. As a security measure, this is permited only if this is not a
14934                    // version downgrade or if the predecessor package is marked as debuggable and
14935                    // a downgrade is explicitly requested.
14936                    //
14937                    // On debuggable platform builds, downgrades are permitted even for
14938                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14939                    // not offer security guarantees and thus it's OK to disable some security
14940                    // mechanisms to make debugging/testing easier on those builds. However, even on
14941                    // debuggable builds downgrades of packages are permitted only if requested via
14942                    // installFlags. This is because we aim to keep the behavior of debuggable
14943                    // platform builds as close as possible to the behavior of non-debuggable
14944                    // platform builds.
14945                    final boolean downgradeRequested =
14946                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14947                    final boolean packageDebuggable =
14948                                (dataOwnerPkg.applicationInfo.flags
14949                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14950                    final boolean downgradePermitted =
14951                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14952                    if (!downgradePermitted) {
14953                        try {
14954                            checkDowngrade(dataOwnerPkg, pkgLite);
14955                        } catch (PackageManagerException e) {
14956                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14957                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14958                        }
14959                    }
14960                }
14961
14962                if (installedPkg != null) {
14963                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14964                        // Check for updated system application.
14965                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14966                            if (onSd) {
14967                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14968                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14969                            }
14970                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14971                        } else {
14972                            if (onSd) {
14973                                // Install flag overrides everything.
14974                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14975                            }
14976                            // If current upgrade specifies particular preference
14977                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14978                                // Application explicitly specified internal.
14979                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14980                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14981                                // App explictly prefers external. Let policy decide
14982                            } else {
14983                                // Prefer previous location
14984                                if (isExternal(installedPkg)) {
14985                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14986                                }
14987                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14988                            }
14989                        }
14990                    } else {
14991                        // Invalid install. Return error code
14992                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14993                    }
14994                }
14995            }
14996            // All the special cases have been taken care of.
14997            // Return result based on recommended install location.
14998            if (onSd) {
14999                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15000            }
15001            return pkgLite.recommendedInstallLocation;
15002        }
15003
15004        /*
15005         * Invoke remote method to get package information and install
15006         * location values. Override install location based on default
15007         * policy if needed and then create install arguments based
15008         * on the install location.
15009         */
15010        public void handleStartCopy() throws RemoteException {
15011            int ret = PackageManager.INSTALL_SUCCEEDED;
15012
15013            // If we're already staged, we've firmly committed to an install location
15014            if (origin.staged) {
15015                if (origin.file != null) {
15016                    installFlags |= PackageManager.INSTALL_INTERNAL;
15017                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15018                } else {
15019                    throw new IllegalStateException("Invalid stage location");
15020                }
15021            }
15022
15023            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15024            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15025            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15026            PackageInfoLite pkgLite = null;
15027
15028            if (onInt && onSd) {
15029                // Check if both bits are set.
15030                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15031                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15032            } else if (onSd && ephemeral) {
15033                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15034                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15035            } else {
15036                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15037                        packageAbiOverride);
15038
15039                if (DEBUG_INSTANT && ephemeral) {
15040                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15041                }
15042
15043                /*
15044                 * If we have too little free space, try to free cache
15045                 * before giving up.
15046                 */
15047                if (!origin.staged && pkgLite.recommendedInstallLocation
15048                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15049                    // TODO: focus freeing disk space on the target device
15050                    final StorageManager storage = StorageManager.from(mContext);
15051                    final long lowThreshold = storage.getStorageLowBytes(
15052                            Environment.getDataDirectory());
15053
15054                    final long sizeBytes = mContainerService.calculateInstalledSize(
15055                            origin.resolvedPath, packageAbiOverride);
15056
15057                    try {
15058                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15059                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15060                                installFlags, packageAbiOverride);
15061                    } catch (InstallerException e) {
15062                        Slog.w(TAG, "Failed to free cache", e);
15063                    }
15064
15065                    /*
15066                     * The cache free must have deleted the file we
15067                     * downloaded to install.
15068                     *
15069                     * TODO: fix the "freeCache" call to not delete
15070                     *       the file we care about.
15071                     */
15072                    if (pkgLite.recommendedInstallLocation
15073                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15074                        pkgLite.recommendedInstallLocation
15075                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15076                    }
15077                }
15078            }
15079
15080            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15081                int loc = pkgLite.recommendedInstallLocation;
15082                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15083                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15084                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15085                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15086                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15087                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15088                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15089                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15090                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15091                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15092                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15093                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15094                } else {
15095                    // Override with defaults if needed.
15096                    loc = installLocationPolicy(pkgLite);
15097                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15098                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15099                    } else if (!onSd && !onInt) {
15100                        // Override install location with flags
15101                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15102                            // Set the flag to install on external media.
15103                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15104                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15105                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15106                            if (DEBUG_INSTANT) {
15107                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15108                            }
15109                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15110                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15111                                    |PackageManager.INSTALL_INTERNAL);
15112                        } else {
15113                            // Make sure the flag for installing on external
15114                            // media is unset
15115                            installFlags |= PackageManager.INSTALL_INTERNAL;
15116                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15117                        }
15118                    }
15119                }
15120            }
15121
15122            final InstallArgs args = createInstallArgs(this);
15123            mArgs = args;
15124
15125            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15126                // TODO: http://b/22976637
15127                // Apps installed for "all" users use the device owner to verify the app
15128                UserHandle verifierUser = getUser();
15129                if (verifierUser == UserHandle.ALL) {
15130                    verifierUser = UserHandle.SYSTEM;
15131                }
15132
15133                /*
15134                 * Determine if we have any installed package verifiers. If we
15135                 * do, then we'll defer to them to verify the packages.
15136                 */
15137                final int requiredUid = mRequiredVerifierPackage == null ? -1
15138                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15139                                verifierUser.getIdentifier());
15140                final int installerUid =
15141                        verificationInfo == null ? -1 : verificationInfo.installerUid;
15142                if (!origin.existing && requiredUid != -1
15143                        && isVerificationEnabled(
15144                                verifierUser.getIdentifier(), installFlags, installerUid)) {
15145                    final Intent verification = new Intent(
15146                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15147                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15148                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15149                            PACKAGE_MIME_TYPE);
15150                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15151
15152                    // Query all live verifiers based on current user state
15153                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15154                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15155                            false /*allowDynamicSplits*/);
15156
15157                    if (DEBUG_VERIFY) {
15158                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15159                                + verification.toString() + " with " + pkgLite.verifiers.length
15160                                + " optional verifiers");
15161                    }
15162
15163                    final int verificationId = mPendingVerificationToken++;
15164
15165                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15166
15167                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15168                            installerPackageName);
15169
15170                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15171                            installFlags);
15172
15173                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15174                            pkgLite.packageName);
15175
15176                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15177                            pkgLite.versionCode);
15178
15179                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15180                            pkgLite.getLongVersionCode());
15181
15182                    if (verificationInfo != null) {
15183                        if (verificationInfo.originatingUri != null) {
15184                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15185                                    verificationInfo.originatingUri);
15186                        }
15187                        if (verificationInfo.referrer != null) {
15188                            verification.putExtra(Intent.EXTRA_REFERRER,
15189                                    verificationInfo.referrer);
15190                        }
15191                        if (verificationInfo.originatingUid >= 0) {
15192                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15193                                    verificationInfo.originatingUid);
15194                        }
15195                        if (verificationInfo.installerUid >= 0) {
15196                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15197                                    verificationInfo.installerUid);
15198                        }
15199                    }
15200
15201                    final PackageVerificationState verificationState = new PackageVerificationState(
15202                            requiredUid, args);
15203
15204                    mPendingVerification.append(verificationId, verificationState);
15205
15206                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15207                            receivers, verificationState);
15208
15209                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15210                    final long idleDuration = getVerificationTimeout();
15211
15212                    /*
15213                     * If any sufficient verifiers were listed in the package
15214                     * manifest, attempt to ask them.
15215                     */
15216                    if (sufficientVerifiers != null) {
15217                        final int N = sufficientVerifiers.size();
15218                        if (N == 0) {
15219                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15220                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15221                        } else {
15222                            for (int i = 0; i < N; i++) {
15223                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15224                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15225                                        verifierComponent.getPackageName(), idleDuration,
15226                                        verifierUser.getIdentifier(), false, "package verifier");
15227
15228                                final Intent sufficientIntent = new Intent(verification);
15229                                sufficientIntent.setComponent(verifierComponent);
15230                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15231                            }
15232                        }
15233                    }
15234
15235                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15236                            mRequiredVerifierPackage, receivers);
15237                    if (ret == PackageManager.INSTALL_SUCCEEDED
15238                            && mRequiredVerifierPackage != null) {
15239                        Trace.asyncTraceBegin(
15240                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15241                        /*
15242                         * Send the intent to the required verification agent,
15243                         * but only start the verification timeout after the
15244                         * target BroadcastReceivers have run.
15245                         */
15246                        verification.setComponent(requiredVerifierComponent);
15247                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15248                                mRequiredVerifierPackage, idleDuration,
15249                                verifierUser.getIdentifier(), false, "package verifier");
15250                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15251                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15252                                new BroadcastReceiver() {
15253                                    @Override
15254                                    public void onReceive(Context context, Intent intent) {
15255                                        final Message msg = mHandler
15256                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15257                                        msg.arg1 = verificationId;
15258                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15259                                    }
15260                                }, null, 0, null, null);
15261
15262                        /*
15263                         * We don't want the copy to proceed until verification
15264                         * succeeds, so null out this field.
15265                         */
15266                        mArgs = null;
15267                    }
15268                } else {
15269                    /*
15270                     * No package verification is enabled, so immediately start
15271                     * the remote call to initiate copy using temporary file.
15272                     */
15273                    ret = args.copyApk(mContainerService, true);
15274                }
15275            }
15276
15277            mRet = ret;
15278        }
15279
15280        @Override
15281        void handleReturnCode() {
15282            // If mArgs is null, then MCS couldn't be reached. When it
15283            // reconnects, it will try again to install. At that point, this
15284            // will succeed.
15285            if (mArgs != null) {
15286                processPendingInstall(mArgs, mRet);
15287            }
15288        }
15289
15290        @Override
15291        void handleServiceError() {
15292            mArgs = createInstallArgs(this);
15293            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15294        }
15295    }
15296
15297    private InstallArgs createInstallArgs(InstallParams params) {
15298        if (params.move != null) {
15299            return new MoveInstallArgs(params);
15300        } else {
15301            return new FileInstallArgs(params);
15302        }
15303    }
15304
15305    /**
15306     * Create args that describe an existing installed package. Typically used
15307     * when cleaning up old installs, or used as a move source.
15308     */
15309    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15310            String resourcePath, String[] instructionSets) {
15311        return new FileInstallArgs(codePath, resourcePath, instructionSets);
15312    }
15313
15314    static abstract class InstallArgs {
15315        /** @see InstallParams#origin */
15316        final OriginInfo origin;
15317        /** @see InstallParams#move */
15318        final MoveInfo move;
15319
15320        final IPackageInstallObserver2 observer;
15321        // Always refers to PackageManager flags only
15322        final int installFlags;
15323        final String installerPackageName;
15324        final String volumeUuid;
15325        final UserHandle user;
15326        final String abiOverride;
15327        final String[] installGrantPermissions;
15328        /** If non-null, drop an async trace when the install completes */
15329        final String traceMethod;
15330        final int traceCookie;
15331        final PackageParser.SigningDetails signingDetails;
15332        final int installReason;
15333
15334        // The list of instruction sets supported by this app. This is currently
15335        // only used during the rmdex() phase to clean up resources. We can get rid of this
15336        // if we move dex files under the common app path.
15337        /* nullable */ String[] instructionSets;
15338
15339        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15340                int installFlags, String installerPackageName, String volumeUuid,
15341                UserHandle user, String[] instructionSets,
15342                String abiOverride, String[] installGrantPermissions,
15343                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15344                int installReason) {
15345            this.origin = origin;
15346            this.move = move;
15347            this.installFlags = installFlags;
15348            this.observer = observer;
15349            this.installerPackageName = installerPackageName;
15350            this.volumeUuid = volumeUuid;
15351            this.user = user;
15352            this.instructionSets = instructionSets;
15353            this.abiOverride = abiOverride;
15354            this.installGrantPermissions = installGrantPermissions;
15355            this.traceMethod = traceMethod;
15356            this.traceCookie = traceCookie;
15357            this.signingDetails = signingDetails;
15358            this.installReason = installReason;
15359        }
15360
15361        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15362        abstract int doPreInstall(int status);
15363
15364        /**
15365         * Rename package into final resting place. All paths on the given
15366         * scanned package should be updated to reflect the rename.
15367         */
15368        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15369        abstract int doPostInstall(int status, int uid);
15370
15371        /** @see PackageSettingBase#codePathString */
15372        abstract String getCodePath();
15373        /** @see PackageSettingBase#resourcePathString */
15374        abstract String getResourcePath();
15375
15376        // Need installer lock especially for dex file removal.
15377        abstract void cleanUpResourcesLI();
15378        abstract boolean doPostDeleteLI(boolean delete);
15379
15380        /**
15381         * Called before the source arguments are copied. This is used mostly
15382         * for MoveParams when it needs to read the source file to put it in the
15383         * destination.
15384         */
15385        int doPreCopy() {
15386            return PackageManager.INSTALL_SUCCEEDED;
15387        }
15388
15389        /**
15390         * Called after the source arguments are copied. This is used mostly for
15391         * MoveParams when it needs to read the source file to put it in the
15392         * destination.
15393         */
15394        int doPostCopy(int uid) {
15395            return PackageManager.INSTALL_SUCCEEDED;
15396        }
15397
15398        protected boolean isFwdLocked() {
15399            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15400        }
15401
15402        protected boolean isExternalAsec() {
15403            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15404        }
15405
15406        protected boolean isEphemeral() {
15407            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15408        }
15409
15410        UserHandle getUser() {
15411            return user;
15412        }
15413    }
15414
15415    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15416        if (!allCodePaths.isEmpty()) {
15417            if (instructionSets == null) {
15418                throw new IllegalStateException("instructionSet == null");
15419            }
15420            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15421            for (String codePath : allCodePaths) {
15422                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15423                    try {
15424                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15425                    } catch (InstallerException ignored) {
15426                    }
15427                }
15428            }
15429        }
15430    }
15431
15432    /**
15433     * Logic to handle installation of non-ASEC applications, including copying
15434     * and renaming logic.
15435     */
15436    class FileInstallArgs extends InstallArgs {
15437        private File codeFile;
15438        private File resourceFile;
15439
15440        // Example topology:
15441        // /data/app/com.example/base.apk
15442        // /data/app/com.example/split_foo.apk
15443        // /data/app/com.example/lib/arm/libfoo.so
15444        // /data/app/com.example/lib/arm64/libfoo.so
15445        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15446
15447        /** New install */
15448        FileInstallArgs(InstallParams params) {
15449            super(params.origin, params.move, params.observer, params.installFlags,
15450                    params.installerPackageName, params.volumeUuid,
15451                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15452                    params.grantedRuntimePermissions,
15453                    params.traceMethod, params.traceCookie, params.signingDetails,
15454                    params.installReason);
15455            if (isFwdLocked()) {
15456                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15457            }
15458        }
15459
15460        /** Existing install */
15461        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15462            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15463                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15464                    PackageManager.INSTALL_REASON_UNKNOWN);
15465            this.codeFile = (codePath != null) ? new File(codePath) : null;
15466            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15467        }
15468
15469        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15470            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15471            try {
15472                return doCopyApk(imcs, temp);
15473            } finally {
15474                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15475            }
15476        }
15477
15478        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15479            if (origin.staged) {
15480                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15481                codeFile = origin.file;
15482                resourceFile = origin.file;
15483                return PackageManager.INSTALL_SUCCEEDED;
15484            }
15485
15486            try {
15487                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15488                final File tempDir =
15489                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15490                codeFile = tempDir;
15491                resourceFile = tempDir;
15492            } catch (IOException e) {
15493                Slog.w(TAG, "Failed to create copy file: " + e);
15494                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15495            }
15496
15497            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15498                @Override
15499                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15500                    if (!FileUtils.isValidExtFilename(name)) {
15501                        throw new IllegalArgumentException("Invalid filename: " + name);
15502                    }
15503                    try {
15504                        final File file = new File(codeFile, name);
15505                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15506                                O_RDWR | O_CREAT, 0644);
15507                        Os.chmod(file.getAbsolutePath(), 0644);
15508                        return new ParcelFileDescriptor(fd);
15509                    } catch (ErrnoException e) {
15510                        throw new RemoteException("Failed to open: " + e.getMessage());
15511                    }
15512                }
15513            };
15514
15515            int ret = PackageManager.INSTALL_SUCCEEDED;
15516            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15517            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15518                Slog.e(TAG, "Failed to copy package");
15519                return ret;
15520            }
15521
15522            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15523            NativeLibraryHelper.Handle handle = null;
15524            try {
15525                handle = NativeLibraryHelper.Handle.create(codeFile);
15526                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15527                        abiOverride);
15528            } catch (IOException e) {
15529                Slog.e(TAG, "Copying native libraries failed", e);
15530                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15531            } finally {
15532                IoUtils.closeQuietly(handle);
15533            }
15534
15535            return ret;
15536        }
15537
15538        int doPreInstall(int status) {
15539            if (status != PackageManager.INSTALL_SUCCEEDED) {
15540                cleanUp();
15541            }
15542            return status;
15543        }
15544
15545        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15546            if (status != PackageManager.INSTALL_SUCCEEDED) {
15547                cleanUp();
15548                return false;
15549            }
15550
15551            final File targetDir = codeFile.getParentFile();
15552            final File beforeCodeFile = codeFile;
15553            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15554
15555            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15556            try {
15557                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15558            } catch (ErrnoException e) {
15559                Slog.w(TAG, "Failed to rename", e);
15560                return false;
15561            }
15562
15563            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15564                Slog.w(TAG, "Failed to restorecon");
15565                return false;
15566            }
15567
15568            // Reflect the rename internally
15569            codeFile = afterCodeFile;
15570            resourceFile = afterCodeFile;
15571
15572            // Reflect the rename in scanned details
15573            try {
15574                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15575            } catch (IOException e) {
15576                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15577                return false;
15578            }
15579            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15580                    afterCodeFile, pkg.baseCodePath));
15581            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15582                    afterCodeFile, pkg.splitCodePaths));
15583
15584            // Reflect the rename in app info
15585            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15586            pkg.setApplicationInfoCodePath(pkg.codePath);
15587            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15588            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15589            pkg.setApplicationInfoResourcePath(pkg.codePath);
15590            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15591            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15592
15593            return true;
15594        }
15595
15596        int doPostInstall(int status, int uid) {
15597            if (status != PackageManager.INSTALL_SUCCEEDED) {
15598                cleanUp();
15599            }
15600            return status;
15601        }
15602
15603        @Override
15604        String getCodePath() {
15605            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15606        }
15607
15608        @Override
15609        String getResourcePath() {
15610            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15611        }
15612
15613        private boolean cleanUp() {
15614            if (codeFile == null || !codeFile.exists()) {
15615                return false;
15616            }
15617
15618            removeCodePathLI(codeFile);
15619
15620            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15621                resourceFile.delete();
15622            }
15623
15624            return true;
15625        }
15626
15627        void cleanUpResourcesLI() {
15628            // Try enumerating all code paths before deleting
15629            List<String> allCodePaths = Collections.EMPTY_LIST;
15630            if (codeFile != null && codeFile.exists()) {
15631                try {
15632                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15633                    allCodePaths = pkg.getAllCodePaths();
15634                } catch (PackageParserException e) {
15635                    // Ignored; we tried our best
15636                }
15637            }
15638
15639            cleanUp();
15640            removeDexFiles(allCodePaths, instructionSets);
15641        }
15642
15643        boolean doPostDeleteLI(boolean delete) {
15644            // XXX err, shouldn't we respect the delete flag?
15645            cleanUpResourcesLI();
15646            return true;
15647        }
15648    }
15649
15650    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15651            PackageManagerException {
15652        if (copyRet < 0) {
15653            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15654                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15655                throw new PackageManagerException(copyRet, message);
15656            }
15657        }
15658    }
15659
15660    /**
15661     * Extract the StorageManagerService "container ID" from the full code path of an
15662     * .apk.
15663     */
15664    static String cidFromCodePath(String fullCodePath) {
15665        int eidx = fullCodePath.lastIndexOf("/");
15666        String subStr1 = fullCodePath.substring(0, eidx);
15667        int sidx = subStr1.lastIndexOf("/");
15668        return subStr1.substring(sidx+1, eidx);
15669    }
15670
15671    /**
15672     * Logic to handle movement of existing installed applications.
15673     */
15674    class MoveInstallArgs extends InstallArgs {
15675        private File codeFile;
15676        private File resourceFile;
15677
15678        /** New install */
15679        MoveInstallArgs(InstallParams params) {
15680            super(params.origin, params.move, params.observer, params.installFlags,
15681                    params.installerPackageName, params.volumeUuid,
15682                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15683                    params.grantedRuntimePermissions,
15684                    params.traceMethod, params.traceCookie, params.signingDetails,
15685                    params.installReason);
15686        }
15687
15688        int copyApk(IMediaContainerService imcs, boolean temp) {
15689            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15690                    + move.fromUuid + " to " + move.toUuid);
15691            synchronized (mInstaller) {
15692                try {
15693                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15694                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15695                } catch (InstallerException e) {
15696                    Slog.w(TAG, "Failed to move app", e);
15697                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15698                }
15699            }
15700
15701            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15702            resourceFile = codeFile;
15703            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15704
15705            return PackageManager.INSTALL_SUCCEEDED;
15706        }
15707
15708        int doPreInstall(int status) {
15709            if (status != PackageManager.INSTALL_SUCCEEDED) {
15710                cleanUp(move.toUuid);
15711            }
15712            return status;
15713        }
15714
15715        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15716            if (status != PackageManager.INSTALL_SUCCEEDED) {
15717                cleanUp(move.toUuid);
15718                return false;
15719            }
15720
15721            // Reflect the move in app info
15722            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15723            pkg.setApplicationInfoCodePath(pkg.codePath);
15724            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15725            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15726            pkg.setApplicationInfoResourcePath(pkg.codePath);
15727            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15728            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15729
15730            return true;
15731        }
15732
15733        int doPostInstall(int status, int uid) {
15734            if (status == PackageManager.INSTALL_SUCCEEDED) {
15735                cleanUp(move.fromUuid);
15736            } else {
15737                cleanUp(move.toUuid);
15738            }
15739            return status;
15740        }
15741
15742        @Override
15743        String getCodePath() {
15744            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15745        }
15746
15747        @Override
15748        String getResourcePath() {
15749            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15750        }
15751
15752        private boolean cleanUp(String volumeUuid) {
15753            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15754                    move.dataAppName);
15755            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15756            final int[] userIds = sUserManager.getUserIds();
15757            synchronized (mInstallLock) {
15758                // Clean up both app data and code
15759                // All package moves are frozen until finished
15760                for (int userId : userIds) {
15761                    try {
15762                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15763                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15764                    } catch (InstallerException e) {
15765                        Slog.w(TAG, String.valueOf(e));
15766                    }
15767                }
15768                removeCodePathLI(codeFile);
15769            }
15770            return true;
15771        }
15772
15773        void cleanUpResourcesLI() {
15774            throw new UnsupportedOperationException();
15775        }
15776
15777        boolean doPostDeleteLI(boolean delete) {
15778            throw new UnsupportedOperationException();
15779        }
15780    }
15781
15782    static String getAsecPackageName(String packageCid) {
15783        int idx = packageCid.lastIndexOf("-");
15784        if (idx == -1) {
15785            return packageCid;
15786        }
15787        return packageCid.substring(0, idx);
15788    }
15789
15790    // Utility method used to create code paths based on package name and available index.
15791    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15792        String idxStr = "";
15793        int idx = 1;
15794        // Fall back to default value of idx=1 if prefix is not
15795        // part of oldCodePath
15796        if (oldCodePath != null) {
15797            String subStr = oldCodePath;
15798            // Drop the suffix right away
15799            if (suffix != null && subStr.endsWith(suffix)) {
15800                subStr = subStr.substring(0, subStr.length() - suffix.length());
15801            }
15802            // If oldCodePath already contains prefix find out the
15803            // ending index to either increment or decrement.
15804            int sidx = subStr.lastIndexOf(prefix);
15805            if (sidx != -1) {
15806                subStr = subStr.substring(sidx + prefix.length());
15807                if (subStr != null) {
15808                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15809                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15810                    }
15811                    try {
15812                        idx = Integer.parseInt(subStr);
15813                        if (idx <= 1) {
15814                            idx++;
15815                        } else {
15816                            idx--;
15817                        }
15818                    } catch(NumberFormatException e) {
15819                    }
15820                }
15821            }
15822        }
15823        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15824        return prefix + idxStr;
15825    }
15826
15827    private File getNextCodePath(File targetDir, String packageName) {
15828        File result;
15829        SecureRandom random = new SecureRandom();
15830        byte[] bytes = new byte[16];
15831        do {
15832            random.nextBytes(bytes);
15833            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15834            result = new File(targetDir, packageName + "-" + suffix);
15835        } while (result.exists());
15836        return result;
15837    }
15838
15839    // Utility method that returns the relative package path with respect
15840    // to the installation directory. Like say for /data/data/com.test-1.apk
15841    // string com.test-1 is returned.
15842    static String deriveCodePathName(String codePath) {
15843        if (codePath == null) {
15844            return null;
15845        }
15846        final File codeFile = new File(codePath);
15847        final String name = codeFile.getName();
15848        if (codeFile.isDirectory()) {
15849            return name;
15850        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15851            final int lastDot = name.lastIndexOf('.');
15852            return name.substring(0, lastDot);
15853        } else {
15854            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15855            return null;
15856        }
15857    }
15858
15859    static class PackageInstalledInfo {
15860        String name;
15861        int uid;
15862        // The set of users that originally had this package installed.
15863        int[] origUsers;
15864        // The set of users that now have this package installed.
15865        int[] newUsers;
15866        PackageParser.Package pkg;
15867        int returnCode;
15868        String returnMsg;
15869        String installerPackageName;
15870        PackageRemovedInfo removedInfo;
15871        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15872
15873        public void setError(int code, String msg) {
15874            setReturnCode(code);
15875            setReturnMessage(msg);
15876            Slog.w(TAG, msg);
15877        }
15878
15879        public void setError(String msg, PackageParserException e) {
15880            setReturnCode(e.error);
15881            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15882            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15883            for (int i = 0; i < childCount; i++) {
15884                addedChildPackages.valueAt(i).setError(msg, e);
15885            }
15886            Slog.w(TAG, msg, e);
15887        }
15888
15889        public void setError(String msg, PackageManagerException e) {
15890            returnCode = e.error;
15891            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15892            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15893            for (int i = 0; i < childCount; i++) {
15894                addedChildPackages.valueAt(i).setError(msg, e);
15895            }
15896            Slog.w(TAG, msg, e);
15897        }
15898
15899        public void setReturnCode(int returnCode) {
15900            this.returnCode = returnCode;
15901            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15902            for (int i = 0; i < childCount; i++) {
15903                addedChildPackages.valueAt(i).returnCode = returnCode;
15904            }
15905        }
15906
15907        private void setReturnMessage(String returnMsg) {
15908            this.returnMsg = returnMsg;
15909            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15910            for (int i = 0; i < childCount; i++) {
15911                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15912            }
15913        }
15914
15915        // In some error cases we want to convey more info back to the observer
15916        String origPackage;
15917        String origPermission;
15918    }
15919
15920    /*
15921     * Install a non-existing package.
15922     */
15923    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15924            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15925            String volumeUuid, PackageInstalledInfo res, int installReason) {
15926        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15927
15928        // Remember this for later, in case we need to rollback this install
15929        String pkgName = pkg.packageName;
15930
15931        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15932
15933        synchronized(mPackages) {
15934            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15935            if (renamedPackage != null) {
15936                // A package with the same name is already installed, though
15937                // it has been renamed to an older name.  The package we
15938                // are trying to install should be installed as an update to
15939                // the existing one, but that has not been requested, so bail.
15940                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15941                        + " without first uninstalling package running as "
15942                        + renamedPackage);
15943                return;
15944            }
15945            if (mPackages.containsKey(pkgName)) {
15946                // Don't allow installation over an existing package with the same name.
15947                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15948                        + " without first uninstalling.");
15949                return;
15950            }
15951        }
15952
15953        try {
15954            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15955                    System.currentTimeMillis(), user);
15956
15957            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15958
15959            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15960                prepareAppDataAfterInstallLIF(newPackage);
15961
15962            } else {
15963                // Remove package from internal structures, but keep around any
15964                // data that might have already existed
15965                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15966                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15967            }
15968        } catch (PackageManagerException e) {
15969            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15970        }
15971
15972        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15973    }
15974
15975    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15976        try (DigestInputStream digestStream =
15977                new DigestInputStream(new FileInputStream(file), digest)) {
15978            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15979        }
15980    }
15981
15982    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15983            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15984            PackageInstalledInfo res, int installReason) {
15985        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15986
15987        final PackageParser.Package oldPackage;
15988        final PackageSetting ps;
15989        final String pkgName = pkg.packageName;
15990        final int[] allUsers;
15991        final int[] installedUsers;
15992
15993        synchronized(mPackages) {
15994            oldPackage = mPackages.get(pkgName);
15995            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15996
15997            // don't allow upgrade to target a release SDK from a pre-release SDK
15998            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15999                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16000            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16001                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16002            if (oldTargetsPreRelease
16003                    && !newTargetsPreRelease
16004                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16005                Slog.w(TAG, "Can't install package targeting released sdk");
16006                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16007                return;
16008            }
16009
16010            ps = mSettings.mPackages.get(pkgName);
16011
16012            // verify signatures are valid
16013            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16014            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16015                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
16016                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16017                            "New package not signed by keys specified by upgrade-keysets: "
16018                                    + pkgName);
16019                    return;
16020                }
16021            } else {
16022
16023                // default to original signature matching
16024                if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
16025                        PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
16026                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16027                            "New package has a different signature: " + pkgName);
16028                    return;
16029                }
16030            }
16031
16032            // don't allow a system upgrade unless the upgrade hash matches
16033            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
16034                byte[] digestBytes = null;
16035                try {
16036                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16037                    updateDigest(digest, new File(pkg.baseCodePath));
16038                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16039                        for (String path : pkg.splitCodePaths) {
16040                            updateDigest(digest, new File(path));
16041                        }
16042                    }
16043                    digestBytes = digest.digest();
16044                } catch (NoSuchAlgorithmException | IOException e) {
16045                    res.setError(INSTALL_FAILED_INVALID_APK,
16046                            "Could not compute hash: " + pkgName);
16047                    return;
16048                }
16049                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16050                    res.setError(INSTALL_FAILED_INVALID_APK,
16051                            "New package fails restrict-update check: " + pkgName);
16052                    return;
16053                }
16054                // retain upgrade restriction
16055                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16056            }
16057
16058            // Check for shared user id changes
16059            String invalidPackageName =
16060                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16061            if (invalidPackageName != null) {
16062                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16063                        "Package " + invalidPackageName + " tried to change user "
16064                                + oldPackage.mSharedUserId);
16065                return;
16066            }
16067
16068            // check if the new package supports all of the abis which the old package supports
16069            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
16070            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
16071            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
16072                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16073                        "Update to package " + pkgName + " doesn't support multi arch");
16074                return;
16075            }
16076
16077            // In case of rollback, remember per-user/profile install state
16078            allUsers = sUserManager.getUserIds();
16079            installedUsers = ps.queryInstalledUsers(allUsers, true);
16080
16081            // don't allow an upgrade from full to ephemeral
16082            if (isInstantApp) {
16083                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16084                    for (int currentUser : allUsers) {
16085                        if (!ps.getInstantApp(currentUser)) {
16086                            // can't downgrade from full to instant
16087                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16088                                    + " for user: " + currentUser);
16089                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16090                            return;
16091                        }
16092                    }
16093                } else if (!ps.getInstantApp(user.getIdentifier())) {
16094                    // can't downgrade from full to instant
16095                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16096                            + " for user: " + user.getIdentifier());
16097                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16098                    return;
16099                }
16100            }
16101        }
16102
16103        // Update what is removed
16104        res.removedInfo = new PackageRemovedInfo(this);
16105        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16106        res.removedInfo.removedPackage = oldPackage.packageName;
16107        res.removedInfo.installerPackageName = ps.installerPackageName;
16108        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16109        res.removedInfo.isUpdate = true;
16110        res.removedInfo.origUsers = installedUsers;
16111        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16112        for (int i = 0; i < installedUsers.length; i++) {
16113            final int userId = installedUsers[i];
16114            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16115        }
16116
16117        final int childCount = (oldPackage.childPackages != null)
16118                ? oldPackage.childPackages.size() : 0;
16119        for (int i = 0; i < childCount; i++) {
16120            boolean childPackageUpdated = false;
16121            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16122            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16123            if (res.addedChildPackages != null) {
16124                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16125                if (childRes != null) {
16126                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16127                    childRes.removedInfo.removedPackage = childPkg.packageName;
16128                    if (childPs != null) {
16129                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16130                    }
16131                    childRes.removedInfo.isUpdate = true;
16132                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16133                    childPackageUpdated = true;
16134                }
16135            }
16136            if (!childPackageUpdated) {
16137                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16138                childRemovedRes.removedPackage = childPkg.packageName;
16139                if (childPs != null) {
16140                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16141                }
16142                childRemovedRes.isUpdate = false;
16143                childRemovedRes.dataRemoved = true;
16144                synchronized (mPackages) {
16145                    if (childPs != null) {
16146                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16147                    }
16148                }
16149                if (res.removedInfo.removedChildPackages == null) {
16150                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16151                }
16152                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16153            }
16154        }
16155
16156        boolean sysPkg = (isSystemApp(oldPackage));
16157        if (sysPkg) {
16158            // Set the system/privileged/oem/vendor/product flags as needed
16159            final boolean privileged =
16160                    (oldPackage.applicationInfo.privateFlags
16161                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16162            final boolean oem =
16163                    (oldPackage.applicationInfo.privateFlags
16164                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16165            final boolean vendor =
16166                    (oldPackage.applicationInfo.privateFlags
16167                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16168            final boolean product =
16169                    (oldPackage.applicationInfo.privateFlags
16170                            & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
16171            final @ParseFlags int systemParseFlags = parseFlags;
16172            final @ScanFlags int systemScanFlags = scanFlags
16173                    | SCAN_AS_SYSTEM
16174                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
16175                    | (oem ? SCAN_AS_OEM : 0)
16176                    | (vendor ? SCAN_AS_VENDOR : 0)
16177                    | (product ? SCAN_AS_PRODUCT : 0);
16178
16179            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
16180                    user, allUsers, installerPackageName, res, installReason);
16181        } else {
16182            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
16183                    user, allUsers, installerPackageName, res, installReason);
16184        }
16185    }
16186
16187    @Override
16188    public List<String> getPreviousCodePaths(String packageName) {
16189        final int callingUid = Binder.getCallingUid();
16190        final List<String> result = new ArrayList<>();
16191        if (getInstantAppPackageName(callingUid) != null) {
16192            return result;
16193        }
16194        final PackageSetting ps = mSettings.mPackages.get(packageName);
16195        if (ps != null
16196                && ps.oldCodePaths != null
16197                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
16198            result.addAll(ps.oldCodePaths);
16199        }
16200        return result;
16201    }
16202
16203    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16204            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16205            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
16206            String installerPackageName, PackageInstalledInfo res, int installReason) {
16207        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16208                + deletedPackage);
16209
16210        String pkgName = deletedPackage.packageName;
16211        boolean deletedPkg = true;
16212        boolean addedPkg = false;
16213        boolean updatedSettings = false;
16214        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16215        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16216                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16217
16218        final long origUpdateTime = (pkg.mExtras != null)
16219                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16220
16221        // First delete the existing package while retaining the data directory
16222        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16223                res.removedInfo, true, pkg)) {
16224            // If the existing package wasn't successfully deleted
16225            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16226            deletedPkg = false;
16227        } else {
16228            // Successfully deleted the old package; proceed with replace.
16229
16230            // If deleted package lived in a container, give users a chance to
16231            // relinquish resources before killing.
16232            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16233                if (DEBUG_INSTALL) {
16234                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16235                }
16236                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16237                final ArrayList<String> pkgList = new ArrayList<String>(1);
16238                pkgList.add(deletedPackage.applicationInfo.packageName);
16239                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16240            }
16241
16242            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16243                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16244
16245            try {
16246                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16247                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16248                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16249                        installReason);
16250
16251                // Update the in-memory copy of the previous code paths.
16252                PackageSetting ps = mSettings.mPackages.get(pkgName);
16253                if (!killApp) {
16254                    if (ps.oldCodePaths == null) {
16255                        ps.oldCodePaths = new ArraySet<>();
16256                    }
16257                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16258                    if (deletedPackage.splitCodePaths != null) {
16259                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16260                    }
16261                } else {
16262                    ps.oldCodePaths = null;
16263                }
16264                if (ps.childPackageNames != null) {
16265                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16266                        final String childPkgName = ps.childPackageNames.get(i);
16267                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16268                        childPs.oldCodePaths = ps.oldCodePaths;
16269                    }
16270                }
16271                // set instant app status, but, only if it's explicitly specified
16272                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16273                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16274                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16275                prepareAppDataAfterInstallLIF(newPackage);
16276                addedPkg = true;
16277                mDexManager.notifyPackageUpdated(newPackage.packageName,
16278                        newPackage.baseCodePath, newPackage.splitCodePaths);
16279            } catch (PackageManagerException e) {
16280                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16281            }
16282        }
16283
16284        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16285            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16286
16287            // Revert all internal state mutations and added folders for the failed install
16288            if (addedPkg) {
16289                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16290                        res.removedInfo, true, null);
16291            }
16292
16293            // Restore the old package
16294            if (deletedPkg) {
16295                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16296                File restoreFile = new File(deletedPackage.codePath);
16297                // Parse old package
16298                boolean oldExternal = isExternal(deletedPackage);
16299                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16300                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16301                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16302                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16303                try {
16304                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16305                            null);
16306                } catch (PackageManagerException e) {
16307                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16308                            + e.getMessage());
16309                    return;
16310                }
16311
16312                synchronized (mPackages) {
16313                    // Ensure the installer package name up to date
16314                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16315
16316                    // Update permissions for restored package
16317                    mPermissionManager.updatePermissions(
16318                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16319                            mPermissionCallback);
16320
16321                    mSettings.writeLPr();
16322                }
16323
16324                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16325            }
16326        } else {
16327            synchronized (mPackages) {
16328                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16329                if (ps != null) {
16330                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16331                    if (res.removedInfo.removedChildPackages != null) {
16332                        final int childCount = res.removedInfo.removedChildPackages.size();
16333                        // Iterate in reverse as we may modify the collection
16334                        for (int i = childCount - 1; i >= 0; i--) {
16335                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16336                            if (res.addedChildPackages.containsKey(childPackageName)) {
16337                                res.removedInfo.removedChildPackages.removeAt(i);
16338                            } else {
16339                                PackageRemovedInfo childInfo = res.removedInfo
16340                                        .removedChildPackages.valueAt(i);
16341                                childInfo.removedForAllUsers = mPackages.get(
16342                                        childInfo.removedPackage) == null;
16343                            }
16344                        }
16345                    }
16346                }
16347            }
16348        }
16349    }
16350
16351    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16352            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16353            final @ScanFlags int scanFlags, UserHandle user,
16354            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16355            int installReason) {
16356        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16357                + ", old=" + deletedPackage);
16358
16359        final boolean disabledSystem;
16360
16361        // Remove existing system package
16362        removePackageLI(deletedPackage, true);
16363
16364        synchronized (mPackages) {
16365            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16366        }
16367        if (!disabledSystem) {
16368            // We didn't need to disable the .apk as a current system package,
16369            // which means we are replacing another update that is already
16370            // installed.  We need to make sure to delete the older one's .apk.
16371            res.removedInfo.args = createInstallArgsForExisting(0,
16372                    deletedPackage.applicationInfo.getCodePath(),
16373                    deletedPackage.applicationInfo.getResourcePath(),
16374                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16375        } else {
16376            res.removedInfo.args = null;
16377        }
16378
16379        // Successfully disabled the old package. Now proceed with re-installation
16380        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16381                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16382
16383        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16384        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16385                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16386
16387        PackageParser.Package newPackage = null;
16388        try {
16389            // Add the package to the internal data structures
16390            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16391
16392            // Set the update and install times
16393            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16394            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16395                    System.currentTimeMillis());
16396
16397            // Update the package dynamic state if succeeded
16398            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16399                // Now that the install succeeded make sure we remove data
16400                // directories for any child package the update removed.
16401                final int deletedChildCount = (deletedPackage.childPackages != null)
16402                        ? deletedPackage.childPackages.size() : 0;
16403                final int newChildCount = (newPackage.childPackages != null)
16404                        ? newPackage.childPackages.size() : 0;
16405                for (int i = 0; i < deletedChildCount; i++) {
16406                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16407                    boolean childPackageDeleted = true;
16408                    for (int j = 0; j < newChildCount; j++) {
16409                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16410                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16411                            childPackageDeleted = false;
16412                            break;
16413                        }
16414                    }
16415                    if (childPackageDeleted) {
16416                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16417                                deletedChildPkg.packageName);
16418                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16419                            PackageRemovedInfo removedChildRes = res.removedInfo
16420                                    .removedChildPackages.get(deletedChildPkg.packageName);
16421                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16422                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16423                        }
16424                    }
16425                }
16426
16427                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16428                        installReason);
16429                prepareAppDataAfterInstallLIF(newPackage);
16430
16431                mDexManager.notifyPackageUpdated(newPackage.packageName,
16432                            newPackage.baseCodePath, newPackage.splitCodePaths);
16433            }
16434        } catch (PackageManagerException e) {
16435            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16436            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16437        }
16438
16439        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16440            // Re installation failed. Restore old information
16441            // Remove new pkg information
16442            if (newPackage != null) {
16443                removeInstalledPackageLI(newPackage, true);
16444            }
16445            // Add back the old system package
16446            try {
16447                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16448            } catch (PackageManagerException e) {
16449                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16450            }
16451
16452            synchronized (mPackages) {
16453                if (disabledSystem) {
16454                    enableSystemPackageLPw(deletedPackage);
16455                }
16456
16457                // Ensure the installer package name up to date
16458                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16459
16460                // Update permissions for restored package
16461                mPermissionManager.updatePermissions(
16462                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16463                        mPermissionCallback);
16464
16465                mSettings.writeLPr();
16466            }
16467
16468            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16469                    + " after failed upgrade");
16470        }
16471    }
16472
16473    /**
16474     * Checks whether the parent or any of the child packages have a change shared
16475     * user. For a package to be a valid update the shred users of the parent and
16476     * the children should match. We may later support changing child shared users.
16477     * @param oldPkg The updated package.
16478     * @param newPkg The update package.
16479     * @return The shared user that change between the versions.
16480     */
16481    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16482            PackageParser.Package newPkg) {
16483        // Check parent shared user
16484        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16485            return newPkg.packageName;
16486        }
16487        // Check child shared users
16488        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16489        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16490        for (int i = 0; i < newChildCount; i++) {
16491            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16492            // If this child was present, did it have the same shared user?
16493            for (int j = 0; j < oldChildCount; j++) {
16494                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16495                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16496                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16497                    return newChildPkg.packageName;
16498                }
16499            }
16500        }
16501        return null;
16502    }
16503
16504    private void removeNativeBinariesLI(PackageSetting ps) {
16505        // Remove the lib path for the parent package
16506        if (ps != null) {
16507            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16508            // Remove the lib path for the child packages
16509            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16510            for (int i = 0; i < childCount; i++) {
16511                PackageSetting childPs = null;
16512                synchronized (mPackages) {
16513                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16514                }
16515                if (childPs != null) {
16516                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16517                            .legacyNativeLibraryPathString);
16518                }
16519            }
16520        }
16521    }
16522
16523    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16524        // Enable the parent package
16525        mSettings.enableSystemPackageLPw(pkg.packageName);
16526        // Enable the child packages
16527        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16528        for (int i = 0; i < childCount; i++) {
16529            PackageParser.Package childPkg = pkg.childPackages.get(i);
16530            mSettings.enableSystemPackageLPw(childPkg.packageName);
16531        }
16532    }
16533
16534    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16535            PackageParser.Package newPkg) {
16536        // Disable the parent package (parent always replaced)
16537        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16538        // Disable the child packages
16539        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16540        for (int i = 0; i < childCount; i++) {
16541            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16542            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16543            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16544        }
16545        return disabled;
16546    }
16547
16548    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16549            String installerPackageName) {
16550        // Enable the parent package
16551        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16552        // Enable the child packages
16553        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16554        for (int i = 0; i < childCount; i++) {
16555            PackageParser.Package childPkg = pkg.childPackages.get(i);
16556            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16557        }
16558    }
16559
16560    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16561            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16562        // Update the parent package setting
16563        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16564                res, user, installReason);
16565        // Update the child packages setting
16566        final int childCount = (newPackage.childPackages != null)
16567                ? newPackage.childPackages.size() : 0;
16568        for (int i = 0; i < childCount; i++) {
16569            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16570            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16571            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16572                    childRes.origUsers, childRes, user, installReason);
16573        }
16574    }
16575
16576    private void updateSettingsInternalLI(PackageParser.Package pkg,
16577            String installerPackageName, int[] allUsers, int[] installedForUsers,
16578            PackageInstalledInfo res, UserHandle user, int installReason) {
16579        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16580
16581        final String pkgName = pkg.packageName;
16582
16583        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16584        synchronized (mPackages) {
16585// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16586            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16587                    mPermissionCallback);
16588            // For system-bundled packages, we assume that installing an upgraded version
16589            // of the package implies that the user actually wants to run that new code,
16590            // so we enable the package.
16591            PackageSetting ps = mSettings.mPackages.get(pkgName);
16592            final int userId = user.getIdentifier();
16593            if (ps != null) {
16594                if (isSystemApp(pkg)) {
16595                    if (DEBUG_INSTALL) {
16596                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16597                    }
16598                    // Enable system package for requested users
16599                    if (res.origUsers != null) {
16600                        for (int origUserId : res.origUsers) {
16601                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16602                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16603                                        origUserId, installerPackageName);
16604                            }
16605                        }
16606                    }
16607                    // Also convey the prior install/uninstall state
16608                    if (allUsers != null && installedForUsers != null) {
16609                        for (int currentUserId : allUsers) {
16610                            final boolean installed = ArrayUtils.contains(
16611                                    installedForUsers, currentUserId);
16612                            if (DEBUG_INSTALL) {
16613                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16614                            }
16615                            ps.setInstalled(installed, currentUserId);
16616                        }
16617                        // these install state changes will be persisted in the
16618                        // upcoming call to mSettings.writeLPr().
16619                    }
16620                }
16621                // It's implied that when a user requests installation, they want the app to be
16622                // installed and enabled.
16623                if (userId != UserHandle.USER_ALL) {
16624                    ps.setInstalled(true, userId);
16625                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16626                } else {
16627                    for (int currentUserId : sUserManager.getUserIds()) {
16628                        ps.setInstalled(true, currentUserId);
16629                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
16630                                installerPackageName);
16631                    }
16632                }
16633
16634                // When replacing an existing package, preserve the original install reason for all
16635                // users that had the package installed before.
16636                final Set<Integer> previousUserIds = new ArraySet<>();
16637                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16638                    final int installReasonCount = res.removedInfo.installReasons.size();
16639                    for (int i = 0; i < installReasonCount; i++) {
16640                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16641                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16642                        ps.setInstallReason(previousInstallReason, previousUserId);
16643                        previousUserIds.add(previousUserId);
16644                    }
16645                }
16646
16647                // Set install reason for users that are having the package newly installed.
16648                if (userId == UserHandle.USER_ALL) {
16649                    for (int currentUserId : sUserManager.getUserIds()) {
16650                        if (!previousUserIds.contains(currentUserId)) {
16651                            ps.setInstallReason(installReason, currentUserId);
16652                        }
16653                    }
16654                } else if (!previousUserIds.contains(userId)) {
16655                    ps.setInstallReason(installReason, userId);
16656                }
16657                mSettings.writeKernelMappingLPr(ps);
16658            }
16659            res.name = pkgName;
16660            res.uid = pkg.applicationInfo.uid;
16661            res.pkg = pkg;
16662            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16663            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16664            //to update install status
16665            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16666            mSettings.writeLPr();
16667            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16668        }
16669
16670        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16671    }
16672
16673    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16674        try {
16675            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16676            installPackageLI(args, res);
16677        } finally {
16678            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16679        }
16680    }
16681
16682    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16683        final int installFlags = args.installFlags;
16684        final String installerPackageName = args.installerPackageName;
16685        final String volumeUuid = args.volumeUuid;
16686        final File tmpPackageFile = new File(args.getCodePath());
16687        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16688        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16689                || (args.volumeUuid != null));
16690        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16691        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16692        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16693        final boolean virtualPreload =
16694                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16695        boolean replace = false;
16696        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16697        if (args.move != null) {
16698            // moving a complete application; perform an initial scan on the new install location
16699            scanFlags |= SCAN_INITIAL;
16700        }
16701        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16702            scanFlags |= SCAN_DONT_KILL_APP;
16703        }
16704        if (instantApp) {
16705            scanFlags |= SCAN_AS_INSTANT_APP;
16706        }
16707        if (fullApp) {
16708            scanFlags |= SCAN_AS_FULL_APP;
16709        }
16710        if (virtualPreload) {
16711            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16712        }
16713
16714        // Result object to be returned
16715        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16716        res.installerPackageName = installerPackageName;
16717
16718        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16719
16720        // Sanity check
16721        if (instantApp && (forwardLocked || onExternal)) {
16722            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16723                    + " external=" + onExternal);
16724            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16725            return;
16726        }
16727
16728        // Retrieve PackageSettings and parse package
16729        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16730                | PackageParser.PARSE_ENFORCE_CODE
16731                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16732                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16733                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16734        PackageParser pp = new PackageParser();
16735        pp.setSeparateProcesses(mSeparateProcesses);
16736        pp.setDisplayMetrics(mMetrics);
16737        pp.setCallback(mPackageParserCallback);
16738
16739        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16740        final PackageParser.Package pkg;
16741        try {
16742            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16743            DexMetadataHelper.validatePackageDexMetadata(pkg);
16744        } catch (PackageParserException e) {
16745            res.setError("Failed parse during installPackageLI", e);
16746            return;
16747        } finally {
16748            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16749        }
16750
16751        // Instant apps have several additional install-time checks.
16752        if (instantApp) {
16753            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
16754                Slog.w(TAG,
16755                        "Instant app package " + pkg.packageName + " does not target at least O");
16756                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16757                        "Instant app package must target at least O");
16758                return;
16759            }
16760            if (pkg.applicationInfo.targetSandboxVersion != 2) {
16761                Slog.w(TAG, "Instant app package " + pkg.packageName
16762                        + " does not target targetSandboxVersion 2");
16763                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16764                        "Instant app package must use targetSandboxVersion 2");
16765                return;
16766            }
16767            if (pkg.mSharedUserId != null) {
16768                Slog.w(TAG, "Instant app package " + pkg.packageName
16769                        + " may not declare sharedUserId.");
16770                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16771                        "Instant app package may not declare a sharedUserId");
16772                return;
16773            }
16774        }
16775
16776        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16777            // Static shared libraries have synthetic package names
16778            renameStaticSharedLibraryPackage(pkg);
16779
16780            // No static shared libs on external storage
16781            if (onExternal) {
16782                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16783                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16784                        "Packages declaring static-shared libs cannot be updated");
16785                return;
16786            }
16787        }
16788
16789        // If we are installing a clustered package add results for the children
16790        if (pkg.childPackages != null) {
16791            synchronized (mPackages) {
16792                final int childCount = pkg.childPackages.size();
16793                for (int i = 0; i < childCount; i++) {
16794                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16795                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16796                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16797                    childRes.pkg = childPkg;
16798                    childRes.name = childPkg.packageName;
16799                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16800                    if (childPs != null) {
16801                        childRes.origUsers = childPs.queryInstalledUsers(
16802                                sUserManager.getUserIds(), true);
16803                    }
16804                    if ((mPackages.containsKey(childPkg.packageName))) {
16805                        childRes.removedInfo = new PackageRemovedInfo(this);
16806                        childRes.removedInfo.removedPackage = childPkg.packageName;
16807                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16808                    }
16809                    if (res.addedChildPackages == null) {
16810                        res.addedChildPackages = new ArrayMap<>();
16811                    }
16812                    res.addedChildPackages.put(childPkg.packageName, childRes);
16813                }
16814            }
16815        }
16816
16817        // If package doesn't declare API override, mark that we have an install
16818        // time CPU ABI override.
16819        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16820            pkg.cpuAbiOverride = args.abiOverride;
16821        }
16822
16823        String pkgName = res.name = pkg.packageName;
16824        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16825            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16826                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16827                return;
16828            }
16829        }
16830
16831        try {
16832            // either use what we've been given or parse directly from the APK
16833            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16834                pkg.setSigningDetails(args.signingDetails);
16835            } else {
16836                PackageParser.collectCertificates(pkg, false /* skipVerify */);
16837            }
16838        } catch (PackageParserException e) {
16839            res.setError("Failed collect during installPackageLI", e);
16840            return;
16841        }
16842
16843        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
16844                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16845            Slog.w(TAG, "Instant app package " + pkg.packageName
16846                    + " is not signed with at least APK Signature Scheme v2");
16847            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16848                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
16849            return;
16850        }
16851
16852        // Get rid of all references to package scan path via parser.
16853        pp = null;
16854        String oldCodePath = null;
16855        boolean systemApp = false;
16856        synchronized (mPackages) {
16857            // Check if installing already existing package
16858            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16859                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16860                if (pkg.mOriginalPackages != null
16861                        && pkg.mOriginalPackages.contains(oldName)
16862                        && mPackages.containsKey(oldName)) {
16863                    // This package is derived from an original package,
16864                    // and this device has been updating from that original
16865                    // name.  We must continue using the original name, so
16866                    // rename the new package here.
16867                    pkg.setPackageName(oldName);
16868                    pkgName = pkg.packageName;
16869                    replace = true;
16870                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16871                            + oldName + " pkgName=" + pkgName);
16872                } else if (mPackages.containsKey(pkgName)) {
16873                    // This package, under its official name, already exists
16874                    // on the device; we should replace it.
16875                    replace = true;
16876                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16877                }
16878
16879                // Child packages are installed through the parent package
16880                if (pkg.parentPackage != null) {
16881                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16882                            "Package " + pkg.packageName + " is child of package "
16883                                    + pkg.parentPackage.parentPackage + ". Child packages "
16884                                    + "can be updated only through the parent package.");
16885                    return;
16886                }
16887
16888                if (replace) {
16889                    // Prevent apps opting out from runtime permissions
16890                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16891                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16892                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16893                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16894                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16895                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16896                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16897                                        + " doesn't support runtime permissions but the old"
16898                                        + " target SDK " + oldTargetSdk + " does.");
16899                        return;
16900                    }
16901                    // Prevent persistent apps from being updated
16902                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16903                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16904                                "Package " + oldPackage.packageName + " is a persistent app. "
16905                                        + "Persistent apps are not updateable.");
16906                        return;
16907                    }
16908                    // Prevent apps from downgrading their targetSandbox.
16909                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16910                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16911                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16912                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16913                                "Package " + pkg.packageName + " new target sandbox "
16914                                + newTargetSandbox + " is incompatible with the previous value of"
16915                                + oldTargetSandbox + ".");
16916                        return;
16917                    }
16918
16919                    // Prevent installing of child packages
16920                    if (oldPackage.parentPackage != null) {
16921                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16922                                "Package " + pkg.packageName + " is child of package "
16923                                        + oldPackage.parentPackage + ". Child packages "
16924                                        + "can be updated only through the parent package.");
16925                        return;
16926                    }
16927                }
16928            }
16929
16930            PackageSetting ps = mSettings.mPackages.get(pkgName);
16931            if (ps != null) {
16932                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16933
16934                // Static shared libs have same package with different versions where
16935                // we internally use a synthetic package name to allow multiple versions
16936                // of the same package, therefore we need to compare signatures against
16937                // the package setting for the latest library version.
16938                PackageSetting signatureCheckPs = ps;
16939                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16940                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16941                    if (libraryEntry != null) {
16942                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16943                    }
16944                }
16945
16946                // Quick sanity check that we're signed correctly if updating;
16947                // we'll check this again later when scanning, but we want to
16948                // bail early here before tripping over redefined permissions.
16949                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16950                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16951                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16952                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16953                                + pkg.packageName + " upgrade keys do not match the "
16954                                + "previously installed version");
16955                        return;
16956                    }
16957                } else {
16958                    try {
16959                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16960                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16961                        // We don't care about disabledPkgSetting on install for now.
16962                        final boolean compatMatch = verifySignatures(
16963                                signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
16964                                compareRecover);
16965                        // The new KeySets will be re-added later in the scanning process.
16966                        if (compatMatch) {
16967                            synchronized (mPackages) {
16968                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16969                            }
16970                        }
16971                    } catch (PackageManagerException e) {
16972                        res.setError(e.error, e.getMessage());
16973                        return;
16974                    }
16975                }
16976
16977                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16978                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16979                    systemApp = (ps.pkg.applicationInfo.flags &
16980                            ApplicationInfo.FLAG_SYSTEM) != 0;
16981                }
16982                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16983            }
16984
16985            int N = pkg.permissions.size();
16986            for (int i = N-1; i >= 0; i--) {
16987                final PackageParser.Permission perm = pkg.permissions.get(i);
16988                final BasePermission bp =
16989                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
16990
16991                // Don't allow anyone but the system to define ephemeral permissions.
16992                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16993                        && !systemApp) {
16994                    Slog.w(TAG, "Non-System package " + pkg.packageName
16995                            + " attempting to delcare ephemeral permission "
16996                            + perm.info.name + "; Removing ephemeral.");
16997                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
16998                }
16999
17000                // Check whether the newly-scanned package wants to define an already-defined perm
17001                if (bp != null) {
17002                    // If the defining package is signed with our cert, it's okay.  This
17003                    // also includes the "updating the same package" case, of course.
17004                    // "updating same package" could also involve key-rotation.
17005                    final boolean sigsOk;
17006                    final String sourcePackageName = bp.getSourcePackageName();
17007                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17008                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17009                    if (sourcePackageName.equals(pkg.packageName)
17010                            && (ksms.shouldCheckUpgradeKeySetLocked(
17011                                    sourcePackageSetting, scanFlags))) {
17012                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17013                    } else {
17014
17015                        // in the event of signing certificate rotation, we need to see if the
17016                        // package's certificate has rotated from the current one, or if it is an
17017                        // older certificate with which the current is ok with sharing permissions
17018                        if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17019                                        pkg.mSigningDetails,
17020                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17021                            sigsOk = true;
17022                        } else if (pkg.mSigningDetails.checkCapability(
17023                                        sourcePackageSetting.signatures.mSigningDetails,
17024                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17025
17026                            // the scanned package checks out, has signing certificate rotation
17027                            // history, and is newer; bring it over
17028                            sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17029                            sigsOk = true;
17030                        } else {
17031                            sigsOk = false;
17032                        }
17033                    }
17034                    if (!sigsOk) {
17035                        // If the owning package is the system itself, we log but allow
17036                        // install to proceed; we fail the install on all other permission
17037                        // redefinitions.
17038                        if (!sourcePackageName.equals("android")) {
17039                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17040                                    + pkg.packageName + " attempting to redeclare permission "
17041                                    + perm.info.name + " already owned by " + sourcePackageName);
17042                            res.origPermission = perm.info.name;
17043                            res.origPackage = sourcePackageName;
17044                            return;
17045                        } else {
17046                            Slog.w(TAG, "Package " + pkg.packageName
17047                                    + " attempting to redeclare system permission "
17048                                    + perm.info.name + "; ignoring new declaration");
17049                            pkg.permissions.remove(i);
17050                        }
17051                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17052                        // Prevent apps to change protection level to dangerous from any other
17053                        // type as this would allow a privilege escalation where an app adds a
17054                        // normal/signature permission in other app's group and later redefines
17055                        // it as dangerous leading to the group auto-grant.
17056                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17057                                == PermissionInfo.PROTECTION_DANGEROUS) {
17058                            if (bp != null && !bp.isRuntime()) {
17059                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17060                                        + "non-runtime permission " + perm.info.name
17061                                        + " to runtime; keeping old protection level");
17062                                perm.info.protectionLevel = bp.getProtectionLevel();
17063                            }
17064                        }
17065                    }
17066                }
17067            }
17068        }
17069
17070        if (systemApp) {
17071            if (onExternal) {
17072                // Abort update; system app can't be replaced with app on sdcard
17073                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17074                        "Cannot install updates to system apps on sdcard");
17075                return;
17076            } else if (instantApp) {
17077                // Abort update; system app can't be replaced with an instant app
17078                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17079                        "Cannot update a system app with an instant app");
17080                return;
17081            }
17082        }
17083
17084        if (args.move != null) {
17085            // We did an in-place move, so dex is ready to roll
17086            scanFlags |= SCAN_NO_DEX;
17087            scanFlags |= SCAN_MOVE;
17088
17089            synchronized (mPackages) {
17090                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17091                if (ps == null) {
17092                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17093                            "Missing settings for moved package " + pkgName);
17094                }
17095
17096                // We moved the entire application as-is, so bring over the
17097                // previously derived ABI information.
17098                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17099                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17100            }
17101
17102        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17103            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17104            scanFlags |= SCAN_NO_DEX;
17105
17106            try {
17107                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17108                    args.abiOverride : pkg.cpuAbiOverride);
17109                final boolean extractNativeLibs = !pkg.isLibrary();
17110                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17111            } catch (PackageManagerException pme) {
17112                Slog.e(TAG, "Error deriving application ABI", pme);
17113                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17114                return;
17115            }
17116
17117            // Shared libraries for the package need to be updated.
17118            synchronized (mPackages) {
17119                try {
17120                    updateSharedLibrariesLPr(pkg, null);
17121                } catch (PackageManagerException e) {
17122                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17123                }
17124            }
17125        }
17126
17127        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17128            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17129            return;
17130        }
17131
17132        if (PackageManagerServiceUtils.isApkVerityEnabled()) {
17133            String apkPath = null;
17134            synchronized (mPackages) {
17135                // Note that if the attacker managed to skip verify setup, for example by tampering
17136                // with the package settings, upon reboot we will do full apk verification when
17137                // verity is not detected.
17138                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17139                if (ps != null && ps.isPrivileged()) {
17140                    apkPath = pkg.baseCodePath;
17141                }
17142            }
17143
17144            if (apkPath != null) {
17145                final VerityUtils.SetupResult result =
17146                        VerityUtils.generateApkVeritySetupData(apkPath);
17147                if (result.isOk()) {
17148                    if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
17149                    FileDescriptor fd = result.getUnownedFileDescriptor();
17150                    try {
17151                        mInstaller.installApkVerity(apkPath, fd);
17152                    } catch (InstallerException e) {
17153                        res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17154                                "Failed to set up verity: " + e);
17155                        return;
17156                    } finally {
17157                        IoUtils.closeQuietly(fd);
17158                    }
17159                } else if (result.isFailed()) {
17160                    res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Failed to generate verity");
17161                    return;
17162                } else {
17163                    // Do nothing if verity is skipped. Will fall back to full apk verification on
17164                    // reboot.
17165                }
17166            }
17167        }
17168
17169        if (!instantApp) {
17170            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17171        } else {
17172            if (DEBUG_DOMAIN_VERIFICATION) {
17173                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17174            }
17175        }
17176
17177        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17178                "installPackageLI")) {
17179            if (replace) {
17180                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17181                    // Static libs have a synthetic package name containing the version
17182                    // and cannot be updated as an update would get a new package name,
17183                    // unless this is the exact same version code which is useful for
17184                    // development.
17185                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17186                    if (existingPkg != null &&
17187                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17188                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17189                                + "static-shared libs cannot be updated");
17190                        return;
17191                    }
17192                }
17193                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
17194                        installerPackageName, res, args.installReason);
17195            } else {
17196                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17197                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17198            }
17199        }
17200
17201        // Prepare the application profiles for the new code paths.
17202        // This needs to be done before invoking dexopt so that any install-time profile
17203        // can be used for optimizations.
17204        mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
17205
17206        // Check whether we need to dexopt the app.
17207        //
17208        // NOTE: it is IMPORTANT to call dexopt:
17209        //   - after doRename which will sync the package data from PackageParser.Package and its
17210        //     corresponding ApplicationInfo.
17211        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
17212        //     uid of the application (pkg.applicationInfo.uid).
17213        //     This update happens in place!
17214        //
17215        // We only need to dexopt if the package meets ALL of the following conditions:
17216        //   1) it is not forward locked.
17217        //   2) it is not on on an external ASEC container.
17218        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
17219        //
17220        // Note that we do not dexopt instant apps by default. dexopt can take some time to
17221        // complete, so we skip this step during installation. Instead, we'll take extra time
17222        // the first time the instant app starts. It's preferred to do it this way to provide
17223        // continuous progress to the useur instead of mysteriously blocking somewhere in the
17224        // middle of running an instant app. The default behaviour can be overridden
17225        // via gservices.
17226        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
17227                && !forwardLocked
17228                && !pkg.applicationInfo.isExternalAsec()
17229                && (!instantApp || Global.getInt(mContext.getContentResolver(),
17230                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
17231
17232        if (performDexopt) {
17233            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17234            // Do not run PackageDexOptimizer through the local performDexOpt
17235            // method because `pkg` may not be in `mPackages` yet.
17236            //
17237            // Also, don't fail application installs if the dexopt step fails.
17238            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
17239                    REASON_INSTALL,
17240                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
17241                    DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17242            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17243                    null /* instructionSets */,
17244                    getOrCreateCompilerPackageStats(pkg),
17245                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
17246                    dexoptOptions);
17247            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17248        }
17249
17250        // Notify BackgroundDexOptService that the package has been changed.
17251        // If this is an update of a package which used to fail to compile,
17252        // BackgroundDexOptService will remove it from its blacklist.
17253        // TODO: Layering violation
17254        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17255
17256        synchronized (mPackages) {
17257            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17258            if (ps != null) {
17259                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17260                ps.setUpdateAvailable(false /*updateAvailable*/);
17261            }
17262
17263            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17264            for (int i = 0; i < childCount; i++) {
17265                PackageParser.Package childPkg = pkg.childPackages.get(i);
17266                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17267                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17268                if (childPs != null) {
17269                    childRes.newUsers = childPs.queryInstalledUsers(
17270                            sUserManager.getUserIds(), true);
17271                }
17272            }
17273
17274            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17275                updateSequenceNumberLP(ps, res.newUsers);
17276                updateInstantAppInstallerLocked(pkgName);
17277            }
17278        }
17279    }
17280
17281    private void startIntentFilterVerifications(int userId, boolean replacing,
17282            PackageParser.Package pkg) {
17283        if (mIntentFilterVerifierComponent == null) {
17284            Slog.w(TAG, "No IntentFilter verification will not be done as "
17285                    + "there is no IntentFilterVerifier available!");
17286            return;
17287        }
17288
17289        final int verifierUid = getPackageUid(
17290                mIntentFilterVerifierComponent.getPackageName(),
17291                MATCH_DEBUG_TRIAGED_MISSING,
17292                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17293
17294        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17295        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17296        mHandler.sendMessage(msg);
17297
17298        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17299        for (int i = 0; i < childCount; i++) {
17300            PackageParser.Package childPkg = pkg.childPackages.get(i);
17301            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17302            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17303            mHandler.sendMessage(msg);
17304        }
17305    }
17306
17307    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17308            PackageParser.Package pkg) {
17309        int size = pkg.activities.size();
17310        if (size == 0) {
17311            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17312                    "No activity, so no need to verify any IntentFilter!");
17313            return;
17314        }
17315
17316        final boolean hasDomainURLs = hasDomainURLs(pkg);
17317        if (!hasDomainURLs) {
17318            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17319                    "No domain URLs, so no need to verify any IntentFilter!");
17320            return;
17321        }
17322
17323        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17324                + " if any IntentFilter from the " + size
17325                + " Activities needs verification ...");
17326
17327        int count = 0;
17328        final String packageName = pkg.packageName;
17329
17330        synchronized (mPackages) {
17331            // If this is a new install and we see that we've already run verification for this
17332            // package, we have nothing to do: it means the state was restored from backup.
17333            if (!replacing) {
17334                IntentFilterVerificationInfo ivi =
17335                        mSettings.getIntentFilterVerificationLPr(packageName);
17336                if (ivi != null) {
17337                    if (DEBUG_DOMAIN_VERIFICATION) {
17338                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17339                                + ivi.getStatusString());
17340                    }
17341                    return;
17342                }
17343            }
17344
17345            // If any filters need to be verified, then all need to be.
17346            boolean needToVerify = false;
17347            for (PackageParser.Activity a : pkg.activities) {
17348                for (ActivityIntentInfo filter : a.intents) {
17349                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17350                        if (DEBUG_DOMAIN_VERIFICATION) {
17351                            Slog.d(TAG,
17352                                    "Intent filter needs verification, so processing all filters");
17353                        }
17354                        needToVerify = true;
17355                        break;
17356                    }
17357                }
17358            }
17359
17360            if (needToVerify) {
17361                final int verificationId = mIntentFilterVerificationToken++;
17362                for (PackageParser.Activity a : pkg.activities) {
17363                    for (ActivityIntentInfo filter : a.intents) {
17364                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17365                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17366                                    "Verification needed for IntentFilter:" + filter.toString());
17367                            mIntentFilterVerifier.addOneIntentFilterVerification(
17368                                    verifierUid, userId, verificationId, filter, packageName);
17369                            count++;
17370                        }
17371                    }
17372                }
17373            }
17374        }
17375
17376        if (count > 0) {
17377            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17378                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17379                    +  " for userId:" + userId);
17380            mIntentFilterVerifier.startVerifications(userId);
17381        } else {
17382            if (DEBUG_DOMAIN_VERIFICATION) {
17383                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17384            }
17385        }
17386    }
17387
17388    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17389        final ComponentName cn  = filter.activity.getComponentName();
17390        final String packageName = cn.getPackageName();
17391
17392        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17393                packageName);
17394        if (ivi == null) {
17395            return true;
17396        }
17397        int status = ivi.getStatus();
17398        switch (status) {
17399            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17400            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17401                return true;
17402
17403            default:
17404                // Nothing to do
17405                return false;
17406        }
17407    }
17408
17409    private static boolean isMultiArch(ApplicationInfo info) {
17410        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17411    }
17412
17413    private static boolean isExternal(PackageParser.Package pkg) {
17414        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17415    }
17416
17417    private static boolean isExternal(PackageSetting ps) {
17418        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17419    }
17420
17421    private static boolean isSystemApp(PackageParser.Package pkg) {
17422        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17423    }
17424
17425    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17426        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17427    }
17428
17429    private static boolean isOemApp(PackageParser.Package pkg) {
17430        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17431    }
17432
17433    private static boolean isVendorApp(PackageParser.Package pkg) {
17434        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17435    }
17436
17437    private static boolean isProductApp(PackageParser.Package pkg) {
17438        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
17439    }
17440
17441    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17442        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17443    }
17444
17445    private static boolean isSystemApp(PackageSetting ps) {
17446        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17447    }
17448
17449    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17450        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17451    }
17452
17453    private int packageFlagsToInstallFlags(PackageSetting ps) {
17454        int installFlags = 0;
17455        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17456            // This existing package was an external ASEC install when we have
17457            // the external flag without a UUID
17458            installFlags |= PackageManager.INSTALL_EXTERNAL;
17459        }
17460        if (ps.isForwardLocked()) {
17461            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17462        }
17463        return installFlags;
17464    }
17465
17466    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17467        if (isExternal(pkg)) {
17468            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17469                return mSettings.getExternalVersion();
17470            } else {
17471                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17472            }
17473        } else {
17474            return mSettings.getInternalVersion();
17475        }
17476    }
17477
17478    private void deleteTempPackageFiles() {
17479        final FilenameFilter filter = new FilenameFilter() {
17480            public boolean accept(File dir, String name) {
17481                return name.startsWith("vmdl") && name.endsWith(".tmp");
17482            }
17483        };
17484        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17485            file.delete();
17486        }
17487    }
17488
17489    @Override
17490    public void deletePackageAsUser(String packageName, int versionCode,
17491            IPackageDeleteObserver observer, int userId, int flags) {
17492        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17493                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17494    }
17495
17496    @Override
17497    public void deletePackageVersioned(VersionedPackage versionedPackage,
17498            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17499        final int callingUid = Binder.getCallingUid();
17500        mContext.enforceCallingOrSelfPermission(
17501                android.Manifest.permission.DELETE_PACKAGES, null);
17502        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17503        Preconditions.checkNotNull(versionedPackage);
17504        Preconditions.checkNotNull(observer);
17505        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17506                PackageManager.VERSION_CODE_HIGHEST,
17507                Long.MAX_VALUE, "versionCode must be >= -1");
17508
17509        final String packageName = versionedPackage.getPackageName();
17510        final long versionCode = versionedPackage.getLongVersionCode();
17511        final String internalPackageName;
17512        synchronized (mPackages) {
17513            // Normalize package name to handle renamed packages and static libs
17514            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17515        }
17516
17517        final int uid = Binder.getCallingUid();
17518        if (!isOrphaned(internalPackageName)
17519                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17520            try {
17521                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17522                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17523                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17524                observer.onUserActionRequired(intent);
17525            } catch (RemoteException re) {
17526            }
17527            return;
17528        }
17529        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17530        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17531        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17532            mContext.enforceCallingOrSelfPermission(
17533                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17534                    "deletePackage for user " + userId);
17535        }
17536
17537        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17538            try {
17539                observer.onPackageDeleted(packageName,
17540                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17541            } catch (RemoteException re) {
17542            }
17543            return;
17544        }
17545
17546        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17547            try {
17548                observer.onPackageDeleted(packageName,
17549                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17550            } catch (RemoteException re) {
17551            }
17552            return;
17553        }
17554
17555        if (DEBUG_REMOVE) {
17556            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17557                    + " deleteAllUsers: " + deleteAllUsers + " version="
17558                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17559                    ? "VERSION_CODE_HIGHEST" : versionCode));
17560        }
17561        // Queue up an async operation since the package deletion may take a little while.
17562        mHandler.post(new Runnable() {
17563            public void run() {
17564                mHandler.removeCallbacks(this);
17565                int returnCode;
17566                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17567                boolean doDeletePackage = true;
17568                if (ps != null) {
17569                    final boolean targetIsInstantApp =
17570                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17571                    doDeletePackage = !targetIsInstantApp
17572                            || canViewInstantApps;
17573                }
17574                if (doDeletePackage) {
17575                    if (!deleteAllUsers) {
17576                        returnCode = deletePackageX(internalPackageName, versionCode,
17577                                userId, deleteFlags);
17578                    } else {
17579                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17580                                internalPackageName, users);
17581                        // If nobody is blocking uninstall, proceed with delete for all users
17582                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17583                            returnCode = deletePackageX(internalPackageName, versionCode,
17584                                    userId, deleteFlags);
17585                        } else {
17586                            // Otherwise uninstall individually for users with blockUninstalls=false
17587                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17588                            for (int userId : users) {
17589                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17590                                    returnCode = deletePackageX(internalPackageName, versionCode,
17591                                            userId, userFlags);
17592                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17593                                        Slog.w(TAG, "Package delete failed for user " + userId
17594                                                + ", returnCode " + returnCode);
17595                                    }
17596                                }
17597                            }
17598                            // The app has only been marked uninstalled for certain users.
17599                            // We still need to report that delete was blocked
17600                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17601                        }
17602                    }
17603                } else {
17604                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17605                }
17606                try {
17607                    observer.onPackageDeleted(packageName, returnCode, null);
17608                } catch (RemoteException e) {
17609                    Log.i(TAG, "Observer no longer exists.");
17610                } //end catch
17611            } //end run
17612        });
17613    }
17614
17615    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17616        if (pkg.staticSharedLibName != null) {
17617            return pkg.manifestPackageName;
17618        }
17619        return pkg.packageName;
17620    }
17621
17622    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17623        // Handle renamed packages
17624        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17625        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17626
17627        // Is this a static library?
17628        LongSparseArray<SharedLibraryEntry> versionedLib =
17629                mStaticLibsByDeclaringPackage.get(packageName);
17630        if (versionedLib == null || versionedLib.size() <= 0) {
17631            return packageName;
17632        }
17633
17634        // Figure out which lib versions the caller can see
17635        LongSparseLongArray versionsCallerCanSee = null;
17636        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17637        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17638                && callingAppId != Process.ROOT_UID) {
17639            versionsCallerCanSee = new LongSparseLongArray();
17640            String libName = versionedLib.valueAt(0).info.getName();
17641            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17642            if (uidPackages != null) {
17643                for (String uidPackage : uidPackages) {
17644                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17645                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17646                    if (libIdx >= 0) {
17647                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17648                        versionsCallerCanSee.append(libVersion, libVersion);
17649                    }
17650                }
17651            }
17652        }
17653
17654        // Caller can see nothing - done
17655        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17656            return packageName;
17657        }
17658
17659        // Find the version the caller can see and the app version code
17660        SharedLibraryEntry highestVersion = null;
17661        final int versionCount = versionedLib.size();
17662        for (int i = 0; i < versionCount; i++) {
17663            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17664            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17665                    libEntry.info.getLongVersion()) < 0) {
17666                continue;
17667            }
17668            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17669            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17670                if (libVersionCode == versionCode) {
17671                    return libEntry.apk;
17672                }
17673            } else if (highestVersion == null) {
17674                highestVersion = libEntry;
17675            } else if (libVersionCode  > highestVersion.info
17676                    .getDeclaringPackage().getLongVersionCode()) {
17677                highestVersion = libEntry;
17678            }
17679        }
17680
17681        if (highestVersion != null) {
17682            return highestVersion.apk;
17683        }
17684
17685        return packageName;
17686    }
17687
17688    boolean isCallerVerifier(int callingUid) {
17689        final int callingUserId = UserHandle.getUserId(callingUid);
17690        return mRequiredVerifierPackage != null &&
17691                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17692    }
17693
17694    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17695        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17696              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17697            return true;
17698        }
17699        final int callingUserId = UserHandle.getUserId(callingUid);
17700        // If the caller installed the pkgName, then allow it to silently uninstall.
17701        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17702            return true;
17703        }
17704
17705        // Allow package verifier to silently uninstall.
17706        if (mRequiredVerifierPackage != null &&
17707                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17708            return true;
17709        }
17710
17711        // Allow package uninstaller to silently uninstall.
17712        if (mRequiredUninstallerPackage != null &&
17713                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17714            return true;
17715        }
17716
17717        // Allow storage manager to silently uninstall.
17718        if (mStorageManagerPackage != null &&
17719                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17720            return true;
17721        }
17722
17723        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17724        // uninstall for device owner provisioning.
17725        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17726                == PERMISSION_GRANTED) {
17727            return true;
17728        }
17729
17730        return false;
17731    }
17732
17733    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17734        int[] result = EMPTY_INT_ARRAY;
17735        for (int userId : userIds) {
17736            if (getBlockUninstallForUser(packageName, userId)) {
17737                result = ArrayUtils.appendInt(result, userId);
17738            }
17739        }
17740        return result;
17741    }
17742
17743    @Override
17744    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17745        final int callingUid = Binder.getCallingUid();
17746        if (getInstantAppPackageName(callingUid) != null
17747                && !isCallerSameApp(packageName, callingUid)) {
17748            return false;
17749        }
17750        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17751    }
17752
17753    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17754        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17755                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17756        try {
17757            if (dpm != null) {
17758                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17759                        /* callingUserOnly =*/ false);
17760                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17761                        : deviceOwnerComponentName.getPackageName();
17762                // Does the package contains the device owner?
17763                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17764                // this check is probably not needed, since DO should be registered as a device
17765                // admin on some user too. (Original bug for this: b/17657954)
17766                if (packageName.equals(deviceOwnerPackageName)) {
17767                    return true;
17768                }
17769                // Does it contain a device admin for any user?
17770                int[] users;
17771                if (userId == UserHandle.USER_ALL) {
17772                    users = sUserManager.getUserIds();
17773                } else {
17774                    users = new int[]{userId};
17775                }
17776                for (int i = 0; i < users.length; ++i) {
17777                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17778                        return true;
17779                    }
17780                }
17781            }
17782        } catch (RemoteException e) {
17783        }
17784        return false;
17785    }
17786
17787    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17788        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17789    }
17790
17791    /**
17792     *  This method is an internal method that could be get invoked either
17793     *  to delete an installed package or to clean up a failed installation.
17794     *  After deleting an installed package, a broadcast is sent to notify any
17795     *  listeners that the package has been removed. For cleaning up a failed
17796     *  installation, the broadcast is not necessary since the package's
17797     *  installation wouldn't have sent the initial broadcast either
17798     *  The key steps in deleting a package are
17799     *  deleting the package information in internal structures like mPackages,
17800     *  deleting the packages base directories through installd
17801     *  updating mSettings to reflect current status
17802     *  persisting settings for later use
17803     *  sending a broadcast if necessary
17804     */
17805    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17806        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17807        final boolean res;
17808
17809        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17810                ? UserHandle.USER_ALL : userId;
17811
17812        if (isPackageDeviceAdmin(packageName, removeUser)) {
17813            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17814            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17815        }
17816
17817        PackageSetting uninstalledPs = null;
17818        PackageParser.Package pkg = null;
17819
17820        // for the uninstall-updates case and restricted profiles, remember the per-
17821        // user handle installed state
17822        int[] allUsers;
17823        synchronized (mPackages) {
17824            uninstalledPs = mSettings.mPackages.get(packageName);
17825            if (uninstalledPs == null) {
17826                Slog.w(TAG, "Not removing non-existent package " + packageName);
17827                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17828            }
17829
17830            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17831                    && uninstalledPs.versionCode != versionCode) {
17832                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17833                        + uninstalledPs.versionCode + " != " + versionCode);
17834                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17835            }
17836
17837            // Static shared libs can be declared by any package, so let us not
17838            // allow removing a package if it provides a lib others depend on.
17839            pkg = mPackages.get(packageName);
17840
17841            allUsers = sUserManager.getUserIds();
17842
17843            if (pkg != null && pkg.staticSharedLibName != null) {
17844                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17845                        pkg.staticSharedLibVersion);
17846                if (libEntry != null) {
17847                    for (int currUserId : allUsers) {
17848                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17849                            continue;
17850                        }
17851                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17852                                libEntry.info, 0, currUserId);
17853                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17854                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17855                                    + " hosting lib " + libEntry.info.getName() + " version "
17856                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17857                                    + " for user " + currUserId);
17858                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17859                        }
17860                    }
17861                }
17862            }
17863
17864            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17865        }
17866
17867        final int freezeUser;
17868        if (isUpdatedSystemApp(uninstalledPs)
17869                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17870            // We're downgrading a system app, which will apply to all users, so
17871            // freeze them all during the downgrade
17872            freezeUser = UserHandle.USER_ALL;
17873        } else {
17874            freezeUser = removeUser;
17875        }
17876
17877        synchronized (mInstallLock) {
17878            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17879            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17880                    deleteFlags, "deletePackageX")) {
17881                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17882                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17883            }
17884            synchronized (mPackages) {
17885                if (res) {
17886                    if (pkg != null) {
17887                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17888                    }
17889                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17890                    updateInstantAppInstallerLocked(packageName);
17891                }
17892            }
17893        }
17894
17895        if (res) {
17896            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17897            info.sendPackageRemovedBroadcasts(killApp);
17898            info.sendSystemPackageUpdatedBroadcasts();
17899            info.sendSystemPackageAppearedBroadcasts();
17900        }
17901        // Force a gc here.
17902        Runtime.getRuntime().gc();
17903        // Delete the resources here after sending the broadcast to let
17904        // other processes clean up before deleting resources.
17905        if (info.args != null) {
17906            synchronized (mInstallLock) {
17907                info.args.doPostDeleteLI(true);
17908            }
17909        }
17910
17911        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17912    }
17913
17914    static class PackageRemovedInfo {
17915        final PackageSender packageSender;
17916        String removedPackage;
17917        String installerPackageName;
17918        int uid = -1;
17919        int removedAppId = -1;
17920        int[] origUsers;
17921        int[] removedUsers = null;
17922        int[] broadcastUsers = null;
17923        int[] instantUserIds = null;
17924        SparseArray<Integer> installReasons;
17925        boolean isRemovedPackageSystemUpdate = false;
17926        boolean isUpdate;
17927        boolean dataRemoved;
17928        boolean removedForAllUsers;
17929        boolean isStaticSharedLib;
17930        // Clean up resources deleted packages.
17931        InstallArgs args = null;
17932        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17933        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17934
17935        PackageRemovedInfo(PackageSender packageSender) {
17936            this.packageSender = packageSender;
17937        }
17938
17939        void sendPackageRemovedBroadcasts(boolean killApp) {
17940            sendPackageRemovedBroadcastInternal(killApp);
17941            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17942            for (int i = 0; i < childCount; i++) {
17943                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17944                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17945            }
17946        }
17947
17948        void sendSystemPackageUpdatedBroadcasts() {
17949            if (isRemovedPackageSystemUpdate) {
17950                sendSystemPackageUpdatedBroadcastsInternal();
17951                final int childCount = (removedChildPackages != null)
17952                        ? removedChildPackages.size() : 0;
17953                for (int i = 0; i < childCount; i++) {
17954                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17955                    if (childInfo.isRemovedPackageSystemUpdate) {
17956                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17957                    }
17958                }
17959            }
17960        }
17961
17962        void sendSystemPackageAppearedBroadcasts() {
17963            final int packageCount = (appearedChildPackages != null)
17964                    ? appearedChildPackages.size() : 0;
17965            for (int i = 0; i < packageCount; i++) {
17966                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17967                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17968                    true /*sendBootCompleted*/, false /*startReceiver*/,
17969                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17970            }
17971        }
17972
17973        private void sendSystemPackageUpdatedBroadcastsInternal() {
17974            Bundle extras = new Bundle(2);
17975            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17976            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17977            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17978                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17979            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17980                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17981            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17982                null, null, 0, removedPackage, null, null, null);
17983            if (installerPackageName != null) {
17984                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17985                        removedPackage, extras, 0 /*flags*/,
17986                        installerPackageName, null, null, null);
17987                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17988                        removedPackage, extras, 0 /*flags*/,
17989                        installerPackageName, null, null, null);
17990            }
17991        }
17992
17993        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17994            // Don't send static shared library removal broadcasts as these
17995            // libs are visible only the the apps that depend on them an one
17996            // cannot remove the library if it has a dependency.
17997            if (isStaticSharedLib) {
17998                return;
17999            }
18000            Bundle extras = new Bundle(2);
18001            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18002            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18003            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18004            if (isUpdate || isRemovedPackageSystemUpdate) {
18005                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18006            }
18007            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18008            if (removedPackage != null) {
18009                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18010                    removedPackage, extras, 0, null /*targetPackage*/, null,
18011                    broadcastUsers, instantUserIds);
18012                if (installerPackageName != null) {
18013                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18014                            removedPackage, extras, 0 /*flags*/,
18015                            installerPackageName, null, broadcastUsers, instantUserIds);
18016                }
18017                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18018                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18019                        removedPackage, extras,
18020                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18021                        null, null, broadcastUsers, instantUserIds);
18022                    packageSender.notifyPackageRemoved(removedPackage);
18023                }
18024            }
18025            if (removedAppId >= 0) {
18026                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18027                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18028                    null, null, broadcastUsers, instantUserIds);
18029            }
18030        }
18031
18032        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18033            removedUsers = userIds;
18034            if (removedUsers == null) {
18035                broadcastUsers = null;
18036                return;
18037            }
18038
18039            broadcastUsers = EMPTY_INT_ARRAY;
18040            instantUserIds = EMPTY_INT_ARRAY;
18041            for (int i = userIds.length - 1; i >= 0; --i) {
18042                final int userId = userIds[i];
18043                if (deletedPackageSetting.getInstantApp(userId)) {
18044                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18045                } else {
18046                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18047                }
18048            }
18049        }
18050    }
18051
18052    /*
18053     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18054     * flag is not set, the data directory is removed as well.
18055     * make sure this flag is set for partially installed apps. If not its meaningless to
18056     * delete a partially installed application.
18057     */
18058    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18059            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18060        String packageName = ps.name;
18061        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18062        // Retrieve object to delete permissions for shared user later on
18063        final PackageParser.Package deletedPkg;
18064        final PackageSetting deletedPs;
18065        // reader
18066        synchronized (mPackages) {
18067            deletedPkg = mPackages.get(packageName);
18068            deletedPs = mSettings.mPackages.get(packageName);
18069            if (outInfo != null) {
18070                outInfo.removedPackage = packageName;
18071                outInfo.installerPackageName = ps.installerPackageName;
18072                outInfo.isStaticSharedLib = deletedPkg != null
18073                        && deletedPkg.staticSharedLibName != null;
18074                outInfo.populateUsers(deletedPs == null ? null
18075                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18076            }
18077        }
18078
18079        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
18080
18081        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18082            final PackageParser.Package resolvedPkg;
18083            if (deletedPkg != null) {
18084                resolvedPkg = deletedPkg;
18085            } else {
18086                // We don't have a parsed package when it lives on an ejected
18087                // adopted storage device, so fake something together
18088                resolvedPkg = new PackageParser.Package(ps.name);
18089                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18090            }
18091            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18092                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18093            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18094            if (outInfo != null) {
18095                outInfo.dataRemoved = true;
18096            }
18097            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18098        }
18099
18100        int removedAppId = -1;
18101
18102        // writer
18103        synchronized (mPackages) {
18104            boolean installedStateChanged = false;
18105            if (deletedPs != null) {
18106                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18107                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18108                    clearDefaultBrowserIfNeeded(packageName);
18109                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18110                    removedAppId = mSettings.removePackageLPw(packageName);
18111                    if (outInfo != null) {
18112                        outInfo.removedAppId = removedAppId;
18113                    }
18114                    mPermissionManager.updatePermissions(
18115                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18116                    if (deletedPs.sharedUser != null) {
18117                        // Remove permissions associated with package. Since runtime
18118                        // permissions are per user we have to kill the removed package
18119                        // or packages running under the shared user of the removed
18120                        // package if revoking the permissions requested only by the removed
18121                        // package is successful and this causes a change in gids.
18122                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18123                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18124                                    userId);
18125                            if (userIdToKill == UserHandle.USER_ALL
18126                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18127                                // If gids changed for this user, kill all affected packages.
18128                                mHandler.post(new Runnable() {
18129                                    @Override
18130                                    public void run() {
18131                                        // This has to happen with no lock held.
18132                                        killApplication(deletedPs.name, deletedPs.appId,
18133                                                KILL_APP_REASON_GIDS_CHANGED);
18134                                    }
18135                                });
18136                                break;
18137                            }
18138                        }
18139                    }
18140                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18141                }
18142                // make sure to preserve per-user disabled state if this removal was just
18143                // a downgrade of a system app to the factory package
18144                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18145                    if (DEBUG_REMOVE) {
18146                        Slog.d(TAG, "Propagating install state across downgrade");
18147                    }
18148                    for (int userId : allUserHandles) {
18149                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18150                        if (DEBUG_REMOVE) {
18151                            Slog.d(TAG, "    user " + userId + " => " + installed);
18152                        }
18153                        if (installed != ps.getInstalled(userId)) {
18154                            installedStateChanged = true;
18155                        }
18156                        ps.setInstalled(installed, userId);
18157                    }
18158                }
18159            }
18160            // can downgrade to reader
18161            if (writeSettings) {
18162                // Save settings now
18163                mSettings.writeLPr();
18164            }
18165            if (installedStateChanged) {
18166                mSettings.writeKernelMappingLPr(ps);
18167            }
18168        }
18169        if (removedAppId != -1) {
18170            // A user ID was deleted here. Go through all users and remove it
18171            // from KeyStore.
18172            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18173        }
18174    }
18175
18176    static boolean locationIsPrivileged(String path) {
18177        try {
18178            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18179            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18180            final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18181            return path.startsWith(privilegedAppDir.getCanonicalPath())
18182                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath())
18183                    || path.startsWith(privilegedProductAppDir.getCanonicalPath());
18184        } catch (IOException e) {
18185            Slog.e(TAG, "Unable to access code path " + path);
18186        }
18187        return false;
18188    }
18189
18190    static boolean locationIsOem(String path) {
18191        try {
18192            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
18193        } catch (IOException e) {
18194            Slog.e(TAG, "Unable to access code path " + path);
18195        }
18196        return false;
18197    }
18198
18199    static boolean locationIsVendor(String path) {
18200        try {
18201            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
18202        } catch (IOException e) {
18203            Slog.e(TAG, "Unable to access code path " + path);
18204        }
18205        return false;
18206    }
18207
18208    static boolean locationIsProduct(String path) {
18209        try {
18210            return path.startsWith(Environment.getProductDirectory().getCanonicalPath());
18211        } catch (IOException e) {
18212            Slog.e(TAG, "Unable to access code path " + path);
18213        }
18214        return false;
18215    }
18216
18217    /*
18218     * Tries to delete system package.
18219     */
18220    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18221            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18222            boolean writeSettings) {
18223        if (deletedPs.parentPackageName != null) {
18224            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18225            return false;
18226        }
18227
18228        final boolean applyUserRestrictions
18229                = (allUserHandles != null) && (outInfo.origUsers != null);
18230        final PackageSetting disabledPs;
18231        // Confirm if the system package has been updated
18232        // An updated system app can be deleted. This will also have to restore
18233        // the system pkg from system partition
18234        // reader
18235        synchronized (mPackages) {
18236            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18237        }
18238
18239        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18240                + " disabledPs=" + disabledPs);
18241
18242        if (disabledPs == null) {
18243            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18244            return false;
18245        } else if (DEBUG_REMOVE) {
18246            Slog.d(TAG, "Deleting system pkg from data partition");
18247        }
18248
18249        if (DEBUG_REMOVE) {
18250            if (applyUserRestrictions) {
18251                Slog.d(TAG, "Remembering install states:");
18252                for (int userId : allUserHandles) {
18253                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18254                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18255                }
18256            }
18257        }
18258
18259        // Delete the updated package
18260        outInfo.isRemovedPackageSystemUpdate = true;
18261        if (outInfo.removedChildPackages != null) {
18262            final int childCount = (deletedPs.childPackageNames != null)
18263                    ? deletedPs.childPackageNames.size() : 0;
18264            for (int i = 0; i < childCount; i++) {
18265                String childPackageName = deletedPs.childPackageNames.get(i);
18266                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18267                        .contains(childPackageName)) {
18268                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18269                            childPackageName);
18270                    if (childInfo != null) {
18271                        childInfo.isRemovedPackageSystemUpdate = true;
18272                    }
18273                }
18274            }
18275        }
18276
18277        if (disabledPs.versionCode < deletedPs.versionCode) {
18278            // Delete data for downgrades
18279            flags &= ~PackageManager.DELETE_KEEP_DATA;
18280        } else {
18281            // Preserve data by setting flag
18282            flags |= PackageManager.DELETE_KEEP_DATA;
18283        }
18284
18285        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18286                outInfo, writeSettings, disabledPs.pkg);
18287        if (!ret) {
18288            return false;
18289        }
18290
18291        // writer
18292        synchronized (mPackages) {
18293            // NOTE: The system package always needs to be enabled; even if it's for
18294            // a compressed stub. If we don't, installing the system package fails
18295            // during scan [scanning checks the disabled packages]. We will reverse
18296            // this later, after we've "installed" the stub.
18297            // Reinstate the old system package
18298            enableSystemPackageLPw(disabledPs.pkg);
18299            // Remove any native libraries from the upgraded package.
18300            removeNativeBinariesLI(deletedPs);
18301        }
18302
18303        // Install the system package
18304        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18305        try {
18306            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18307                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18308        } catch (PackageManagerException e) {
18309            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18310                    + e.getMessage());
18311            return false;
18312        } finally {
18313            if (disabledPs.pkg.isStub) {
18314                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18315            }
18316        }
18317        return true;
18318    }
18319
18320    /**
18321     * Installs a package that's already on the system partition.
18322     */
18323    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18324            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18325            @Nullable PermissionsState origPermissionState, boolean writeSettings)
18326                    throws PackageManagerException {
18327        @ParseFlags int parseFlags =
18328                mDefParseFlags
18329                | PackageParser.PARSE_MUST_BE_APK
18330                | PackageParser.PARSE_IS_SYSTEM_DIR;
18331        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18332        if (isPrivileged || locationIsPrivileged(codePathString)) {
18333            scanFlags |= SCAN_AS_PRIVILEGED;
18334        }
18335        if (locationIsOem(codePathString)) {
18336            scanFlags |= SCAN_AS_OEM;
18337        }
18338        if (locationIsVendor(codePathString)) {
18339            scanFlags |= SCAN_AS_VENDOR;
18340        }
18341        if (locationIsProduct(codePathString)) {
18342            scanFlags |= SCAN_AS_PRODUCT;
18343        }
18344
18345        final File codePath = new File(codePathString);
18346        final PackageParser.Package pkg =
18347                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18348
18349        try {
18350            // update shared libraries for the newly re-installed system package
18351            updateSharedLibrariesLPr(pkg, null);
18352        } catch (PackageManagerException e) {
18353            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18354        }
18355
18356        prepareAppDataAfterInstallLIF(pkg);
18357
18358        // writer
18359        synchronized (mPackages) {
18360            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18361
18362            // Propagate the permissions state as we do not want to drop on the floor
18363            // runtime permissions. The update permissions method below will take
18364            // care of removing obsolete permissions and grant install permissions.
18365            if (origPermissionState != null) {
18366                ps.getPermissionsState().copyFrom(origPermissionState);
18367            }
18368            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18369                    mPermissionCallback);
18370
18371            final boolean applyUserRestrictions
18372                    = (allUserHandles != null) && (origUserHandles != null);
18373            if (applyUserRestrictions) {
18374                boolean installedStateChanged = false;
18375                if (DEBUG_REMOVE) {
18376                    Slog.d(TAG, "Propagating install state across reinstall");
18377                }
18378                for (int userId : allUserHandles) {
18379                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18380                    if (DEBUG_REMOVE) {
18381                        Slog.d(TAG, "    user " + userId + " => " + installed);
18382                    }
18383                    if (installed != ps.getInstalled(userId)) {
18384                        installedStateChanged = true;
18385                    }
18386                    ps.setInstalled(installed, userId);
18387
18388                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18389                }
18390                // Regardless of writeSettings we need to ensure that this restriction
18391                // state propagation is persisted
18392                mSettings.writeAllUsersPackageRestrictionsLPr();
18393                if (installedStateChanged) {
18394                    mSettings.writeKernelMappingLPr(ps);
18395                }
18396            }
18397            // can downgrade to reader here
18398            if (writeSettings) {
18399                mSettings.writeLPr();
18400            }
18401        }
18402        return pkg;
18403    }
18404
18405    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18406            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18407            PackageRemovedInfo outInfo, boolean writeSettings,
18408            PackageParser.Package replacingPackage) {
18409        synchronized (mPackages) {
18410            if (outInfo != null) {
18411                outInfo.uid = ps.appId;
18412            }
18413
18414            if (outInfo != null && outInfo.removedChildPackages != null) {
18415                final int childCount = (ps.childPackageNames != null)
18416                        ? ps.childPackageNames.size() : 0;
18417                for (int i = 0; i < childCount; i++) {
18418                    String childPackageName = ps.childPackageNames.get(i);
18419                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18420                    if (childPs == null) {
18421                        return false;
18422                    }
18423                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18424                            childPackageName);
18425                    if (childInfo != null) {
18426                        childInfo.uid = childPs.appId;
18427                    }
18428                }
18429            }
18430        }
18431
18432        // Delete package data from internal structures and also remove data if flag is set
18433        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18434
18435        // Delete the child packages data
18436        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18437        for (int i = 0; i < childCount; i++) {
18438            PackageSetting childPs;
18439            synchronized (mPackages) {
18440                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18441            }
18442            if (childPs != null) {
18443                PackageRemovedInfo childOutInfo = (outInfo != null
18444                        && outInfo.removedChildPackages != null)
18445                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18446                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18447                        && (replacingPackage != null
18448                        && !replacingPackage.hasChildPackage(childPs.name))
18449                        ? flags & ~DELETE_KEEP_DATA : flags;
18450                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18451                        deleteFlags, writeSettings);
18452            }
18453        }
18454
18455        // Delete application code and resources only for parent packages
18456        if (ps.parentPackageName == null) {
18457            if (deleteCodeAndResources && (outInfo != null)) {
18458                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18459                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18460                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18461            }
18462        }
18463
18464        return true;
18465    }
18466
18467    @Override
18468    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18469            int userId) {
18470        mContext.enforceCallingOrSelfPermission(
18471                android.Manifest.permission.DELETE_PACKAGES, null);
18472        synchronized (mPackages) {
18473            // Cannot block uninstall of static shared libs as they are
18474            // considered a part of the using app (emulating static linking).
18475            // Also static libs are installed always on internal storage.
18476            PackageParser.Package pkg = mPackages.get(packageName);
18477            if (pkg != null && pkg.staticSharedLibName != null) {
18478                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18479                        + " providing static shared library: " + pkg.staticSharedLibName);
18480                return false;
18481            }
18482            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18483            mSettings.writePackageRestrictionsLPr(userId);
18484        }
18485        return true;
18486    }
18487
18488    @Override
18489    public boolean getBlockUninstallForUser(String packageName, int userId) {
18490        synchronized (mPackages) {
18491            final PackageSetting ps = mSettings.mPackages.get(packageName);
18492            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18493                return false;
18494            }
18495            return mSettings.getBlockUninstallLPr(userId, packageName);
18496        }
18497    }
18498
18499    @Override
18500    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18501        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18502        synchronized (mPackages) {
18503            PackageSetting ps = mSettings.mPackages.get(packageName);
18504            if (ps == null) {
18505                Log.w(TAG, "Package doesn't exist: " + packageName);
18506                return false;
18507            }
18508            if (systemUserApp) {
18509                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18510            } else {
18511                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18512            }
18513            mSettings.writeLPr();
18514        }
18515        return true;
18516    }
18517
18518    /*
18519     * This method handles package deletion in general
18520     */
18521    private boolean deletePackageLIF(String packageName, UserHandle user,
18522            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18523            PackageRemovedInfo outInfo, boolean writeSettings,
18524            PackageParser.Package replacingPackage) {
18525        if (packageName == null) {
18526            Slog.w(TAG, "Attempt to delete null packageName.");
18527            return false;
18528        }
18529
18530        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18531
18532        PackageSetting ps;
18533        synchronized (mPackages) {
18534            ps = mSettings.mPackages.get(packageName);
18535            if (ps == null) {
18536                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18537                return false;
18538            }
18539
18540            if (ps.parentPackageName != null && (!isSystemApp(ps)
18541                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18542                if (DEBUG_REMOVE) {
18543                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18544                            + ((user == null) ? UserHandle.USER_ALL : user));
18545                }
18546                final int removedUserId = (user != null) ? user.getIdentifier()
18547                        : UserHandle.USER_ALL;
18548                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18549                    return false;
18550                }
18551                markPackageUninstalledForUserLPw(ps, user);
18552                scheduleWritePackageRestrictionsLocked(user);
18553                return true;
18554            }
18555        }
18556
18557        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18558                && user.getIdentifier() != UserHandle.USER_ALL)) {
18559            // The caller is asking that the package only be deleted for a single
18560            // user.  To do this, we just mark its uninstalled state and delete
18561            // its data. If this is a system app, we only allow this to happen if
18562            // they have set the special DELETE_SYSTEM_APP which requests different
18563            // semantics than normal for uninstalling system apps.
18564            markPackageUninstalledForUserLPw(ps, user);
18565
18566            if (!isSystemApp(ps)) {
18567                // Do not uninstall the APK if an app should be cached
18568                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18569                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18570                    // Other user still have this package installed, so all
18571                    // we need to do is clear this user's data and save that
18572                    // it is uninstalled.
18573                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18574                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18575                        return false;
18576                    }
18577                    scheduleWritePackageRestrictionsLocked(user);
18578                    return true;
18579                } else {
18580                    // We need to set it back to 'installed' so the uninstall
18581                    // broadcasts will be sent correctly.
18582                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18583                    ps.setInstalled(true, user.getIdentifier());
18584                    mSettings.writeKernelMappingLPr(ps);
18585                }
18586            } else {
18587                // This is a system app, so we assume that the
18588                // other users still have this package installed, so all
18589                // we need to do is clear this user's data and save that
18590                // it is uninstalled.
18591                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18592                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18593                    return false;
18594                }
18595                scheduleWritePackageRestrictionsLocked(user);
18596                return true;
18597            }
18598        }
18599
18600        // If we are deleting a composite package for all users, keep track
18601        // of result for each child.
18602        if (ps.childPackageNames != null && outInfo != null) {
18603            synchronized (mPackages) {
18604                final int childCount = ps.childPackageNames.size();
18605                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18606                for (int i = 0; i < childCount; i++) {
18607                    String childPackageName = ps.childPackageNames.get(i);
18608                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18609                    childInfo.removedPackage = childPackageName;
18610                    childInfo.installerPackageName = ps.installerPackageName;
18611                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18612                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18613                    if (childPs != null) {
18614                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18615                    }
18616                }
18617            }
18618        }
18619
18620        boolean ret = false;
18621        if (isSystemApp(ps)) {
18622            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18623            // When an updated system application is deleted we delete the existing resources
18624            // as well and fall back to existing code in system partition
18625            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18626        } else {
18627            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18628            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18629                    outInfo, writeSettings, replacingPackage);
18630        }
18631
18632        // Take a note whether we deleted the package for all users
18633        if (outInfo != null) {
18634            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18635            if (outInfo.removedChildPackages != null) {
18636                synchronized (mPackages) {
18637                    final int childCount = outInfo.removedChildPackages.size();
18638                    for (int i = 0; i < childCount; i++) {
18639                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18640                        if (childInfo != null) {
18641                            childInfo.removedForAllUsers = mPackages.get(
18642                                    childInfo.removedPackage) == null;
18643                        }
18644                    }
18645                }
18646            }
18647            // If we uninstalled an update to a system app there may be some
18648            // child packages that appeared as they are declared in the system
18649            // app but were not declared in the update.
18650            if (isSystemApp(ps)) {
18651                synchronized (mPackages) {
18652                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18653                    final int childCount = (updatedPs.childPackageNames != null)
18654                            ? updatedPs.childPackageNames.size() : 0;
18655                    for (int i = 0; i < childCount; i++) {
18656                        String childPackageName = updatedPs.childPackageNames.get(i);
18657                        if (outInfo.removedChildPackages == null
18658                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18659                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18660                            if (childPs == null) {
18661                                continue;
18662                            }
18663                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18664                            installRes.name = childPackageName;
18665                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18666                            installRes.pkg = mPackages.get(childPackageName);
18667                            installRes.uid = childPs.pkg.applicationInfo.uid;
18668                            if (outInfo.appearedChildPackages == null) {
18669                                outInfo.appearedChildPackages = new ArrayMap<>();
18670                            }
18671                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18672                        }
18673                    }
18674                }
18675            }
18676        }
18677
18678        return ret;
18679    }
18680
18681    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18682        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18683                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18684        for (int nextUserId : userIds) {
18685            if (DEBUG_REMOVE) {
18686                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18687            }
18688            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18689                    false /*installed*/,
18690                    true /*stopped*/,
18691                    true /*notLaunched*/,
18692                    false /*hidden*/,
18693                    false /*suspended*/,
18694                    false /*instantApp*/,
18695                    false /*virtualPreload*/,
18696                    null /*lastDisableAppCaller*/,
18697                    null /*enabledComponents*/,
18698                    null /*disabledComponents*/,
18699                    ps.readUserState(nextUserId).domainVerificationStatus,
18700                    0, PackageManager.INSTALL_REASON_UNKNOWN,
18701                    null /*harmfulAppWarning*/);
18702        }
18703        mSettings.writeKernelMappingLPr(ps);
18704    }
18705
18706    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18707            PackageRemovedInfo outInfo) {
18708        final PackageParser.Package pkg;
18709        synchronized (mPackages) {
18710            pkg = mPackages.get(ps.name);
18711        }
18712
18713        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18714                : new int[] {userId};
18715        for (int nextUserId : userIds) {
18716            if (DEBUG_REMOVE) {
18717                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18718                        + nextUserId);
18719            }
18720
18721            destroyAppDataLIF(pkg, userId,
18722                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18723            destroyAppProfilesLIF(pkg, userId);
18724            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18725            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18726            schedulePackageCleaning(ps.name, nextUserId, false);
18727            synchronized (mPackages) {
18728                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18729                    scheduleWritePackageRestrictionsLocked(nextUserId);
18730                }
18731                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18732            }
18733        }
18734
18735        if (outInfo != null) {
18736            outInfo.removedPackage = ps.name;
18737            outInfo.installerPackageName = ps.installerPackageName;
18738            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18739            outInfo.removedAppId = ps.appId;
18740            outInfo.removedUsers = userIds;
18741            outInfo.broadcastUsers = userIds;
18742        }
18743
18744        return true;
18745    }
18746
18747    private static final class ClearStorageConnection implements ServiceConnection {
18748        IMediaContainerService mContainerService;
18749
18750        @Override
18751        public void onServiceConnected(ComponentName name, IBinder service) {
18752            synchronized (this) {
18753                mContainerService = IMediaContainerService.Stub
18754                        .asInterface(Binder.allowBlocking(service));
18755                notifyAll();
18756            }
18757        }
18758
18759        @Override
18760        public void onServiceDisconnected(ComponentName name) {
18761        }
18762    }
18763
18764    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18765        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18766
18767        final boolean mounted;
18768        if (Environment.isExternalStorageEmulated()) {
18769            mounted = true;
18770        } else {
18771            final String status = Environment.getExternalStorageState();
18772
18773            mounted = status.equals(Environment.MEDIA_MOUNTED)
18774                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18775        }
18776
18777        if (!mounted) {
18778            return;
18779        }
18780
18781        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18782        int[] users;
18783        if (userId == UserHandle.USER_ALL) {
18784            users = sUserManager.getUserIds();
18785        } else {
18786            users = new int[] { userId };
18787        }
18788        final ClearStorageConnection conn = new ClearStorageConnection();
18789        if (mContext.bindServiceAsUser(
18790                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18791            try {
18792                for (int curUser : users) {
18793                    long timeout = SystemClock.uptimeMillis() + 5000;
18794                    synchronized (conn) {
18795                        long now;
18796                        while (conn.mContainerService == null &&
18797                                (now = SystemClock.uptimeMillis()) < timeout) {
18798                            try {
18799                                conn.wait(timeout - now);
18800                            } catch (InterruptedException e) {
18801                            }
18802                        }
18803                    }
18804                    if (conn.mContainerService == null) {
18805                        return;
18806                    }
18807
18808                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18809                    clearDirectory(conn.mContainerService,
18810                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18811                    if (allData) {
18812                        clearDirectory(conn.mContainerService,
18813                                userEnv.buildExternalStorageAppDataDirs(packageName));
18814                        clearDirectory(conn.mContainerService,
18815                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18816                    }
18817                }
18818            } finally {
18819                mContext.unbindService(conn);
18820            }
18821        }
18822    }
18823
18824    @Override
18825    public void clearApplicationProfileData(String packageName) {
18826        enforceSystemOrRoot("Only the system can clear all profile data");
18827
18828        final PackageParser.Package pkg;
18829        synchronized (mPackages) {
18830            pkg = mPackages.get(packageName);
18831        }
18832
18833        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18834            synchronized (mInstallLock) {
18835                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18836            }
18837        }
18838    }
18839
18840    @Override
18841    public void clearApplicationUserData(final String packageName,
18842            final IPackageDataObserver observer, final int userId) {
18843        mContext.enforceCallingOrSelfPermission(
18844                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18845
18846        final int callingUid = Binder.getCallingUid();
18847        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18848                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18849
18850        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18851        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18852        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18853            throw new SecurityException("Cannot clear data for a protected package: "
18854                    + packageName);
18855        }
18856        // Queue up an async operation since the package deletion may take a little while.
18857        mHandler.post(new Runnable() {
18858            public void run() {
18859                mHandler.removeCallbacks(this);
18860                final boolean succeeded;
18861                if (!filterApp) {
18862                    try (PackageFreezer freezer = freezePackage(packageName,
18863                            "clearApplicationUserData")) {
18864                        synchronized (mInstallLock) {
18865                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18866                        }
18867                        clearExternalStorageDataSync(packageName, userId, true);
18868                        synchronized (mPackages) {
18869                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18870                                    packageName, userId);
18871                        }
18872                    }
18873                    if (succeeded) {
18874                        // invoke DeviceStorageMonitor's update method to clear any notifications
18875                        DeviceStorageMonitorInternal dsm = LocalServices
18876                                .getService(DeviceStorageMonitorInternal.class);
18877                        if (dsm != null) {
18878                            dsm.checkMemory();
18879                        }
18880                    }
18881                } else {
18882                    succeeded = false;
18883                }
18884                if (observer != null) {
18885                    try {
18886                        observer.onRemoveCompleted(packageName, succeeded);
18887                    } catch (RemoteException e) {
18888                        Log.i(TAG, "Observer no longer exists.");
18889                    }
18890                } //end if observer
18891            } //end run
18892        });
18893    }
18894
18895    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18896        if (packageName == null) {
18897            Slog.w(TAG, "Attempt to delete null packageName.");
18898            return false;
18899        }
18900
18901        // Try finding details about the requested package
18902        PackageParser.Package pkg;
18903        synchronized (mPackages) {
18904            pkg = mPackages.get(packageName);
18905            if (pkg == null) {
18906                final PackageSetting ps = mSettings.mPackages.get(packageName);
18907                if (ps != null) {
18908                    pkg = ps.pkg;
18909                }
18910            }
18911
18912            if (pkg == null) {
18913                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18914                return false;
18915            }
18916
18917            PackageSetting ps = (PackageSetting) pkg.mExtras;
18918            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18919        }
18920
18921        clearAppDataLIF(pkg, userId,
18922                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18923
18924        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18925        removeKeystoreDataIfNeeded(userId, appId);
18926
18927        UserManagerInternal umInternal = getUserManagerInternal();
18928        final int flags;
18929        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18930            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18931        } else if (umInternal.isUserRunning(userId)) {
18932            flags = StorageManager.FLAG_STORAGE_DE;
18933        } else {
18934            flags = 0;
18935        }
18936        prepareAppDataContentsLIF(pkg, userId, flags);
18937
18938        return true;
18939    }
18940
18941    /**
18942     * Reverts user permission state changes (permissions and flags) in
18943     * all packages for a given user.
18944     *
18945     * @param userId The device user for which to do a reset.
18946     */
18947    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18948        final int packageCount = mPackages.size();
18949        for (int i = 0; i < packageCount; i++) {
18950            PackageParser.Package pkg = mPackages.valueAt(i);
18951            PackageSetting ps = (PackageSetting) pkg.mExtras;
18952            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18953        }
18954    }
18955
18956    private void resetNetworkPolicies(int userId) {
18957        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18958    }
18959
18960    /**
18961     * Reverts user permission state changes (permissions and flags).
18962     *
18963     * @param ps The package for which to reset.
18964     * @param userId The device user for which to do a reset.
18965     */
18966    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18967            final PackageSetting ps, final int userId) {
18968        if (ps.pkg == null) {
18969            return;
18970        }
18971
18972        // These are flags that can change base on user actions.
18973        final int userSettableMask = FLAG_PERMISSION_USER_SET
18974                | FLAG_PERMISSION_USER_FIXED
18975                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18976                | FLAG_PERMISSION_REVIEW_REQUIRED;
18977
18978        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18979                | FLAG_PERMISSION_POLICY_FIXED;
18980
18981        boolean writeInstallPermissions = false;
18982        boolean writeRuntimePermissions = false;
18983
18984        final int permissionCount = ps.pkg.requestedPermissions.size();
18985        for (int i = 0; i < permissionCount; i++) {
18986            final String permName = ps.pkg.requestedPermissions.get(i);
18987            final BasePermission bp =
18988                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
18989            if (bp == null) {
18990                continue;
18991            }
18992
18993            // If shared user we just reset the state to which only this app contributed.
18994            if (ps.sharedUser != null) {
18995                boolean used = false;
18996                final int packageCount = ps.sharedUser.packages.size();
18997                for (int j = 0; j < packageCount; j++) {
18998                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18999                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19000                            && pkg.pkg.requestedPermissions.contains(permName)) {
19001                        used = true;
19002                        break;
19003                    }
19004                }
19005                if (used) {
19006                    continue;
19007                }
19008            }
19009
19010            final PermissionsState permissionsState = ps.getPermissionsState();
19011
19012            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
19013
19014            // Always clear the user settable flags.
19015            final boolean hasInstallState =
19016                    permissionsState.getInstallPermissionState(permName) != null;
19017            // If permission review is enabled and this is a legacy app, mark the
19018            // permission as requiring a review as this is the initial state.
19019            int flags = 0;
19020            if (mSettings.mPermissions.mPermissionReviewRequired
19021                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19022                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19023            }
19024            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19025                if (hasInstallState) {
19026                    writeInstallPermissions = true;
19027                } else {
19028                    writeRuntimePermissions = true;
19029                }
19030            }
19031
19032            // Below is only runtime permission handling.
19033            if (!bp.isRuntime()) {
19034                continue;
19035            }
19036
19037            // Never clobber system or policy.
19038            if ((oldFlags & policyOrSystemFlags) != 0) {
19039                continue;
19040            }
19041
19042            // If this permission was granted by default, make sure it is.
19043            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19044                if (permissionsState.grantRuntimePermission(bp, userId)
19045                        != PERMISSION_OPERATION_FAILURE) {
19046                    writeRuntimePermissions = true;
19047                }
19048            // If permission review is enabled the permissions for a legacy apps
19049            // are represented as constantly granted runtime ones, so don't revoke.
19050            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19051                // Otherwise, reset the permission.
19052                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19053                switch (revokeResult) {
19054                    case PERMISSION_OPERATION_SUCCESS:
19055                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19056                        writeRuntimePermissions = true;
19057                        final int appId = ps.appId;
19058                        mHandler.post(new Runnable() {
19059                            @Override
19060                            public void run() {
19061                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19062                            }
19063                        });
19064                    } break;
19065                }
19066            }
19067        }
19068
19069        // Synchronously write as we are taking permissions away.
19070        if (writeRuntimePermissions) {
19071            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19072        }
19073
19074        // Synchronously write as we are taking permissions away.
19075        if (writeInstallPermissions) {
19076            mSettings.writeLPr();
19077        }
19078    }
19079
19080    /**
19081     * Remove entries from the keystore daemon. Will only remove it if the
19082     * {@code appId} is valid.
19083     */
19084    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19085        if (appId < 0) {
19086            return;
19087        }
19088
19089        final KeyStore keyStore = KeyStore.getInstance();
19090        if (keyStore != null) {
19091            if (userId == UserHandle.USER_ALL) {
19092                for (final int individual : sUserManager.getUserIds()) {
19093                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19094                }
19095            } else {
19096                keyStore.clearUid(UserHandle.getUid(userId, appId));
19097            }
19098        } else {
19099            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19100        }
19101    }
19102
19103    @Override
19104    public void deleteApplicationCacheFiles(final String packageName,
19105            final IPackageDataObserver observer) {
19106        final int userId = UserHandle.getCallingUserId();
19107        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19108    }
19109
19110    @Override
19111    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19112            final IPackageDataObserver observer) {
19113        final int callingUid = Binder.getCallingUid();
19114        if (mContext.checkCallingOrSelfPermission(
19115                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
19116                != PackageManager.PERMISSION_GRANTED) {
19117            // If the caller has the old delete cache permission, silently ignore.  Else throw.
19118            if (mContext.checkCallingOrSelfPermission(
19119                    android.Manifest.permission.DELETE_CACHE_FILES)
19120                    == PackageManager.PERMISSION_GRANTED) {
19121                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
19122                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
19123                        ", silently ignoring");
19124                return;
19125            }
19126            mContext.enforceCallingOrSelfPermission(
19127                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
19128        }
19129        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19130                /* requireFullPermission= */ true, /* checkShell= */ false,
19131                "delete application cache files");
19132        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19133                android.Manifest.permission.ACCESS_INSTANT_APPS);
19134
19135        final PackageParser.Package pkg;
19136        synchronized (mPackages) {
19137            pkg = mPackages.get(packageName);
19138        }
19139
19140        // Queue up an async operation since the package deletion may take a little while.
19141        mHandler.post(new Runnable() {
19142            public void run() {
19143                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
19144                boolean doClearData = true;
19145                if (ps != null) {
19146                    final boolean targetIsInstantApp =
19147                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19148                    doClearData = !targetIsInstantApp
19149                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
19150                }
19151                if (doClearData) {
19152                    synchronized (mInstallLock) {
19153                        final int flags = StorageManager.FLAG_STORAGE_DE
19154                                | StorageManager.FLAG_STORAGE_CE;
19155                        // We're only clearing cache files, so we don't care if the
19156                        // app is unfrozen and still able to run
19157                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19158                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19159                    }
19160                    clearExternalStorageDataSync(packageName, userId, false);
19161                }
19162                if (observer != null) {
19163                    try {
19164                        observer.onRemoveCompleted(packageName, true);
19165                    } catch (RemoteException e) {
19166                        Log.i(TAG, "Observer no longer exists.");
19167                    }
19168                }
19169            }
19170        });
19171    }
19172
19173    @Override
19174    public void getPackageSizeInfo(final String packageName, int userHandle,
19175            final IPackageStatsObserver observer) {
19176        throw new UnsupportedOperationException(
19177                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19178    }
19179
19180    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19181        final PackageSetting ps;
19182        synchronized (mPackages) {
19183            ps = mSettings.mPackages.get(packageName);
19184            if (ps == null) {
19185                Slog.w(TAG, "Failed to find settings for " + packageName);
19186                return false;
19187            }
19188        }
19189
19190        final String[] packageNames = { packageName };
19191        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19192        final String[] codePaths = { ps.codePathString };
19193
19194        try {
19195            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19196                    ps.appId, ceDataInodes, codePaths, stats);
19197
19198            // For now, ignore code size of packages on system partition
19199            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19200                stats.codeSize = 0;
19201            }
19202
19203            // External clients expect these to be tracked separately
19204            stats.dataSize -= stats.cacheSize;
19205
19206        } catch (InstallerException e) {
19207            Slog.w(TAG, String.valueOf(e));
19208            return false;
19209        }
19210
19211        return true;
19212    }
19213
19214    private int getUidTargetSdkVersionLockedLPr(int uid) {
19215        Object obj = mSettings.getUserIdLPr(uid);
19216        if (obj instanceof SharedUserSetting) {
19217            final SharedUserSetting sus = (SharedUserSetting) obj;
19218            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19219            final Iterator<PackageSetting> it = sus.packages.iterator();
19220            while (it.hasNext()) {
19221                final PackageSetting ps = it.next();
19222                if (ps.pkg != null) {
19223                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19224                    if (v < vers) vers = v;
19225                }
19226            }
19227            return vers;
19228        } else if (obj instanceof PackageSetting) {
19229            final PackageSetting ps = (PackageSetting) obj;
19230            if (ps.pkg != null) {
19231                return ps.pkg.applicationInfo.targetSdkVersion;
19232            }
19233        }
19234        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19235    }
19236
19237    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
19238        final PackageParser.Package p = mPackages.get(packageName);
19239        if (p != null) {
19240            return p.applicationInfo.targetSdkVersion;
19241        }
19242        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19243    }
19244
19245    @Override
19246    public void addPreferredActivity(IntentFilter filter, int match,
19247            ComponentName[] set, ComponentName activity, int userId) {
19248        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19249                "Adding preferred");
19250    }
19251
19252    private void addPreferredActivityInternal(IntentFilter filter, int match,
19253            ComponentName[] set, ComponentName activity, boolean always, int userId,
19254            String opname) {
19255        // writer
19256        int callingUid = Binder.getCallingUid();
19257        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19258                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19259        if (filter.countActions() == 0) {
19260            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19261            return;
19262        }
19263        synchronized (mPackages) {
19264            if (mContext.checkCallingOrSelfPermission(
19265                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19266                    != PackageManager.PERMISSION_GRANTED) {
19267                if (getUidTargetSdkVersionLockedLPr(callingUid)
19268                        < Build.VERSION_CODES.FROYO) {
19269                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19270                            + callingUid);
19271                    return;
19272                }
19273                mContext.enforceCallingOrSelfPermission(
19274                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19275            }
19276
19277            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19278            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19279                    + userId + ":");
19280            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19281            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19282            scheduleWritePackageRestrictionsLocked(userId);
19283            postPreferredActivityChangedBroadcast(userId);
19284        }
19285    }
19286
19287    private void postPreferredActivityChangedBroadcast(int userId) {
19288        mHandler.post(() -> {
19289            final IActivityManager am = ActivityManager.getService();
19290            if (am == null) {
19291                return;
19292            }
19293
19294            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19295            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19296            try {
19297                am.broadcastIntent(null, intent, null, null,
19298                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19299                        null, false, false, userId);
19300            } catch (RemoteException e) {
19301            }
19302        });
19303    }
19304
19305    @Override
19306    public void replacePreferredActivity(IntentFilter filter, int match,
19307            ComponentName[] set, ComponentName activity, int userId) {
19308        if (filter.countActions() != 1) {
19309            throw new IllegalArgumentException(
19310                    "replacePreferredActivity expects filter to have only 1 action.");
19311        }
19312        if (filter.countDataAuthorities() != 0
19313                || filter.countDataPaths() != 0
19314                || filter.countDataSchemes() > 1
19315                || filter.countDataTypes() != 0) {
19316            throw new IllegalArgumentException(
19317                    "replacePreferredActivity expects filter to have no data authorities, " +
19318                    "paths, or types; and at most one scheme.");
19319        }
19320
19321        final int callingUid = Binder.getCallingUid();
19322        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19323                true /* requireFullPermission */, false /* checkShell */,
19324                "replace preferred activity");
19325        synchronized (mPackages) {
19326            if (mContext.checkCallingOrSelfPermission(
19327                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19328                    != PackageManager.PERMISSION_GRANTED) {
19329                if (getUidTargetSdkVersionLockedLPr(callingUid)
19330                        < Build.VERSION_CODES.FROYO) {
19331                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19332                            + Binder.getCallingUid());
19333                    return;
19334                }
19335                mContext.enforceCallingOrSelfPermission(
19336                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19337            }
19338
19339            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19340            if (pir != null) {
19341                // Get all of the existing entries that exactly match this filter.
19342                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19343                if (existing != null && existing.size() == 1) {
19344                    PreferredActivity cur = existing.get(0);
19345                    if (DEBUG_PREFERRED) {
19346                        Slog.i(TAG, "Checking replace of preferred:");
19347                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19348                        if (!cur.mPref.mAlways) {
19349                            Slog.i(TAG, "  -- CUR; not mAlways!");
19350                        } else {
19351                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19352                            Slog.i(TAG, "  -- CUR: mSet="
19353                                    + Arrays.toString(cur.mPref.mSetComponents));
19354                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19355                            Slog.i(TAG, "  -- NEW: mMatch="
19356                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19357                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19358                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19359                        }
19360                    }
19361                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19362                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19363                            && cur.mPref.sameSet(set)) {
19364                        // Setting the preferred activity to what it happens to be already
19365                        if (DEBUG_PREFERRED) {
19366                            Slog.i(TAG, "Replacing with same preferred activity "
19367                                    + cur.mPref.mShortComponent + " for user "
19368                                    + userId + ":");
19369                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19370                        }
19371                        return;
19372                    }
19373                }
19374
19375                if (existing != null) {
19376                    if (DEBUG_PREFERRED) {
19377                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19378                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19379                    }
19380                    for (int i = 0; i < existing.size(); i++) {
19381                        PreferredActivity pa = existing.get(i);
19382                        if (DEBUG_PREFERRED) {
19383                            Slog.i(TAG, "Removing existing preferred activity "
19384                                    + pa.mPref.mComponent + ":");
19385                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19386                        }
19387                        pir.removeFilter(pa);
19388                    }
19389                }
19390            }
19391            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19392                    "Replacing preferred");
19393        }
19394    }
19395
19396    @Override
19397    public void clearPackagePreferredActivities(String packageName) {
19398        final int callingUid = Binder.getCallingUid();
19399        if (getInstantAppPackageName(callingUid) != null) {
19400            return;
19401        }
19402        // writer
19403        synchronized (mPackages) {
19404            PackageParser.Package pkg = mPackages.get(packageName);
19405            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19406                if (mContext.checkCallingOrSelfPermission(
19407                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19408                        != PackageManager.PERMISSION_GRANTED) {
19409                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19410                            < Build.VERSION_CODES.FROYO) {
19411                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19412                                + callingUid);
19413                        return;
19414                    }
19415                    mContext.enforceCallingOrSelfPermission(
19416                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19417                }
19418            }
19419            final PackageSetting ps = mSettings.getPackageLPr(packageName);
19420            if (ps != null
19421                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19422                return;
19423            }
19424            int user = UserHandle.getCallingUserId();
19425            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19426                scheduleWritePackageRestrictionsLocked(user);
19427            }
19428        }
19429    }
19430
19431    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19432    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19433        ArrayList<PreferredActivity> removed = null;
19434        boolean changed = false;
19435        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19436            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19437            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19438            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19439                continue;
19440            }
19441            Iterator<PreferredActivity> it = pir.filterIterator();
19442            while (it.hasNext()) {
19443                PreferredActivity pa = it.next();
19444                // Mark entry for removal only if it matches the package name
19445                // and the entry is of type "always".
19446                if (packageName == null ||
19447                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19448                                && pa.mPref.mAlways)) {
19449                    if (removed == null) {
19450                        removed = new ArrayList<PreferredActivity>();
19451                    }
19452                    removed.add(pa);
19453                }
19454            }
19455            if (removed != null) {
19456                for (int j=0; j<removed.size(); j++) {
19457                    PreferredActivity pa = removed.get(j);
19458                    pir.removeFilter(pa);
19459                }
19460                changed = true;
19461            }
19462        }
19463        if (changed) {
19464            postPreferredActivityChangedBroadcast(userId);
19465        }
19466        return changed;
19467    }
19468
19469    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19470    private void clearIntentFilterVerificationsLPw(int userId) {
19471        final int packageCount = mPackages.size();
19472        for (int i = 0; i < packageCount; i++) {
19473            PackageParser.Package pkg = mPackages.valueAt(i);
19474            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19475        }
19476    }
19477
19478    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19479    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19480        if (userId == UserHandle.USER_ALL) {
19481            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19482                    sUserManager.getUserIds())) {
19483                for (int oneUserId : sUserManager.getUserIds()) {
19484                    scheduleWritePackageRestrictionsLocked(oneUserId);
19485                }
19486            }
19487        } else {
19488            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19489                scheduleWritePackageRestrictionsLocked(userId);
19490            }
19491        }
19492    }
19493
19494    /** Clears state for all users, and touches intent filter verification policy */
19495    void clearDefaultBrowserIfNeeded(String packageName) {
19496        for (int oneUserId : sUserManager.getUserIds()) {
19497            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19498        }
19499    }
19500
19501    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19502        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19503        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19504            if (packageName.equals(defaultBrowserPackageName)) {
19505                setDefaultBrowserPackageName(null, userId);
19506            }
19507        }
19508    }
19509
19510    @Override
19511    public void resetApplicationPreferences(int userId) {
19512        mContext.enforceCallingOrSelfPermission(
19513                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19514        final long identity = Binder.clearCallingIdentity();
19515        // writer
19516        try {
19517            synchronized (mPackages) {
19518                clearPackagePreferredActivitiesLPw(null, userId);
19519                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19520                // TODO: We have to reset the default SMS and Phone. This requires
19521                // significant refactoring to keep all default apps in the package
19522                // manager (cleaner but more work) or have the services provide
19523                // callbacks to the package manager to request a default app reset.
19524                applyFactoryDefaultBrowserLPw(userId);
19525                clearIntentFilterVerificationsLPw(userId);
19526                primeDomainVerificationsLPw(userId);
19527                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19528                scheduleWritePackageRestrictionsLocked(userId);
19529            }
19530            resetNetworkPolicies(userId);
19531        } finally {
19532            Binder.restoreCallingIdentity(identity);
19533        }
19534    }
19535
19536    @Override
19537    public int getPreferredActivities(List<IntentFilter> outFilters,
19538            List<ComponentName> outActivities, String packageName) {
19539        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19540            return 0;
19541        }
19542        int num = 0;
19543        final int userId = UserHandle.getCallingUserId();
19544        // reader
19545        synchronized (mPackages) {
19546            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19547            if (pir != null) {
19548                final Iterator<PreferredActivity> it = pir.filterIterator();
19549                while (it.hasNext()) {
19550                    final PreferredActivity pa = it.next();
19551                    if (packageName == null
19552                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19553                                    && pa.mPref.mAlways)) {
19554                        if (outFilters != null) {
19555                            outFilters.add(new IntentFilter(pa));
19556                        }
19557                        if (outActivities != null) {
19558                            outActivities.add(pa.mPref.mComponent);
19559                        }
19560                    }
19561                }
19562            }
19563        }
19564
19565        return num;
19566    }
19567
19568    @Override
19569    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19570            int userId) {
19571        int callingUid = Binder.getCallingUid();
19572        if (callingUid != Process.SYSTEM_UID) {
19573            throw new SecurityException(
19574                    "addPersistentPreferredActivity can only be run by the system");
19575        }
19576        if (filter.countActions() == 0) {
19577            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19578            return;
19579        }
19580        synchronized (mPackages) {
19581            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19582                    ":");
19583            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19584            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19585                    new PersistentPreferredActivity(filter, activity));
19586            scheduleWritePackageRestrictionsLocked(userId);
19587            postPreferredActivityChangedBroadcast(userId);
19588        }
19589    }
19590
19591    @Override
19592    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19593        int callingUid = Binder.getCallingUid();
19594        if (callingUid != Process.SYSTEM_UID) {
19595            throw new SecurityException(
19596                    "clearPackagePersistentPreferredActivities can only be run by the system");
19597        }
19598        ArrayList<PersistentPreferredActivity> removed = null;
19599        boolean changed = false;
19600        synchronized (mPackages) {
19601            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19602                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19603                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19604                        .valueAt(i);
19605                if (userId != thisUserId) {
19606                    continue;
19607                }
19608                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19609                while (it.hasNext()) {
19610                    PersistentPreferredActivity ppa = it.next();
19611                    // Mark entry for removal only if it matches the package name.
19612                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19613                        if (removed == null) {
19614                            removed = new ArrayList<PersistentPreferredActivity>();
19615                        }
19616                        removed.add(ppa);
19617                    }
19618                }
19619                if (removed != null) {
19620                    for (int j=0; j<removed.size(); j++) {
19621                        PersistentPreferredActivity ppa = removed.get(j);
19622                        ppir.removeFilter(ppa);
19623                    }
19624                    changed = true;
19625                }
19626            }
19627
19628            if (changed) {
19629                scheduleWritePackageRestrictionsLocked(userId);
19630                postPreferredActivityChangedBroadcast(userId);
19631            }
19632        }
19633    }
19634
19635    /**
19636     * Common machinery for picking apart a restored XML blob and passing
19637     * it to a caller-supplied functor to be applied to the running system.
19638     */
19639    private void restoreFromXml(XmlPullParser parser, int userId,
19640            String expectedStartTag, BlobXmlRestorer functor)
19641            throws IOException, XmlPullParserException {
19642        int type;
19643        while ((type = parser.next()) != XmlPullParser.START_TAG
19644                && type != XmlPullParser.END_DOCUMENT) {
19645        }
19646        if (type != XmlPullParser.START_TAG) {
19647            // oops didn't find a start tag?!
19648            if (DEBUG_BACKUP) {
19649                Slog.e(TAG, "Didn't find start tag during restore");
19650            }
19651            return;
19652        }
19653Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19654        // this is supposed to be TAG_PREFERRED_BACKUP
19655        if (!expectedStartTag.equals(parser.getName())) {
19656            if (DEBUG_BACKUP) {
19657                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19658            }
19659            return;
19660        }
19661
19662        // skip interfering stuff, then we're aligned with the backing implementation
19663        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19664Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19665        functor.apply(parser, userId);
19666    }
19667
19668    private interface BlobXmlRestorer {
19669        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19670    }
19671
19672    /**
19673     * Non-Binder method, support for the backup/restore mechanism: write the
19674     * full set of preferred activities in its canonical XML format.  Returns the
19675     * XML output as a byte array, or null if there is none.
19676     */
19677    @Override
19678    public byte[] getPreferredActivityBackup(int userId) {
19679        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19680            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19681        }
19682
19683        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19684        try {
19685            final XmlSerializer serializer = new FastXmlSerializer();
19686            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19687            serializer.startDocument(null, true);
19688            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19689
19690            synchronized (mPackages) {
19691                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19692            }
19693
19694            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19695            serializer.endDocument();
19696            serializer.flush();
19697        } catch (Exception e) {
19698            if (DEBUG_BACKUP) {
19699                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19700            }
19701            return null;
19702        }
19703
19704        return dataStream.toByteArray();
19705    }
19706
19707    @Override
19708    public void restorePreferredActivities(byte[] backup, int userId) {
19709        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19710            throw new SecurityException("Only the system may call restorePreferredActivities()");
19711        }
19712
19713        try {
19714            final XmlPullParser parser = Xml.newPullParser();
19715            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19716            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19717                    new BlobXmlRestorer() {
19718                        @Override
19719                        public void apply(XmlPullParser parser, int userId)
19720                                throws XmlPullParserException, IOException {
19721                            synchronized (mPackages) {
19722                                mSettings.readPreferredActivitiesLPw(parser, userId);
19723                            }
19724                        }
19725                    } );
19726        } catch (Exception e) {
19727            if (DEBUG_BACKUP) {
19728                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19729            }
19730        }
19731    }
19732
19733    /**
19734     * Non-Binder method, support for the backup/restore mechanism: write the
19735     * default browser (etc) settings in its canonical XML format.  Returns the default
19736     * browser XML representation as a byte array, or null if there is none.
19737     */
19738    @Override
19739    public byte[] getDefaultAppsBackup(int userId) {
19740        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19741            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19742        }
19743
19744        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19745        try {
19746            final XmlSerializer serializer = new FastXmlSerializer();
19747            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19748            serializer.startDocument(null, true);
19749            serializer.startTag(null, TAG_DEFAULT_APPS);
19750
19751            synchronized (mPackages) {
19752                mSettings.writeDefaultAppsLPr(serializer, userId);
19753            }
19754
19755            serializer.endTag(null, TAG_DEFAULT_APPS);
19756            serializer.endDocument();
19757            serializer.flush();
19758        } catch (Exception e) {
19759            if (DEBUG_BACKUP) {
19760                Slog.e(TAG, "Unable to write default apps for backup", e);
19761            }
19762            return null;
19763        }
19764
19765        return dataStream.toByteArray();
19766    }
19767
19768    @Override
19769    public void restoreDefaultApps(byte[] backup, int userId) {
19770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19771            throw new SecurityException("Only the system may call restoreDefaultApps()");
19772        }
19773
19774        try {
19775            final XmlPullParser parser = Xml.newPullParser();
19776            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19777            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19778                    new BlobXmlRestorer() {
19779                        @Override
19780                        public void apply(XmlPullParser parser, int userId)
19781                                throws XmlPullParserException, IOException {
19782                            synchronized (mPackages) {
19783                                mSettings.readDefaultAppsLPw(parser, userId);
19784                            }
19785                        }
19786                    } );
19787        } catch (Exception e) {
19788            if (DEBUG_BACKUP) {
19789                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19790            }
19791        }
19792    }
19793
19794    @Override
19795    public byte[] getIntentFilterVerificationBackup(int userId) {
19796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19797            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19798        }
19799
19800        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19801        try {
19802            final XmlSerializer serializer = new FastXmlSerializer();
19803            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19804            serializer.startDocument(null, true);
19805            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19806
19807            synchronized (mPackages) {
19808                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19809            }
19810
19811            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19812            serializer.endDocument();
19813            serializer.flush();
19814        } catch (Exception e) {
19815            if (DEBUG_BACKUP) {
19816                Slog.e(TAG, "Unable to write default apps for backup", e);
19817            }
19818            return null;
19819        }
19820
19821        return dataStream.toByteArray();
19822    }
19823
19824    @Override
19825    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19826        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19827            throw new SecurityException("Only the system may call restorePreferredActivities()");
19828        }
19829
19830        try {
19831            final XmlPullParser parser = Xml.newPullParser();
19832            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19833            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19834                    new BlobXmlRestorer() {
19835                        @Override
19836                        public void apply(XmlPullParser parser, int userId)
19837                                throws XmlPullParserException, IOException {
19838                            synchronized (mPackages) {
19839                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19840                                mSettings.writeLPr();
19841                            }
19842                        }
19843                    } );
19844        } catch (Exception e) {
19845            if (DEBUG_BACKUP) {
19846                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19847            }
19848        }
19849    }
19850
19851    @Override
19852    public byte[] getPermissionGrantBackup(int userId) {
19853        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19854            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19855        }
19856
19857        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19858        try {
19859            final XmlSerializer serializer = new FastXmlSerializer();
19860            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19861            serializer.startDocument(null, true);
19862            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19863
19864            synchronized (mPackages) {
19865                serializeRuntimePermissionGrantsLPr(serializer, userId);
19866            }
19867
19868            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19869            serializer.endDocument();
19870            serializer.flush();
19871        } catch (Exception e) {
19872            if (DEBUG_BACKUP) {
19873                Slog.e(TAG, "Unable to write default apps for backup", e);
19874            }
19875            return null;
19876        }
19877
19878        return dataStream.toByteArray();
19879    }
19880
19881    @Override
19882    public void restorePermissionGrants(byte[] backup, int userId) {
19883        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19884            throw new SecurityException("Only the system may call restorePermissionGrants()");
19885        }
19886
19887        try {
19888            final XmlPullParser parser = Xml.newPullParser();
19889            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19890            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19891                    new BlobXmlRestorer() {
19892                        @Override
19893                        public void apply(XmlPullParser parser, int userId)
19894                                throws XmlPullParserException, IOException {
19895                            synchronized (mPackages) {
19896                                processRestoredPermissionGrantsLPr(parser, userId);
19897                            }
19898                        }
19899                    } );
19900        } catch (Exception e) {
19901            if (DEBUG_BACKUP) {
19902                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19903            }
19904        }
19905    }
19906
19907    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19908            throws IOException {
19909        serializer.startTag(null, TAG_ALL_GRANTS);
19910
19911        final int N = mSettings.mPackages.size();
19912        for (int i = 0; i < N; i++) {
19913            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19914            boolean pkgGrantsKnown = false;
19915
19916            PermissionsState packagePerms = ps.getPermissionsState();
19917
19918            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19919                final int grantFlags = state.getFlags();
19920                // only look at grants that are not system/policy fixed
19921                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19922                    final boolean isGranted = state.isGranted();
19923                    // And only back up the user-twiddled state bits
19924                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19925                        final String packageName = mSettings.mPackages.keyAt(i);
19926                        if (!pkgGrantsKnown) {
19927                            serializer.startTag(null, TAG_GRANT);
19928                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19929                            pkgGrantsKnown = true;
19930                        }
19931
19932                        final boolean userSet =
19933                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19934                        final boolean userFixed =
19935                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19936                        final boolean revoke =
19937                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19938
19939                        serializer.startTag(null, TAG_PERMISSION);
19940                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19941                        if (isGranted) {
19942                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19943                        }
19944                        if (userSet) {
19945                            serializer.attribute(null, ATTR_USER_SET, "true");
19946                        }
19947                        if (userFixed) {
19948                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19949                        }
19950                        if (revoke) {
19951                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19952                        }
19953                        serializer.endTag(null, TAG_PERMISSION);
19954                    }
19955                }
19956            }
19957
19958            if (pkgGrantsKnown) {
19959                serializer.endTag(null, TAG_GRANT);
19960            }
19961        }
19962
19963        serializer.endTag(null, TAG_ALL_GRANTS);
19964    }
19965
19966    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19967            throws XmlPullParserException, IOException {
19968        String pkgName = null;
19969        int outerDepth = parser.getDepth();
19970        int type;
19971        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19972                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19973            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19974                continue;
19975            }
19976
19977            final String tagName = parser.getName();
19978            if (tagName.equals(TAG_GRANT)) {
19979                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19980                if (DEBUG_BACKUP) {
19981                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19982                }
19983            } else if (tagName.equals(TAG_PERMISSION)) {
19984
19985                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19986                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19987
19988                int newFlagSet = 0;
19989                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19990                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19991                }
19992                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19993                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19994                }
19995                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19996                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19997                }
19998                if (DEBUG_BACKUP) {
19999                    Slog.v(TAG, "  + Restoring grant:"
20000                            + " pkg=" + pkgName
20001                            + " perm=" + permName
20002                            + " granted=" + isGranted
20003                            + " bits=0x" + Integer.toHexString(newFlagSet));
20004                }
20005                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20006                if (ps != null) {
20007                    // Already installed so we apply the grant immediately
20008                    if (DEBUG_BACKUP) {
20009                        Slog.v(TAG, "        + already installed; applying");
20010                    }
20011                    PermissionsState perms = ps.getPermissionsState();
20012                    BasePermission bp =
20013                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
20014                    if (bp != null) {
20015                        if (isGranted) {
20016                            perms.grantRuntimePermission(bp, userId);
20017                        }
20018                        if (newFlagSet != 0) {
20019                            perms.updatePermissionFlags(
20020                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20021                        }
20022                    }
20023                } else {
20024                    // Need to wait for post-restore install to apply the grant
20025                    if (DEBUG_BACKUP) {
20026                        Slog.v(TAG, "        - not yet installed; saving for later");
20027                    }
20028                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20029                            isGranted, newFlagSet, userId);
20030                }
20031            } else {
20032                PackageManagerService.reportSettingsProblem(Log.WARN,
20033                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20034                XmlUtils.skipCurrentTag(parser);
20035            }
20036        }
20037
20038        scheduleWriteSettingsLocked();
20039        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20040    }
20041
20042    @Override
20043    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20044            int sourceUserId, int targetUserId, int flags) {
20045        mContext.enforceCallingOrSelfPermission(
20046                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20047        int callingUid = Binder.getCallingUid();
20048        enforceOwnerRights(ownerPackage, callingUid);
20049        PackageManagerServiceUtils.enforceShellRestriction(
20050                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20051        if (intentFilter.countActions() == 0) {
20052            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20053            return;
20054        }
20055        synchronized (mPackages) {
20056            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20057                    ownerPackage, targetUserId, flags);
20058            CrossProfileIntentResolver resolver =
20059                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20060            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20061            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20062            if (existing != null) {
20063                int size = existing.size();
20064                for (int i = 0; i < size; i++) {
20065                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20066                        return;
20067                    }
20068                }
20069            }
20070            resolver.addFilter(newFilter);
20071            scheduleWritePackageRestrictionsLocked(sourceUserId);
20072        }
20073    }
20074
20075    @Override
20076    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20077        mContext.enforceCallingOrSelfPermission(
20078                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20079        final int callingUid = Binder.getCallingUid();
20080        enforceOwnerRights(ownerPackage, callingUid);
20081        PackageManagerServiceUtils.enforceShellRestriction(
20082                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20083        synchronized (mPackages) {
20084            CrossProfileIntentResolver resolver =
20085                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20086            ArraySet<CrossProfileIntentFilter> set =
20087                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20088            for (CrossProfileIntentFilter filter : set) {
20089                if (filter.getOwnerPackage().equals(ownerPackage)) {
20090                    resolver.removeFilter(filter);
20091                }
20092            }
20093            scheduleWritePackageRestrictionsLocked(sourceUserId);
20094        }
20095    }
20096
20097    // Enforcing that callingUid is owning pkg on userId
20098    private void enforceOwnerRights(String pkg, int callingUid) {
20099        // The system owns everything.
20100        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20101            return;
20102        }
20103        final int callingUserId = UserHandle.getUserId(callingUid);
20104        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20105        if (pi == null) {
20106            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20107                    + callingUserId);
20108        }
20109        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20110            throw new SecurityException("Calling uid " + callingUid
20111                    + " does not own package " + pkg);
20112        }
20113    }
20114
20115    @Override
20116    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20117        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20118            return null;
20119        }
20120        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20121    }
20122
20123    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20124        UserManagerService ums = UserManagerService.getInstance();
20125        if (ums != null) {
20126            final UserInfo parent = ums.getProfileParent(userId);
20127            final int launcherUid = (parent != null) ? parent.id : userId;
20128            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20129            if (launcherComponent != null) {
20130                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20131                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20132                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20133                        .setPackage(launcherComponent.getPackageName());
20134                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20135            }
20136        }
20137    }
20138
20139    /**
20140     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20141     * then reports the most likely home activity or null if there are more than one.
20142     */
20143    private ComponentName getDefaultHomeActivity(int userId) {
20144        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20145        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20146        if (cn != null) {
20147            return cn;
20148        }
20149
20150        // Find the launcher with the highest priority and return that component if there are no
20151        // other home activity with the same priority.
20152        int lastPriority = Integer.MIN_VALUE;
20153        ComponentName lastComponent = null;
20154        final int size = allHomeCandidates.size();
20155        for (int i = 0; i < size; i++) {
20156            final ResolveInfo ri = allHomeCandidates.get(i);
20157            if (ri.priority > lastPriority) {
20158                lastComponent = ri.activityInfo.getComponentName();
20159                lastPriority = ri.priority;
20160            } else if (ri.priority == lastPriority) {
20161                // Two components found with same priority.
20162                lastComponent = null;
20163            }
20164        }
20165        return lastComponent;
20166    }
20167
20168    private Intent getHomeIntent() {
20169        Intent intent = new Intent(Intent.ACTION_MAIN);
20170        intent.addCategory(Intent.CATEGORY_HOME);
20171        intent.addCategory(Intent.CATEGORY_DEFAULT);
20172        return intent;
20173    }
20174
20175    private IntentFilter getHomeFilter() {
20176        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20177        filter.addCategory(Intent.CATEGORY_HOME);
20178        filter.addCategory(Intent.CATEGORY_DEFAULT);
20179        return filter;
20180    }
20181
20182    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20183            int userId) {
20184        Intent intent  = getHomeIntent();
20185        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20186                PackageManager.GET_META_DATA, userId);
20187        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20188                true, false, false, userId);
20189
20190        allHomeCandidates.clear();
20191        if (list != null) {
20192            for (ResolveInfo ri : list) {
20193                allHomeCandidates.add(ri);
20194            }
20195        }
20196        return (preferred == null || preferred.activityInfo == null)
20197                ? null
20198                : new ComponentName(preferred.activityInfo.packageName,
20199                        preferred.activityInfo.name);
20200    }
20201
20202    @Override
20203    public void setHomeActivity(ComponentName comp, int userId) {
20204        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20205            return;
20206        }
20207        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20208        getHomeActivitiesAsUser(homeActivities, userId);
20209
20210        boolean found = false;
20211
20212        final int size = homeActivities.size();
20213        final ComponentName[] set = new ComponentName[size];
20214        for (int i = 0; i < size; i++) {
20215            final ResolveInfo candidate = homeActivities.get(i);
20216            final ActivityInfo info = candidate.activityInfo;
20217            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20218            set[i] = activityName;
20219            if (!found && activityName.equals(comp)) {
20220                found = true;
20221            }
20222        }
20223        if (!found) {
20224            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20225                    + userId);
20226        }
20227        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20228                set, comp, userId);
20229    }
20230
20231    private @Nullable String getSetupWizardPackageName() {
20232        final Intent intent = new Intent(Intent.ACTION_MAIN);
20233        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20234
20235        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20236                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20237                        | MATCH_DISABLED_COMPONENTS,
20238                UserHandle.myUserId());
20239        if (matches.size() == 1) {
20240            return matches.get(0).getComponentInfo().packageName;
20241        } else {
20242            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20243                    + ": matches=" + matches);
20244            return null;
20245        }
20246    }
20247
20248    private @Nullable String getStorageManagerPackageName() {
20249        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20250
20251        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20252                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20253                        | MATCH_DISABLED_COMPONENTS,
20254                UserHandle.myUserId());
20255        if (matches.size() == 1) {
20256            return matches.get(0).getComponentInfo().packageName;
20257        } else {
20258            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20259                    + matches.size() + ": matches=" + matches);
20260            return null;
20261        }
20262    }
20263
20264    @Override
20265    public String getSystemTextClassifierPackageName() {
20266        return mContext.getString(R.string.config_defaultTextClassifierPackage);
20267    }
20268
20269    @Override
20270    public void setApplicationEnabledSetting(String appPackageName,
20271            int newState, int flags, int userId, String callingPackage) {
20272        if (!sUserManager.exists(userId)) return;
20273        if (callingPackage == null) {
20274            callingPackage = Integer.toString(Binder.getCallingUid());
20275        }
20276        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20277    }
20278
20279    @Override
20280    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20281        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20282        synchronized (mPackages) {
20283            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20284            if (pkgSetting != null) {
20285                pkgSetting.setUpdateAvailable(updateAvailable);
20286            }
20287        }
20288    }
20289
20290    @Override
20291    public void setComponentEnabledSetting(ComponentName componentName,
20292            int newState, int flags, int userId) {
20293        if (!sUserManager.exists(userId)) return;
20294        setEnabledSetting(componentName.getPackageName(),
20295                componentName.getClassName(), newState, flags, userId, null);
20296    }
20297
20298    private void setEnabledSetting(final String packageName, String className, int newState,
20299            final int flags, int userId, String callingPackage) {
20300        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20301              || newState == COMPONENT_ENABLED_STATE_ENABLED
20302              || newState == COMPONENT_ENABLED_STATE_DISABLED
20303              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20304              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20305            throw new IllegalArgumentException("Invalid new component state: "
20306                    + newState);
20307        }
20308        PackageSetting pkgSetting;
20309        final int callingUid = Binder.getCallingUid();
20310        final int permission;
20311        if (callingUid == Process.SYSTEM_UID) {
20312            permission = PackageManager.PERMISSION_GRANTED;
20313        } else {
20314            permission = mContext.checkCallingOrSelfPermission(
20315                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20316        }
20317        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20318                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20319        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20320        boolean sendNow = false;
20321        boolean isApp = (className == null);
20322        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20323        String componentName = isApp ? packageName : className;
20324        int packageUid = -1;
20325        ArrayList<String> components;
20326
20327        // reader
20328        synchronized (mPackages) {
20329            pkgSetting = mSettings.mPackages.get(packageName);
20330            if (pkgSetting == null) {
20331                if (!isCallerInstantApp) {
20332                    if (className == null) {
20333                        throw new IllegalArgumentException("Unknown package: " + packageName);
20334                    }
20335                    throw new IllegalArgumentException(
20336                            "Unknown component: " + packageName + "/" + className);
20337                } else {
20338                    // throw SecurityException to prevent leaking package information
20339                    throw new SecurityException(
20340                            "Attempt to change component state; "
20341                            + "pid=" + Binder.getCallingPid()
20342                            + ", uid=" + callingUid
20343                            + (className == null
20344                                    ? ", package=" + packageName
20345                                    : ", component=" + packageName + "/" + className));
20346                }
20347            }
20348        }
20349
20350        // Limit who can change which apps
20351        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20352            // Don't allow apps that don't have permission to modify other apps
20353            if (!allowedByPermission
20354                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20355                throw new SecurityException(
20356                        "Attempt to change component state; "
20357                        + "pid=" + Binder.getCallingPid()
20358                        + ", uid=" + callingUid
20359                        + (className == null
20360                                ? ", package=" + packageName
20361                                : ", component=" + packageName + "/" + className));
20362            }
20363            // Don't allow changing protected packages.
20364            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20365                throw new SecurityException("Cannot disable a protected package: " + packageName);
20366            }
20367        }
20368
20369        synchronized (mPackages) {
20370            if (callingUid == Process.SHELL_UID
20371                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20372                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20373                // unless it is a test package.
20374                int oldState = pkgSetting.getEnabled(userId);
20375                if (className == null
20376                        &&
20377                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20378                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20379                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20380                        &&
20381                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20382                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
20383                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20384                    // ok
20385                } else {
20386                    throw new SecurityException(
20387                            "Shell cannot change component state for " + packageName + "/"
20388                                    + className + " to " + newState);
20389                }
20390            }
20391        }
20392        if (className == null) {
20393            // We're dealing with an application/package level state change
20394            synchronized (mPackages) {
20395                if (pkgSetting.getEnabled(userId) == newState) {
20396                    // Nothing to do
20397                    return;
20398                }
20399            }
20400            // If we're enabling a system stub, there's a little more work to do.
20401            // Prior to enabling the package, we need to decompress the APK(s) to the
20402            // data partition and then replace the version on the system partition.
20403            final PackageParser.Package deletedPkg = pkgSetting.pkg;
20404            final boolean isSystemStub = deletedPkg.isStub
20405                    && deletedPkg.isSystem();
20406            if (isSystemStub
20407                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20408                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20409                final File codePath = decompressPackage(deletedPkg);
20410                if (codePath == null) {
20411                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20412                    return;
20413                }
20414                // TODO remove direct parsing of the package object during internal cleanup
20415                // of scan package
20416                // We need to call parse directly here for no other reason than we need
20417                // the new package in order to disable the old one [we use the information
20418                // for some internal optimization to optionally create a new package setting
20419                // object on replace]. However, we can't get the package from the scan
20420                // because the scan modifies live structures and we need to remove the
20421                // old [system] package from the system before a scan can be attempted.
20422                // Once scan is indempotent we can remove this parse and use the package
20423                // object we scanned, prior to adding it to package settings.
20424                final PackageParser pp = new PackageParser();
20425                pp.setSeparateProcesses(mSeparateProcesses);
20426                pp.setDisplayMetrics(mMetrics);
20427                pp.setCallback(mPackageParserCallback);
20428                final PackageParser.Package tmpPkg;
20429                try {
20430                    final @ParseFlags int parseFlags = mDefParseFlags
20431                            | PackageParser.PARSE_MUST_BE_APK
20432                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20433                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20434                } catch (PackageParserException e) {
20435                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20436                    return;
20437                }
20438                synchronized (mInstallLock) {
20439                    // Disable the stub and remove any package entries
20440                    removePackageLI(deletedPkg, true);
20441                    synchronized (mPackages) {
20442                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20443                    }
20444                    final PackageParser.Package pkg;
20445                    try (PackageFreezer freezer =
20446                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20447                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20448                                | PackageParser.PARSE_ENFORCE_CODE;
20449                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20450                                0 /*currentTime*/, null /*user*/);
20451                        prepareAppDataAfterInstallLIF(pkg);
20452                        synchronized (mPackages) {
20453                            try {
20454                                updateSharedLibrariesLPr(pkg, null);
20455                            } catch (PackageManagerException e) {
20456                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20457                            }
20458                            mPermissionManager.updatePermissions(
20459                                    pkg.packageName, pkg, true, mPackages.values(),
20460                                    mPermissionCallback);
20461                            mSettings.writeLPr();
20462                        }
20463                    } catch (PackageManagerException e) {
20464                        // Whoops! Something went wrong; try to roll back to the stub
20465                        Slog.w(TAG, "Failed to install compressed system package:"
20466                                + pkgSetting.name, e);
20467                        // Remove the failed install
20468                        removeCodePathLI(codePath);
20469
20470                        // Install the system package
20471                        try (PackageFreezer freezer =
20472                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20473                            synchronized (mPackages) {
20474                                // NOTE: The system package always needs to be enabled; even
20475                                // if it's for a compressed stub. If we don't, installing the
20476                                // system package fails during scan [scanning checks the disabled
20477                                // packages]. We will reverse this later, after we've "installed"
20478                                // the stub.
20479                                // This leaves us in a fragile state; the stub should never be
20480                                // enabled, so, cross your fingers and hope nothing goes wrong
20481                                // until we can disable the package later.
20482                                enableSystemPackageLPw(deletedPkg);
20483                            }
20484                            installPackageFromSystemLIF(deletedPkg.codePath,
20485                                    false /*isPrivileged*/, null /*allUserHandles*/,
20486                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20487                                    true /*writeSettings*/);
20488                        } catch (PackageManagerException pme) {
20489                            Slog.w(TAG, "Failed to restore system package:"
20490                                    + deletedPkg.packageName, pme);
20491                        } finally {
20492                            synchronized (mPackages) {
20493                                mSettings.disableSystemPackageLPw(
20494                                        deletedPkg.packageName, true /*replaced*/);
20495                                mSettings.writeLPr();
20496                            }
20497                        }
20498                        return;
20499                    }
20500                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20501                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20502                    mDexManager.notifyPackageUpdated(pkg.packageName,
20503                            pkg.baseCodePath, pkg.splitCodePaths);
20504                }
20505            }
20506            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20507                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20508                // Don't care about who enables an app.
20509                callingPackage = null;
20510            }
20511            synchronized (mPackages) {
20512                pkgSetting.setEnabled(newState, userId, callingPackage);
20513            }
20514        } else {
20515            synchronized (mPackages) {
20516                // We're dealing with a component level state change
20517                // First, verify that this is a valid class name.
20518                PackageParser.Package pkg = pkgSetting.pkg;
20519                if (pkg == null || !pkg.hasComponentClassName(className)) {
20520                    if (pkg != null &&
20521                            pkg.applicationInfo.targetSdkVersion >=
20522                                    Build.VERSION_CODES.JELLY_BEAN) {
20523                        throw new IllegalArgumentException("Component class " + className
20524                                + " does not exist in " + packageName);
20525                    } else {
20526                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20527                                + className + " does not exist in " + packageName);
20528                    }
20529                }
20530                switch (newState) {
20531                    case COMPONENT_ENABLED_STATE_ENABLED:
20532                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20533                            return;
20534                        }
20535                        break;
20536                    case COMPONENT_ENABLED_STATE_DISABLED:
20537                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20538                            return;
20539                        }
20540                        break;
20541                    case COMPONENT_ENABLED_STATE_DEFAULT:
20542                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20543                            return;
20544                        }
20545                        break;
20546                    default:
20547                        Slog.e(TAG, "Invalid new component state: " + newState);
20548                        return;
20549                }
20550            }
20551        }
20552        synchronized (mPackages) {
20553            scheduleWritePackageRestrictionsLocked(userId);
20554            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20555            final long callingId = Binder.clearCallingIdentity();
20556            try {
20557                updateInstantAppInstallerLocked(packageName);
20558            } finally {
20559                Binder.restoreCallingIdentity(callingId);
20560            }
20561            components = mPendingBroadcasts.get(userId, packageName);
20562            final boolean newPackage = components == null;
20563            if (newPackage) {
20564                components = new ArrayList<String>();
20565            }
20566            if (!components.contains(componentName)) {
20567                components.add(componentName);
20568            }
20569            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20570                sendNow = true;
20571                // Purge entry from pending broadcast list if another one exists already
20572                // since we are sending one right away.
20573                mPendingBroadcasts.remove(userId, packageName);
20574            } else {
20575                if (newPackage) {
20576                    mPendingBroadcasts.put(userId, packageName, components);
20577                }
20578                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20579                    // Schedule a message
20580                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20581                }
20582            }
20583        }
20584
20585        long callingId = Binder.clearCallingIdentity();
20586        try {
20587            if (sendNow) {
20588                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20589                sendPackageChangedBroadcast(packageName,
20590                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20591            }
20592        } finally {
20593            Binder.restoreCallingIdentity(callingId);
20594        }
20595    }
20596
20597    @Override
20598    public void flushPackageRestrictionsAsUser(int userId) {
20599        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20600            return;
20601        }
20602        if (!sUserManager.exists(userId)) {
20603            return;
20604        }
20605        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20606                false /* checkShell */, "flushPackageRestrictions");
20607        synchronized (mPackages) {
20608            mSettings.writePackageRestrictionsLPr(userId);
20609            mDirtyUsers.remove(userId);
20610            if (mDirtyUsers.isEmpty()) {
20611                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20612            }
20613        }
20614    }
20615
20616    private void sendPackageChangedBroadcast(String packageName,
20617            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20618        if (DEBUG_INSTALL)
20619            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20620                    + componentNames);
20621        Bundle extras = new Bundle(4);
20622        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20623        String nameList[] = new String[componentNames.size()];
20624        componentNames.toArray(nameList);
20625        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20626        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20627        extras.putInt(Intent.EXTRA_UID, packageUid);
20628        // If this is not reporting a change of the overall package, then only send it
20629        // to registered receivers.  We don't want to launch a swath of apps for every
20630        // little component state change.
20631        final int flags = !componentNames.contains(packageName)
20632                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20633        final int userId = UserHandle.getUserId(packageUid);
20634        final boolean isInstantApp = isInstantApp(packageName, userId);
20635        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20636        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20637        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20638                userIds, instantUserIds);
20639    }
20640
20641    @Override
20642    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20643        if (!sUserManager.exists(userId)) return;
20644        final int callingUid = Binder.getCallingUid();
20645        if (getInstantAppPackageName(callingUid) != null) {
20646            return;
20647        }
20648        final int permission = mContext.checkCallingOrSelfPermission(
20649                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20650        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20651        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20652                true /* requireFullPermission */, true /* checkShell */, "stop package");
20653        // writer
20654        synchronized (mPackages) {
20655            final PackageSetting ps = mSettings.mPackages.get(packageName);
20656            if (!filterAppAccessLPr(ps, callingUid, userId)
20657                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20658                            allowedByPermission, callingUid, userId)) {
20659                scheduleWritePackageRestrictionsLocked(userId);
20660            }
20661        }
20662    }
20663
20664    @Override
20665    public String getInstallerPackageName(String packageName) {
20666        final int callingUid = Binder.getCallingUid();
20667        synchronized (mPackages) {
20668            final PackageSetting ps = mSettings.mPackages.get(packageName);
20669            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20670                return null;
20671            }
20672            return mSettings.getInstallerPackageNameLPr(packageName);
20673        }
20674    }
20675
20676    public boolean isOrphaned(String packageName) {
20677        // reader
20678        synchronized (mPackages) {
20679            return mSettings.isOrphaned(packageName);
20680        }
20681    }
20682
20683    @Override
20684    public int getApplicationEnabledSetting(String packageName, int userId) {
20685        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20686        int callingUid = Binder.getCallingUid();
20687        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20688                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20689        // reader
20690        synchronized (mPackages) {
20691            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20692                return COMPONENT_ENABLED_STATE_DISABLED;
20693            }
20694            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20695        }
20696    }
20697
20698    @Override
20699    public int getComponentEnabledSetting(ComponentName component, int userId) {
20700        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20701        int callingUid = Binder.getCallingUid();
20702        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20703                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20704        synchronized (mPackages) {
20705            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20706                    component, TYPE_UNKNOWN, userId)) {
20707                return COMPONENT_ENABLED_STATE_DISABLED;
20708            }
20709            return mSettings.getComponentEnabledSettingLPr(component, userId);
20710        }
20711    }
20712
20713    @Override
20714    public void enterSafeMode() {
20715        enforceSystemOrRoot("Only the system can request entering safe mode");
20716
20717        if (!mSystemReady) {
20718            mSafeMode = true;
20719        }
20720    }
20721
20722    @Override
20723    public void systemReady() {
20724        enforceSystemOrRoot("Only the system can claim the system is ready");
20725
20726        mSystemReady = true;
20727        final ContentResolver resolver = mContext.getContentResolver();
20728        ContentObserver co = new ContentObserver(mHandler) {
20729            @Override
20730            public void onChange(boolean selfChange) {
20731                mWebInstantAppsDisabled =
20732                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20733                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20734            }
20735        };
20736        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20737                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20738                false, co, UserHandle.USER_SYSTEM);
20739        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20740                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20741        co.onChange(true);
20742
20743        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20744        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20745        // it is done.
20746        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20747            @Override
20748            public void onChange(boolean selfChange) {
20749                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20750                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20751                        oobEnabled == 1 ? "true" : "false");
20752            }
20753        };
20754        mContext.getContentResolver().registerContentObserver(
20755                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20756                UserHandle.USER_SYSTEM);
20757        // At boot, restore the value from the setting, which persists across reboot.
20758        privAppOobObserver.onChange(true);
20759
20760        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20761        // disabled after already being started.
20762        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20763                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20764
20765        // Read the compatibilty setting when the system is ready.
20766        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20767                mContext.getContentResolver(),
20768                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20769        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20770        if (DEBUG_SETTINGS) {
20771            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20772        }
20773
20774        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20775
20776        synchronized (mPackages) {
20777            // Verify that all of the preferred activity components actually
20778            // exist.  It is possible for applications to be updated and at
20779            // that point remove a previously declared activity component that
20780            // had been set as a preferred activity.  We try to clean this up
20781            // the next time we encounter that preferred activity, but it is
20782            // possible for the user flow to never be able to return to that
20783            // situation so here we do a sanity check to make sure we haven't
20784            // left any junk around.
20785            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20786            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20787                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20788                removed.clear();
20789                for (PreferredActivity pa : pir.filterSet()) {
20790                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20791                        removed.add(pa);
20792                    }
20793                }
20794                if (removed.size() > 0) {
20795                    for (int r=0; r<removed.size(); r++) {
20796                        PreferredActivity pa = removed.get(r);
20797                        Slog.w(TAG, "Removing dangling preferred activity: "
20798                                + pa.mPref.mComponent);
20799                        pir.removeFilter(pa);
20800                    }
20801                    mSettings.writePackageRestrictionsLPr(
20802                            mSettings.mPreferredActivities.keyAt(i));
20803                }
20804            }
20805
20806            for (int userId : UserManagerService.getInstance().getUserIds()) {
20807                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20808                    grantPermissionsUserIds = ArrayUtils.appendInt(
20809                            grantPermissionsUserIds, userId);
20810                }
20811            }
20812        }
20813        sUserManager.systemReady();
20814        // If we upgraded grant all default permissions before kicking off.
20815        for (int userId : grantPermissionsUserIds) {
20816            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20817        }
20818
20819        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20820            // If we did not grant default permissions, we preload from this the
20821            // default permission exceptions lazily to ensure we don't hit the
20822            // disk on a new user creation.
20823            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20824        }
20825
20826        // Now that we've scanned all packages, and granted any default
20827        // permissions, ensure permissions are updated. Beware of dragons if you
20828        // try optimizing this.
20829        synchronized (mPackages) {
20830            mPermissionManager.updateAllPermissions(
20831                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20832                    mPermissionCallback);
20833        }
20834
20835        // Kick off any messages waiting for system ready
20836        if (mPostSystemReadyMessages != null) {
20837            for (Message msg : mPostSystemReadyMessages) {
20838                msg.sendToTarget();
20839            }
20840            mPostSystemReadyMessages = null;
20841        }
20842
20843        // Watch for external volumes that come and go over time
20844        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20845        storage.registerListener(mStorageListener);
20846
20847        mInstallerService.systemReady();
20848        mPackageDexOptimizer.systemReady();
20849
20850        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20851                StorageManagerInternal.class);
20852        StorageManagerInternal.addExternalStoragePolicy(
20853                new StorageManagerInternal.ExternalStorageMountPolicy() {
20854            @Override
20855            public int getMountMode(int uid, String packageName) {
20856                if (Process.isIsolated(uid)) {
20857                    return Zygote.MOUNT_EXTERNAL_NONE;
20858                }
20859                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20860                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20861                }
20862                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20863                    return Zygote.MOUNT_EXTERNAL_READ;
20864                }
20865                return Zygote.MOUNT_EXTERNAL_WRITE;
20866            }
20867
20868            @Override
20869            public boolean hasExternalStorage(int uid, String packageName) {
20870                return true;
20871            }
20872        });
20873
20874        // Now that we're mostly running, clean up stale users and apps
20875        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20876        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20877
20878        mPermissionManager.systemReady();
20879
20880        if (mInstantAppResolverConnection != null) {
20881            mContext.registerReceiver(new BroadcastReceiver() {
20882                @Override
20883                public void onReceive(Context context, Intent intent) {
20884                    mInstantAppResolverConnection.optimisticBind();
20885                    mContext.unregisterReceiver(this);
20886                }
20887            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20888        }
20889    }
20890
20891    public void waitForAppDataPrepared() {
20892        if (mPrepareAppDataFuture == null) {
20893            return;
20894        }
20895        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20896        mPrepareAppDataFuture = null;
20897    }
20898
20899    @Override
20900    public boolean isSafeMode() {
20901        // allow instant applications
20902        return mSafeMode;
20903    }
20904
20905    @Override
20906    public boolean hasSystemUidErrors() {
20907        // allow instant applications
20908        return mHasSystemUidErrors;
20909    }
20910
20911    static String arrayToString(int[] array) {
20912        StringBuffer buf = new StringBuffer(128);
20913        buf.append('[');
20914        if (array != null) {
20915            for (int i=0; i<array.length; i++) {
20916                if (i > 0) buf.append(", ");
20917                buf.append(array[i]);
20918            }
20919        }
20920        buf.append(']');
20921        return buf.toString();
20922    }
20923
20924    @Override
20925    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20926            FileDescriptor err, String[] args, ShellCallback callback,
20927            ResultReceiver resultReceiver) {
20928        (new PackageManagerShellCommand(this)).exec(
20929                this, in, out, err, args, callback, resultReceiver);
20930    }
20931
20932    @Override
20933    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20934        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20935
20936        DumpState dumpState = new DumpState();
20937        boolean fullPreferred = false;
20938        boolean checkin = false;
20939
20940        String packageName = null;
20941        ArraySet<String> permissionNames = null;
20942
20943        int opti = 0;
20944        while (opti < args.length) {
20945            String opt = args[opti];
20946            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20947                break;
20948            }
20949            opti++;
20950
20951            if ("-a".equals(opt)) {
20952                // Right now we only know how to print all.
20953            } else if ("-h".equals(opt)) {
20954                pw.println("Package manager dump options:");
20955                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20956                pw.println("    --checkin: dump for a checkin");
20957                pw.println("    -f: print details of intent filters");
20958                pw.println("    -h: print this help");
20959                pw.println("  cmd may be one of:");
20960                pw.println("    l[ibraries]: list known shared libraries");
20961                pw.println("    f[eatures]: list device features");
20962                pw.println("    k[eysets]: print known keysets");
20963                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20964                pw.println("    perm[issions]: dump permissions");
20965                pw.println("    permission [name ...]: dump declaration and use of given permission");
20966                pw.println("    pref[erred]: print preferred package settings");
20967                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20968                pw.println("    prov[iders]: dump content providers");
20969                pw.println("    p[ackages]: dump installed packages");
20970                pw.println("    s[hared-users]: dump shared user IDs");
20971                pw.println("    m[essages]: print collected runtime messages");
20972                pw.println("    v[erifiers]: print package verifier info");
20973                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20974                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20975                pw.println("    version: print database version info");
20976                pw.println("    write: write current settings now");
20977                pw.println("    installs: details about install sessions");
20978                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20979                pw.println("    dexopt: dump dexopt state");
20980                pw.println("    compiler-stats: dump compiler statistics");
20981                pw.println("    service-permissions: dump permissions required by services");
20982                pw.println("    <package.name>: info about given package");
20983                return;
20984            } else if ("--checkin".equals(opt)) {
20985                checkin = true;
20986            } else if ("-f".equals(opt)) {
20987                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20988            } else if ("--proto".equals(opt)) {
20989                dumpProto(fd);
20990                return;
20991            } else {
20992                pw.println("Unknown argument: " + opt + "; use -h for help");
20993            }
20994        }
20995
20996        // Is the caller requesting to dump a particular piece of data?
20997        if (opti < args.length) {
20998            String cmd = args[opti];
20999            opti++;
21000            // Is this a package name?
21001            if ("android".equals(cmd) || cmd.contains(".")) {
21002                packageName = cmd;
21003                // When dumping a single package, we always dump all of its
21004                // filter information since the amount of data will be reasonable.
21005                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21006            } else if ("check-permission".equals(cmd)) {
21007                if (opti >= args.length) {
21008                    pw.println("Error: check-permission missing permission argument");
21009                    return;
21010                }
21011                String perm = args[opti];
21012                opti++;
21013                if (opti >= args.length) {
21014                    pw.println("Error: check-permission missing package argument");
21015                    return;
21016                }
21017
21018                String pkg = args[opti];
21019                opti++;
21020                int user = UserHandle.getUserId(Binder.getCallingUid());
21021                if (opti < args.length) {
21022                    try {
21023                        user = Integer.parseInt(args[opti]);
21024                    } catch (NumberFormatException e) {
21025                        pw.println("Error: check-permission user argument is not a number: "
21026                                + args[opti]);
21027                        return;
21028                    }
21029                }
21030
21031                // Normalize package name to handle renamed packages and static libs
21032                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21033
21034                pw.println(checkPermission(perm, pkg, user));
21035                return;
21036            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21037                dumpState.setDump(DumpState.DUMP_LIBS);
21038            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21039                dumpState.setDump(DumpState.DUMP_FEATURES);
21040            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21041                if (opti >= args.length) {
21042                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21043                            | DumpState.DUMP_SERVICE_RESOLVERS
21044                            | DumpState.DUMP_RECEIVER_RESOLVERS
21045                            | DumpState.DUMP_CONTENT_RESOLVERS);
21046                } else {
21047                    while (opti < args.length) {
21048                        String name = args[opti];
21049                        if ("a".equals(name) || "activity".equals(name)) {
21050                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21051                        } else if ("s".equals(name) || "service".equals(name)) {
21052                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21053                        } else if ("r".equals(name) || "receiver".equals(name)) {
21054                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21055                        } else if ("c".equals(name) || "content".equals(name)) {
21056                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21057                        } else {
21058                            pw.println("Error: unknown resolver table type: " + name);
21059                            return;
21060                        }
21061                        opti++;
21062                    }
21063                }
21064            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21065                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21066            } else if ("permission".equals(cmd)) {
21067                if (opti >= args.length) {
21068                    pw.println("Error: permission requires permission name");
21069                    return;
21070                }
21071                permissionNames = new ArraySet<>();
21072                while (opti < args.length) {
21073                    permissionNames.add(args[opti]);
21074                    opti++;
21075                }
21076                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21077                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21078            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21079                dumpState.setDump(DumpState.DUMP_PREFERRED);
21080            } else if ("preferred-xml".equals(cmd)) {
21081                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21082                if (opti < args.length && "--full".equals(args[opti])) {
21083                    fullPreferred = true;
21084                    opti++;
21085                }
21086            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21087                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21088            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21089                dumpState.setDump(DumpState.DUMP_PACKAGES);
21090            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21091                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21092            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21093                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21094            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21095                dumpState.setDump(DumpState.DUMP_MESSAGES);
21096            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21097                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21098            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21099                    || "intent-filter-verifiers".equals(cmd)) {
21100                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21101            } else if ("version".equals(cmd)) {
21102                dumpState.setDump(DumpState.DUMP_VERSION);
21103            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21104                dumpState.setDump(DumpState.DUMP_KEYSETS);
21105            } else if ("installs".equals(cmd)) {
21106                dumpState.setDump(DumpState.DUMP_INSTALLS);
21107            } else if ("frozen".equals(cmd)) {
21108                dumpState.setDump(DumpState.DUMP_FROZEN);
21109            } else if ("volumes".equals(cmd)) {
21110                dumpState.setDump(DumpState.DUMP_VOLUMES);
21111            } else if ("dexopt".equals(cmd)) {
21112                dumpState.setDump(DumpState.DUMP_DEXOPT);
21113            } else if ("compiler-stats".equals(cmd)) {
21114                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21115            } else if ("changes".equals(cmd)) {
21116                dumpState.setDump(DumpState.DUMP_CHANGES);
21117            } else if ("service-permissions".equals(cmd)) {
21118                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21119            } else if ("write".equals(cmd)) {
21120                synchronized (mPackages) {
21121                    mSettings.writeLPr();
21122                    pw.println("Settings written.");
21123                    return;
21124                }
21125            }
21126        }
21127
21128        if (checkin) {
21129            pw.println("vers,1");
21130        }
21131
21132        // reader
21133        synchronized (mPackages) {
21134            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21135                if (!checkin) {
21136                    if (dumpState.onTitlePrinted())
21137                        pw.println();
21138                    pw.println("Database versions:");
21139                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21140                }
21141            }
21142
21143            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21144                if (!checkin) {
21145                    if (dumpState.onTitlePrinted())
21146                        pw.println();
21147                    pw.println("Verifiers:");
21148                    pw.print("  Required: ");
21149                    pw.print(mRequiredVerifierPackage);
21150                    pw.print(" (uid=");
21151                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21152                            UserHandle.USER_SYSTEM));
21153                    pw.println(")");
21154                } else if (mRequiredVerifierPackage != null) {
21155                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21156                    pw.print(",");
21157                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21158                            UserHandle.USER_SYSTEM));
21159                }
21160            }
21161
21162            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21163                    packageName == null) {
21164                if (mIntentFilterVerifierComponent != null) {
21165                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21166                    if (!checkin) {
21167                        if (dumpState.onTitlePrinted())
21168                            pw.println();
21169                        pw.println("Intent Filter Verifier:");
21170                        pw.print("  Using: ");
21171                        pw.print(verifierPackageName);
21172                        pw.print(" (uid=");
21173                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21174                                UserHandle.USER_SYSTEM));
21175                        pw.println(")");
21176                    } else if (verifierPackageName != null) {
21177                        pw.print("ifv,"); pw.print(verifierPackageName);
21178                        pw.print(",");
21179                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21180                                UserHandle.USER_SYSTEM));
21181                    }
21182                } else {
21183                    pw.println();
21184                    pw.println("No Intent Filter Verifier available!");
21185                }
21186            }
21187
21188            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21189                boolean printedHeader = false;
21190                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21191                while (it.hasNext()) {
21192                    String libName = it.next();
21193                    LongSparseArray<SharedLibraryEntry> versionedLib
21194                            = mSharedLibraries.get(libName);
21195                    if (versionedLib == null) {
21196                        continue;
21197                    }
21198                    final int versionCount = versionedLib.size();
21199                    for (int i = 0; i < versionCount; i++) {
21200                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21201                        if (!checkin) {
21202                            if (!printedHeader) {
21203                                if (dumpState.onTitlePrinted())
21204                                    pw.println();
21205                                pw.println("Libraries:");
21206                                printedHeader = true;
21207                            }
21208                            pw.print("  ");
21209                        } else {
21210                            pw.print("lib,");
21211                        }
21212                        pw.print(libEntry.info.getName());
21213                        if (libEntry.info.isStatic()) {
21214                            pw.print(" version=" + libEntry.info.getLongVersion());
21215                        }
21216                        if (!checkin) {
21217                            pw.print(" -> ");
21218                        }
21219                        if (libEntry.path != null) {
21220                            pw.print(" (jar) ");
21221                            pw.print(libEntry.path);
21222                        } else {
21223                            pw.print(" (apk) ");
21224                            pw.print(libEntry.apk);
21225                        }
21226                        pw.println();
21227                    }
21228                }
21229            }
21230
21231            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21232                if (dumpState.onTitlePrinted())
21233                    pw.println();
21234                if (!checkin) {
21235                    pw.println("Features:");
21236                }
21237
21238                synchronized (mAvailableFeatures) {
21239                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21240                        if (checkin) {
21241                            pw.print("feat,");
21242                            pw.print(feat.name);
21243                            pw.print(",");
21244                            pw.println(feat.version);
21245                        } else {
21246                            pw.print("  ");
21247                            pw.print(feat.name);
21248                            if (feat.version > 0) {
21249                                pw.print(" version=");
21250                                pw.print(feat.version);
21251                            }
21252                            pw.println();
21253                        }
21254                    }
21255                }
21256            }
21257
21258            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21259                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21260                        : "Activity Resolver Table:", "  ", packageName,
21261                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21262                    dumpState.setTitlePrinted(true);
21263                }
21264            }
21265            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21266                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21267                        : "Receiver Resolver Table:", "  ", packageName,
21268                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21269                    dumpState.setTitlePrinted(true);
21270                }
21271            }
21272            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21273                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21274                        : "Service Resolver Table:", "  ", packageName,
21275                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21276                    dumpState.setTitlePrinted(true);
21277                }
21278            }
21279            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21280                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21281                        : "Provider Resolver Table:", "  ", packageName,
21282                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21283                    dumpState.setTitlePrinted(true);
21284                }
21285            }
21286
21287            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21288                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21289                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21290                    int user = mSettings.mPreferredActivities.keyAt(i);
21291                    if (pir.dump(pw,
21292                            dumpState.getTitlePrinted()
21293                                ? "\nPreferred Activities User " + user + ":"
21294                                : "Preferred Activities User " + user + ":", "  ",
21295                            packageName, true, false)) {
21296                        dumpState.setTitlePrinted(true);
21297                    }
21298                }
21299            }
21300
21301            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21302                pw.flush();
21303                FileOutputStream fout = new FileOutputStream(fd);
21304                BufferedOutputStream str = new BufferedOutputStream(fout);
21305                XmlSerializer serializer = new FastXmlSerializer();
21306                try {
21307                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21308                    serializer.startDocument(null, true);
21309                    serializer.setFeature(
21310                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21311                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21312                    serializer.endDocument();
21313                    serializer.flush();
21314                } catch (IllegalArgumentException e) {
21315                    pw.println("Failed writing: " + e);
21316                } catch (IllegalStateException e) {
21317                    pw.println("Failed writing: " + e);
21318                } catch (IOException e) {
21319                    pw.println("Failed writing: " + e);
21320                }
21321            }
21322
21323            if (!checkin
21324                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21325                    && packageName == null) {
21326                pw.println();
21327                int count = mSettings.mPackages.size();
21328                if (count == 0) {
21329                    pw.println("No applications!");
21330                    pw.println();
21331                } else {
21332                    final String prefix = "  ";
21333                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21334                    if (allPackageSettings.size() == 0) {
21335                        pw.println("No domain preferred apps!");
21336                        pw.println();
21337                    } else {
21338                        pw.println("App verification status:");
21339                        pw.println();
21340                        count = 0;
21341                        for (PackageSetting ps : allPackageSettings) {
21342                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21343                            if (ivi == null || ivi.getPackageName() == null) continue;
21344                            pw.println(prefix + "Package: " + ivi.getPackageName());
21345                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21346                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21347                            pw.println();
21348                            count++;
21349                        }
21350                        if (count == 0) {
21351                            pw.println(prefix + "No app verification established.");
21352                            pw.println();
21353                        }
21354                        for (int userId : sUserManager.getUserIds()) {
21355                            pw.println("App linkages for user " + userId + ":");
21356                            pw.println();
21357                            count = 0;
21358                            for (PackageSetting ps : allPackageSettings) {
21359                                final long status = ps.getDomainVerificationStatusForUser(userId);
21360                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21361                                        && !DEBUG_DOMAIN_VERIFICATION) {
21362                                    continue;
21363                                }
21364                                pw.println(prefix + "Package: " + ps.name);
21365                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21366                                String statusStr = IntentFilterVerificationInfo.
21367                                        getStatusStringFromValue(status);
21368                                pw.println(prefix + "Status:  " + statusStr);
21369                                pw.println();
21370                                count++;
21371                            }
21372                            if (count == 0) {
21373                                pw.println(prefix + "No configured app linkages.");
21374                                pw.println();
21375                            }
21376                        }
21377                    }
21378                }
21379            }
21380
21381            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21382                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21383            }
21384
21385            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21386                boolean printedSomething = false;
21387                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21388                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21389                        continue;
21390                    }
21391                    if (!printedSomething) {
21392                        if (dumpState.onTitlePrinted())
21393                            pw.println();
21394                        pw.println("Registered ContentProviders:");
21395                        printedSomething = true;
21396                    }
21397                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21398                    pw.print("    "); pw.println(p.toString());
21399                }
21400                printedSomething = false;
21401                for (Map.Entry<String, PackageParser.Provider> entry :
21402                        mProvidersByAuthority.entrySet()) {
21403                    PackageParser.Provider p = entry.getValue();
21404                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21405                        continue;
21406                    }
21407                    if (!printedSomething) {
21408                        if (dumpState.onTitlePrinted())
21409                            pw.println();
21410                        pw.println("ContentProvider Authorities:");
21411                        printedSomething = true;
21412                    }
21413                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21414                    pw.print("    "); pw.println(p.toString());
21415                    if (p.info != null && p.info.applicationInfo != null) {
21416                        final String appInfo = p.info.applicationInfo.toString();
21417                        pw.print("      applicationInfo="); pw.println(appInfo);
21418                    }
21419                }
21420            }
21421
21422            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21423                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21424            }
21425
21426            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21427                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21428            }
21429
21430            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21431                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21432            }
21433
21434            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21435                if (dumpState.onTitlePrinted()) pw.println();
21436                pw.println("Package Changes:");
21437                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21438                final int K = mChangedPackages.size();
21439                for (int i = 0; i < K; i++) {
21440                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21441                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21442                    final int N = changes.size();
21443                    if (N == 0) {
21444                        pw.print("    "); pw.println("No packages changed");
21445                    } else {
21446                        for (int j = 0; j < N; j++) {
21447                            final String pkgName = changes.valueAt(j);
21448                            final int sequenceNumber = changes.keyAt(j);
21449                            pw.print("    ");
21450                            pw.print("seq=");
21451                            pw.print(sequenceNumber);
21452                            pw.print(", package=");
21453                            pw.println(pkgName);
21454                        }
21455                    }
21456                }
21457            }
21458
21459            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21460                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21461            }
21462
21463            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21464                // XXX should handle packageName != null by dumping only install data that
21465                // the given package is involved with.
21466                if (dumpState.onTitlePrinted()) pw.println();
21467
21468                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21469                    ipw.println();
21470                    ipw.println("Frozen packages:");
21471                    ipw.increaseIndent();
21472                    if (mFrozenPackages.size() == 0) {
21473                        ipw.println("(none)");
21474                    } else {
21475                        for (int i = 0; i < mFrozenPackages.size(); i++) {
21476                            ipw.println(mFrozenPackages.valueAt(i));
21477                        }
21478                    }
21479                    ipw.decreaseIndent();
21480                }
21481            }
21482
21483            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21484                if (dumpState.onTitlePrinted()) pw.println();
21485
21486                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21487                    ipw.println();
21488                    ipw.println("Loaded volumes:");
21489                    ipw.increaseIndent();
21490                    if (mLoadedVolumes.size() == 0) {
21491                        ipw.println("(none)");
21492                    } else {
21493                        for (int i = 0; i < mLoadedVolumes.size(); i++) {
21494                            ipw.println(mLoadedVolumes.valueAt(i));
21495                        }
21496                    }
21497                    ipw.decreaseIndent();
21498                }
21499            }
21500
21501            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21502                    && packageName == null) {
21503                if (dumpState.onTitlePrinted()) pw.println();
21504                pw.println("Service permissions:");
21505
21506                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
21507                while (filterIterator.hasNext()) {
21508                    final ServiceIntentInfo info = filterIterator.next();
21509                    final ServiceInfo serviceInfo = info.service.info;
21510                    final String permission = serviceInfo.permission;
21511                    if (permission != null) {
21512                        pw.print("    ");
21513                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21514                        pw.print(": ");
21515                        pw.println(permission);
21516                    }
21517                }
21518            }
21519
21520            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21521                if (dumpState.onTitlePrinted()) pw.println();
21522                dumpDexoptStateLPr(pw, packageName);
21523            }
21524
21525            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21526                if (dumpState.onTitlePrinted()) pw.println();
21527                dumpCompilerStatsLPr(pw, packageName);
21528            }
21529
21530            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21531                if (dumpState.onTitlePrinted()) pw.println();
21532                mSettings.dumpReadMessagesLPr(pw, dumpState);
21533
21534                pw.println();
21535                pw.println("Package warning messages:");
21536                dumpCriticalInfo(pw, null);
21537            }
21538
21539            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21540                dumpCriticalInfo(pw, "msg,");
21541            }
21542        }
21543
21544        // PackageInstaller should be called outside of mPackages lock
21545        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21546            // XXX should handle packageName != null by dumping only install data that
21547            // the given package is involved with.
21548            if (dumpState.onTitlePrinted()) pw.println();
21549            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21550        }
21551    }
21552
21553    private void dumpProto(FileDescriptor fd) {
21554        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21555
21556        synchronized (mPackages) {
21557            final long requiredVerifierPackageToken =
21558                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21559            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21560            proto.write(
21561                    PackageServiceDumpProto.PackageShortProto.UID,
21562                    getPackageUid(
21563                            mRequiredVerifierPackage,
21564                            MATCH_DEBUG_TRIAGED_MISSING,
21565                            UserHandle.USER_SYSTEM));
21566            proto.end(requiredVerifierPackageToken);
21567
21568            if (mIntentFilterVerifierComponent != null) {
21569                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21570                final long verifierPackageToken =
21571                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21572                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21573                proto.write(
21574                        PackageServiceDumpProto.PackageShortProto.UID,
21575                        getPackageUid(
21576                                verifierPackageName,
21577                                MATCH_DEBUG_TRIAGED_MISSING,
21578                                UserHandle.USER_SYSTEM));
21579                proto.end(verifierPackageToken);
21580            }
21581
21582            dumpSharedLibrariesProto(proto);
21583            dumpFeaturesProto(proto);
21584            mSettings.dumpPackagesProto(proto);
21585            mSettings.dumpSharedUsersProto(proto);
21586            dumpCriticalInfo(proto);
21587        }
21588        proto.flush();
21589    }
21590
21591    private void dumpFeaturesProto(ProtoOutputStream proto) {
21592        synchronized (mAvailableFeatures) {
21593            final int count = mAvailableFeatures.size();
21594            for (int i = 0; i < count; i++) {
21595                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21596            }
21597        }
21598    }
21599
21600    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21601        final int count = mSharedLibraries.size();
21602        for (int i = 0; i < count; i++) {
21603            final String libName = mSharedLibraries.keyAt(i);
21604            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21605            if (versionedLib == null) {
21606                continue;
21607            }
21608            final int versionCount = versionedLib.size();
21609            for (int j = 0; j < versionCount; j++) {
21610                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21611                final long sharedLibraryToken =
21612                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21613                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21614                final boolean isJar = (libEntry.path != null);
21615                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21616                if (isJar) {
21617                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21618                } else {
21619                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21620                }
21621                proto.end(sharedLibraryToken);
21622            }
21623        }
21624    }
21625
21626    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21627        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21628            ipw.println();
21629            ipw.println("Dexopt state:");
21630            ipw.increaseIndent();
21631            Collection<PackageParser.Package> packages = null;
21632            if (packageName != null) {
21633                PackageParser.Package targetPackage = mPackages.get(packageName);
21634                if (targetPackage != null) {
21635                    packages = Collections.singletonList(targetPackage);
21636                } else {
21637                    ipw.println("Unable to find package: " + packageName);
21638                    return;
21639                }
21640            } else {
21641                packages = mPackages.values();
21642            }
21643
21644            for (PackageParser.Package pkg : packages) {
21645                ipw.println("[" + pkg.packageName + "]");
21646                ipw.increaseIndent();
21647                mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21648                        mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21649                ipw.decreaseIndent();
21650            }
21651        }
21652    }
21653
21654    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21655        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21656            ipw.println();
21657            ipw.println("Compiler stats:");
21658            ipw.increaseIndent();
21659            Collection<PackageParser.Package> packages = null;
21660            if (packageName != null) {
21661                PackageParser.Package targetPackage = mPackages.get(packageName);
21662                if (targetPackage != null) {
21663                    packages = Collections.singletonList(targetPackage);
21664                } else {
21665                    ipw.println("Unable to find package: " + packageName);
21666                    return;
21667                }
21668            } else {
21669                packages = mPackages.values();
21670            }
21671
21672            for (PackageParser.Package pkg : packages) {
21673                ipw.println("[" + pkg.packageName + "]");
21674                ipw.increaseIndent();
21675
21676                CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21677                if (stats == null) {
21678                    ipw.println("(No recorded stats)");
21679                } else {
21680                    stats.dump(ipw);
21681                }
21682                ipw.decreaseIndent();
21683            }
21684        }
21685    }
21686
21687    private String dumpDomainString(String packageName) {
21688        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21689                .getList();
21690        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21691
21692        ArraySet<String> result = new ArraySet<>();
21693        if (iviList.size() > 0) {
21694            for (IntentFilterVerificationInfo ivi : iviList) {
21695                for (String host : ivi.getDomains()) {
21696                    result.add(host);
21697                }
21698            }
21699        }
21700        if (filters != null && filters.size() > 0) {
21701            for (IntentFilter filter : filters) {
21702                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21703                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21704                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21705                    result.addAll(filter.getHostsList());
21706                }
21707            }
21708        }
21709
21710        StringBuilder sb = new StringBuilder(result.size() * 16);
21711        for (String domain : result) {
21712            if (sb.length() > 0) sb.append(" ");
21713            sb.append(domain);
21714        }
21715        return sb.toString();
21716    }
21717
21718    // ------- apps on sdcard specific code -------
21719    static final boolean DEBUG_SD_INSTALL = false;
21720
21721    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21722
21723    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21724
21725    private boolean mMediaMounted = false;
21726
21727    static String getEncryptKey() {
21728        try {
21729            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21730                    SD_ENCRYPTION_KEYSTORE_NAME);
21731            if (sdEncKey == null) {
21732                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21733                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21734                if (sdEncKey == null) {
21735                    Slog.e(TAG, "Failed to create encryption keys");
21736                    return null;
21737                }
21738            }
21739            return sdEncKey;
21740        } catch (NoSuchAlgorithmException nsae) {
21741            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21742            return null;
21743        } catch (IOException ioe) {
21744            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21745            return null;
21746        }
21747    }
21748
21749    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21750            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21751        final int size = infos.size();
21752        final String[] packageNames = new String[size];
21753        final int[] packageUids = new int[size];
21754        for (int i = 0; i < size; i++) {
21755            final ApplicationInfo info = infos.get(i);
21756            packageNames[i] = info.packageName;
21757            packageUids[i] = info.uid;
21758        }
21759        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21760                finishedReceiver);
21761    }
21762
21763    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21764            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21765        sendResourcesChangedBroadcast(mediaStatus, replacing,
21766                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21767    }
21768
21769    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21770            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21771        int size = pkgList.length;
21772        if (size > 0) {
21773            // Send broadcasts here
21774            Bundle extras = new Bundle();
21775            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21776            if (uidArr != null) {
21777                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21778            }
21779            if (replacing) {
21780                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21781            }
21782            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21783                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21784            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21785        }
21786    }
21787
21788    private void loadPrivatePackages(final VolumeInfo vol) {
21789        mHandler.post(new Runnable() {
21790            @Override
21791            public void run() {
21792                loadPrivatePackagesInner(vol);
21793            }
21794        });
21795    }
21796
21797    private void loadPrivatePackagesInner(VolumeInfo vol) {
21798        final String volumeUuid = vol.fsUuid;
21799        if (TextUtils.isEmpty(volumeUuid)) {
21800            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21801            return;
21802        }
21803
21804        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21805        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21806        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21807
21808        final VersionInfo ver;
21809        final List<PackageSetting> packages;
21810        synchronized (mPackages) {
21811            ver = mSettings.findOrCreateVersion(volumeUuid);
21812            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21813        }
21814
21815        for (PackageSetting ps : packages) {
21816            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21817            synchronized (mInstallLock) {
21818                final PackageParser.Package pkg;
21819                try {
21820                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21821                    loaded.add(pkg.applicationInfo);
21822
21823                } catch (PackageManagerException e) {
21824                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21825                }
21826
21827                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21828                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21829                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21830                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21831                }
21832            }
21833        }
21834
21835        // Reconcile app data for all started/unlocked users
21836        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21837        final UserManager um = mContext.getSystemService(UserManager.class);
21838        UserManagerInternal umInternal = getUserManagerInternal();
21839        for (UserInfo user : um.getUsers()) {
21840            final int flags;
21841            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21842                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21843            } else if (umInternal.isUserRunning(user.id)) {
21844                flags = StorageManager.FLAG_STORAGE_DE;
21845            } else {
21846                continue;
21847            }
21848
21849            try {
21850                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21851                synchronized (mInstallLock) {
21852                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21853                }
21854            } catch (IllegalStateException e) {
21855                // Device was probably ejected, and we'll process that event momentarily
21856                Slog.w(TAG, "Failed to prepare storage: " + e);
21857            }
21858        }
21859
21860        synchronized (mPackages) {
21861            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21862            if (sdkUpdated) {
21863                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21864                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21865            }
21866            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21867                    mPermissionCallback);
21868
21869            // Yay, everything is now upgraded
21870            ver.forceCurrent();
21871
21872            mSettings.writeLPr();
21873        }
21874
21875        for (PackageFreezer freezer : freezers) {
21876            freezer.close();
21877        }
21878
21879        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21880        sendResourcesChangedBroadcast(true, false, loaded, null);
21881        mLoadedVolumes.add(vol.getId());
21882    }
21883
21884    private void unloadPrivatePackages(final VolumeInfo vol) {
21885        mHandler.post(new Runnable() {
21886            @Override
21887            public void run() {
21888                unloadPrivatePackagesInner(vol);
21889            }
21890        });
21891    }
21892
21893    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21894        final String volumeUuid = vol.fsUuid;
21895        if (TextUtils.isEmpty(volumeUuid)) {
21896            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21897            return;
21898        }
21899
21900        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21901        synchronized (mInstallLock) {
21902        synchronized (mPackages) {
21903            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21904            for (PackageSetting ps : packages) {
21905                if (ps.pkg == null) continue;
21906
21907                final ApplicationInfo info = ps.pkg.applicationInfo;
21908                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21909                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21910
21911                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21912                        "unloadPrivatePackagesInner")) {
21913                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21914                            false, null)) {
21915                        unloaded.add(info);
21916                    } else {
21917                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21918                    }
21919                }
21920
21921                // Try very hard to release any references to this package
21922                // so we don't risk the system server being killed due to
21923                // open FDs
21924                AttributeCache.instance().removePackage(ps.name);
21925            }
21926
21927            mSettings.writeLPr();
21928        }
21929        }
21930
21931        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21932        sendResourcesChangedBroadcast(false, false, unloaded, null);
21933        mLoadedVolumes.remove(vol.getId());
21934
21935        // Try very hard to release any references to this path so we don't risk
21936        // the system server being killed due to open FDs
21937        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21938
21939        for (int i = 0; i < 3; i++) {
21940            System.gc();
21941            System.runFinalization();
21942        }
21943    }
21944
21945    private void assertPackageKnown(String volumeUuid, String packageName)
21946            throws PackageManagerException {
21947        synchronized (mPackages) {
21948            // Normalize package name to handle renamed packages
21949            packageName = normalizePackageNameLPr(packageName);
21950
21951            final PackageSetting ps = mSettings.mPackages.get(packageName);
21952            if (ps == null) {
21953                throw new PackageManagerException("Package " + packageName + " is unknown");
21954            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21955                throw new PackageManagerException(
21956                        "Package " + packageName + " found on unknown volume " + volumeUuid
21957                                + "; expected volume " + ps.volumeUuid);
21958            }
21959        }
21960    }
21961
21962    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21963            throws PackageManagerException {
21964        synchronized (mPackages) {
21965            // Normalize package name to handle renamed packages
21966            packageName = normalizePackageNameLPr(packageName);
21967
21968            final PackageSetting ps = mSettings.mPackages.get(packageName);
21969            if (ps == null) {
21970                throw new PackageManagerException("Package " + packageName + " is unknown");
21971            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21972                throw new PackageManagerException(
21973                        "Package " + packageName + " found on unknown volume " + volumeUuid
21974                                + "; expected volume " + ps.volumeUuid);
21975            } else if (!ps.getInstalled(userId)) {
21976                throw new PackageManagerException(
21977                        "Package " + packageName + " not installed for user " + userId);
21978            }
21979        }
21980    }
21981
21982    private List<String> collectAbsoluteCodePaths() {
21983        synchronized (mPackages) {
21984            List<String> codePaths = new ArrayList<>();
21985            final int packageCount = mSettings.mPackages.size();
21986            for (int i = 0; i < packageCount; i++) {
21987                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21988                codePaths.add(ps.codePath.getAbsolutePath());
21989            }
21990            return codePaths;
21991        }
21992    }
21993
21994    /**
21995     * Examine all apps present on given mounted volume, and destroy apps that
21996     * aren't expected, either due to uninstallation or reinstallation on
21997     * another volume.
21998     */
21999    private void reconcileApps(String volumeUuid) {
22000        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22001        List<File> filesToDelete = null;
22002
22003        final File[] files = FileUtils.listFilesOrEmpty(
22004                Environment.getDataAppDirectory(volumeUuid));
22005        for (File file : files) {
22006            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22007                    && !PackageInstallerService.isStageName(file.getName());
22008            if (!isPackage) {
22009                // Ignore entries which are not packages
22010                continue;
22011            }
22012
22013            String absolutePath = file.getAbsolutePath();
22014
22015            boolean pathValid = false;
22016            final int absoluteCodePathCount = absoluteCodePaths.size();
22017            for (int i = 0; i < absoluteCodePathCount; i++) {
22018                String absoluteCodePath = absoluteCodePaths.get(i);
22019                if (absolutePath.startsWith(absoluteCodePath)) {
22020                    pathValid = true;
22021                    break;
22022                }
22023            }
22024
22025            if (!pathValid) {
22026                if (filesToDelete == null) {
22027                    filesToDelete = new ArrayList<>();
22028                }
22029                filesToDelete.add(file);
22030            }
22031        }
22032
22033        if (filesToDelete != null) {
22034            final int fileToDeleteCount = filesToDelete.size();
22035            for (int i = 0; i < fileToDeleteCount; i++) {
22036                File fileToDelete = filesToDelete.get(i);
22037                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22038                synchronized (mInstallLock) {
22039                    removeCodePathLI(fileToDelete);
22040                }
22041            }
22042        }
22043    }
22044
22045    /**
22046     * Reconcile all app data for the given user.
22047     * <p>
22048     * Verifies that directories exist and that ownership and labeling is
22049     * correct for all installed apps on all mounted volumes.
22050     */
22051    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22052        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22053        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22054            final String volumeUuid = vol.getFsUuid();
22055            synchronized (mInstallLock) {
22056                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22057            }
22058        }
22059    }
22060
22061    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22062            boolean migrateAppData) {
22063        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22064    }
22065
22066    /**
22067     * Reconcile all app data on given mounted volume.
22068     * <p>
22069     * Destroys app data that isn't expected, either due to uninstallation or
22070     * reinstallation on another volume.
22071     * <p>
22072     * Verifies that directories exist and that ownership and labeling is
22073     * correct for all installed apps.
22074     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22075     */
22076    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22077            boolean migrateAppData, boolean onlyCoreApps) {
22078        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22079                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22080        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22081
22082        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22083        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22084
22085        // First look for stale data that doesn't belong, and check if things
22086        // have changed since we did our last restorecon
22087        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22088            if (StorageManager.isFileEncryptedNativeOrEmulated()
22089                    && !StorageManager.isUserKeyUnlocked(userId)) {
22090                throw new RuntimeException(
22091                        "Yikes, someone asked us to reconcile CE storage while " + userId
22092                                + " was still locked; this would have caused massive data loss!");
22093            }
22094
22095            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22096            for (File file : files) {
22097                final String packageName = file.getName();
22098                try {
22099                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22100                } catch (PackageManagerException e) {
22101                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22102                    try {
22103                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22104                                StorageManager.FLAG_STORAGE_CE, 0);
22105                    } catch (InstallerException e2) {
22106                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22107                    }
22108                }
22109            }
22110        }
22111        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22112            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22113            for (File file : files) {
22114                final String packageName = file.getName();
22115                try {
22116                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22117                } catch (PackageManagerException e) {
22118                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22119                    try {
22120                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22121                                StorageManager.FLAG_STORAGE_DE, 0);
22122                    } catch (InstallerException e2) {
22123                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22124                    }
22125                }
22126            }
22127        }
22128
22129        // Ensure that data directories are ready to roll for all packages
22130        // installed for this volume and user
22131        final List<PackageSetting> packages;
22132        synchronized (mPackages) {
22133            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22134        }
22135        int preparedCount = 0;
22136        for (PackageSetting ps : packages) {
22137            final String packageName = ps.name;
22138            if (ps.pkg == null) {
22139                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22140                // TODO: might be due to legacy ASEC apps; we should circle back
22141                // and reconcile again once they're scanned
22142                continue;
22143            }
22144            // Skip non-core apps if requested
22145            if (onlyCoreApps && !ps.pkg.coreApp) {
22146                result.add(packageName);
22147                continue;
22148            }
22149
22150            if (ps.getInstalled(userId)) {
22151                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22152                preparedCount++;
22153            }
22154        }
22155
22156        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22157        return result;
22158    }
22159
22160    /**
22161     * Prepare app data for the given app just after it was installed or
22162     * upgraded. This method carefully only touches users that it's installed
22163     * for, and it forces a restorecon to handle any seinfo changes.
22164     * <p>
22165     * Verifies that directories exist and that ownership and labeling is
22166     * correct for all installed apps. If there is an ownership mismatch, it
22167     * will try recovering system apps by wiping data; third-party app data is
22168     * left intact.
22169     * <p>
22170     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22171     */
22172    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22173        final PackageSetting ps;
22174        synchronized (mPackages) {
22175            ps = mSettings.mPackages.get(pkg.packageName);
22176            mSettings.writeKernelMappingLPr(ps);
22177        }
22178
22179        final UserManager um = mContext.getSystemService(UserManager.class);
22180        UserManagerInternal umInternal = getUserManagerInternal();
22181        for (UserInfo user : um.getUsers()) {
22182            final int flags;
22183            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22184                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22185            } else if (umInternal.isUserRunning(user.id)) {
22186                flags = StorageManager.FLAG_STORAGE_DE;
22187            } else {
22188                continue;
22189            }
22190
22191            if (ps.getInstalled(user.id)) {
22192                // TODO: when user data is locked, mark that we're still dirty
22193                prepareAppDataLIF(pkg, user.id, flags);
22194            }
22195        }
22196    }
22197
22198    /**
22199     * Prepare app data for the given app.
22200     * <p>
22201     * Verifies that directories exist and that ownership and labeling is
22202     * correct for all installed apps. If there is an ownership mismatch, this
22203     * will try recovering system apps by wiping data; third-party app data is
22204     * left intact.
22205     */
22206    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22207        if (pkg == null) {
22208            Slog.wtf(TAG, "Package was null!", new Throwable());
22209            return;
22210        }
22211        prepareAppDataLeafLIF(pkg, userId, flags);
22212        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22213        for (int i = 0; i < childCount; i++) {
22214            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22215        }
22216    }
22217
22218    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22219            boolean maybeMigrateAppData) {
22220        prepareAppDataLIF(pkg, userId, flags);
22221
22222        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22223            // We may have just shuffled around app data directories, so
22224            // prepare them one more time
22225            prepareAppDataLIF(pkg, userId, flags);
22226        }
22227    }
22228
22229    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22230        if (DEBUG_APP_DATA) {
22231            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22232                    + Integer.toHexString(flags));
22233        }
22234
22235        final String volumeUuid = pkg.volumeUuid;
22236        final String packageName = pkg.packageName;
22237        final ApplicationInfo app = pkg.applicationInfo;
22238        final int appId = UserHandle.getAppId(app.uid);
22239
22240        Preconditions.checkNotNull(app.seInfo);
22241
22242        long ceDataInode = -1;
22243        try {
22244            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22245                    appId, app.seInfo, app.targetSdkVersion);
22246        } catch (InstallerException e) {
22247            if (app.isSystemApp()) {
22248                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22249                        + ", but trying to recover: " + e);
22250                destroyAppDataLeafLIF(pkg, userId, flags);
22251                try {
22252                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22253                            appId, app.seInfo, app.targetSdkVersion);
22254                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22255                } catch (InstallerException e2) {
22256                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22257                }
22258            } else {
22259                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22260            }
22261        }
22262        // Prepare the application profiles only for upgrades and first boot (so that we don't
22263        // repeat the same operation at each boot).
22264        // We only have to cover the upgrade and first boot here because for app installs we
22265        // prepare the profiles before invoking dexopt (in installPackageLI).
22266        //
22267        // We also have to cover non system users because we do not call the usual install package
22268        // methods for them.
22269        if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22270            mArtManagerService.prepareAppProfiles(pkg, userId);
22271        }
22272
22273        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22274            // TODO: mark this structure as dirty so we persist it!
22275            synchronized (mPackages) {
22276                final PackageSetting ps = mSettings.mPackages.get(packageName);
22277                if (ps != null) {
22278                    ps.setCeDataInode(ceDataInode, userId);
22279                }
22280            }
22281        }
22282
22283        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22284    }
22285
22286    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22287        if (pkg == null) {
22288            Slog.wtf(TAG, "Package was null!", new Throwable());
22289            return;
22290        }
22291        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22292        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22293        for (int i = 0; i < childCount; i++) {
22294            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22295        }
22296    }
22297
22298    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22299        final String volumeUuid = pkg.volumeUuid;
22300        final String packageName = pkg.packageName;
22301        final ApplicationInfo app = pkg.applicationInfo;
22302
22303        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22304            // Create a native library symlink only if we have native libraries
22305            // and if the native libraries are 32 bit libraries. We do not provide
22306            // this symlink for 64 bit libraries.
22307            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22308                final String nativeLibPath = app.nativeLibraryDir;
22309                try {
22310                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22311                            nativeLibPath, userId);
22312                } catch (InstallerException e) {
22313                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22314                }
22315            }
22316        }
22317    }
22318
22319    /**
22320     * For system apps on non-FBE devices, this method migrates any existing
22321     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22322     * requested by the app.
22323     */
22324    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22325        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22326                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22327            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22328                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22329            try {
22330                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22331                        storageTarget);
22332            } catch (InstallerException e) {
22333                logCriticalInfo(Log.WARN,
22334                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22335            }
22336            return true;
22337        } else {
22338            return false;
22339        }
22340    }
22341
22342    public PackageFreezer freezePackage(String packageName, String killReason) {
22343        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22344    }
22345
22346    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22347        return new PackageFreezer(packageName, userId, killReason);
22348    }
22349
22350    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22351            String killReason) {
22352        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22353    }
22354
22355    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22356            String killReason) {
22357        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22358            return new PackageFreezer();
22359        } else {
22360            return freezePackage(packageName, userId, killReason);
22361        }
22362    }
22363
22364    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22365            String killReason) {
22366        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22367    }
22368
22369    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22370            String killReason) {
22371        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22372            return new PackageFreezer();
22373        } else {
22374            return freezePackage(packageName, userId, killReason);
22375        }
22376    }
22377
22378    /**
22379     * Class that freezes and kills the given package upon creation, and
22380     * unfreezes it upon closing. This is typically used when doing surgery on
22381     * app code/data to prevent the app from running while you're working.
22382     */
22383    private class PackageFreezer implements AutoCloseable {
22384        private final String mPackageName;
22385        private final PackageFreezer[] mChildren;
22386
22387        private final boolean mWeFroze;
22388
22389        private final AtomicBoolean mClosed = new AtomicBoolean();
22390        private final CloseGuard mCloseGuard = CloseGuard.get();
22391
22392        /**
22393         * Create and return a stub freezer that doesn't actually do anything,
22394         * typically used when someone requested
22395         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22396         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22397         */
22398        public PackageFreezer() {
22399            mPackageName = null;
22400            mChildren = null;
22401            mWeFroze = false;
22402            mCloseGuard.open("close");
22403        }
22404
22405        public PackageFreezer(String packageName, int userId, String killReason) {
22406            synchronized (mPackages) {
22407                mPackageName = packageName;
22408                mWeFroze = mFrozenPackages.add(mPackageName);
22409
22410                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22411                if (ps != null) {
22412                    killApplication(ps.name, ps.appId, userId, killReason);
22413                }
22414
22415                final PackageParser.Package p = mPackages.get(packageName);
22416                if (p != null && p.childPackages != null) {
22417                    final int N = p.childPackages.size();
22418                    mChildren = new PackageFreezer[N];
22419                    for (int i = 0; i < N; i++) {
22420                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22421                                userId, killReason);
22422                    }
22423                } else {
22424                    mChildren = null;
22425                }
22426            }
22427            mCloseGuard.open("close");
22428        }
22429
22430        @Override
22431        protected void finalize() throws Throwable {
22432            try {
22433                if (mCloseGuard != null) {
22434                    mCloseGuard.warnIfOpen();
22435                }
22436
22437                close();
22438            } finally {
22439                super.finalize();
22440            }
22441        }
22442
22443        @Override
22444        public void close() {
22445            mCloseGuard.close();
22446            if (mClosed.compareAndSet(false, true)) {
22447                synchronized (mPackages) {
22448                    if (mWeFroze) {
22449                        mFrozenPackages.remove(mPackageName);
22450                    }
22451
22452                    if (mChildren != null) {
22453                        for (PackageFreezer freezer : mChildren) {
22454                            freezer.close();
22455                        }
22456                    }
22457                }
22458            }
22459        }
22460    }
22461
22462    /**
22463     * Verify that given package is currently frozen.
22464     */
22465    private void checkPackageFrozen(String packageName) {
22466        synchronized (mPackages) {
22467            if (!mFrozenPackages.contains(packageName)) {
22468                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22469            }
22470        }
22471    }
22472
22473    @Override
22474    public int movePackage(final String packageName, final String volumeUuid) {
22475        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22476
22477        final int callingUid = Binder.getCallingUid();
22478        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22479        final int moveId = mNextMoveId.getAndIncrement();
22480        mHandler.post(new Runnable() {
22481            @Override
22482            public void run() {
22483                try {
22484                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22485                } catch (PackageManagerException e) {
22486                    Slog.w(TAG, "Failed to move " + packageName, e);
22487                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22488                }
22489            }
22490        });
22491        return moveId;
22492    }
22493
22494    private void movePackageInternal(final String packageName, final String volumeUuid,
22495            final int moveId, final int callingUid, UserHandle user)
22496                    throws PackageManagerException {
22497        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22498        final PackageManager pm = mContext.getPackageManager();
22499
22500        final boolean currentAsec;
22501        final String currentVolumeUuid;
22502        final File codeFile;
22503        final String installerPackageName;
22504        final String packageAbiOverride;
22505        final int appId;
22506        final String seinfo;
22507        final String label;
22508        final int targetSdkVersion;
22509        final PackageFreezer freezer;
22510        final int[] installedUserIds;
22511
22512        // reader
22513        synchronized (mPackages) {
22514            final PackageParser.Package pkg = mPackages.get(packageName);
22515            final PackageSetting ps = mSettings.mPackages.get(packageName);
22516            if (pkg == null
22517                    || ps == null
22518                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22519                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22520            }
22521            if (pkg.applicationInfo.isSystemApp()) {
22522                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22523                        "Cannot move system application");
22524            }
22525
22526            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22527            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22528                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22529            if (isInternalStorage && !allow3rdPartyOnInternal) {
22530                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22531                        "3rd party apps are not allowed on internal storage");
22532            }
22533
22534            if (pkg.applicationInfo.isExternalAsec()) {
22535                currentAsec = true;
22536                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22537            } else if (pkg.applicationInfo.isForwardLocked()) {
22538                currentAsec = true;
22539                currentVolumeUuid = "forward_locked";
22540            } else {
22541                currentAsec = false;
22542                currentVolumeUuid = ps.volumeUuid;
22543
22544                final File probe = new File(pkg.codePath);
22545                final File probeOat = new File(probe, "oat");
22546                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22547                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22548                            "Move only supported for modern cluster style installs");
22549                }
22550            }
22551
22552            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22553                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22554                        "Package already moved to " + volumeUuid);
22555            }
22556            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22557                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22558                        "Device admin cannot be moved");
22559            }
22560
22561            if (mFrozenPackages.contains(packageName)) {
22562                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22563                        "Failed to move already frozen package");
22564            }
22565
22566            codeFile = new File(pkg.codePath);
22567            installerPackageName = ps.installerPackageName;
22568            packageAbiOverride = ps.cpuAbiOverrideString;
22569            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22570            seinfo = pkg.applicationInfo.seInfo;
22571            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22572            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22573            freezer = freezePackage(packageName, "movePackageInternal");
22574            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22575        }
22576
22577        final Bundle extras = new Bundle();
22578        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22579        extras.putString(Intent.EXTRA_TITLE, label);
22580        mMoveCallbacks.notifyCreated(moveId, extras);
22581
22582        int installFlags;
22583        final boolean moveCompleteApp;
22584        final File measurePath;
22585
22586        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22587            installFlags = INSTALL_INTERNAL;
22588            moveCompleteApp = !currentAsec;
22589            measurePath = Environment.getDataAppDirectory(volumeUuid);
22590        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22591            installFlags = INSTALL_EXTERNAL;
22592            moveCompleteApp = false;
22593            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22594        } else {
22595            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22596            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22597                    || !volume.isMountedWritable()) {
22598                freezer.close();
22599                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22600                        "Move location not mounted private volume");
22601            }
22602
22603            Preconditions.checkState(!currentAsec);
22604
22605            installFlags = INSTALL_INTERNAL;
22606            moveCompleteApp = true;
22607            measurePath = Environment.getDataAppDirectory(volumeUuid);
22608        }
22609
22610        // If we're moving app data around, we need all the users unlocked
22611        if (moveCompleteApp) {
22612            for (int userId : installedUserIds) {
22613                if (StorageManager.isFileEncryptedNativeOrEmulated()
22614                        && !StorageManager.isUserKeyUnlocked(userId)) {
22615                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22616                            "User " + userId + " must be unlocked");
22617                }
22618            }
22619        }
22620
22621        final PackageStats stats = new PackageStats(null, -1);
22622        synchronized (mInstaller) {
22623            for (int userId : installedUserIds) {
22624                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22625                    freezer.close();
22626                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22627                            "Failed to measure package size");
22628                }
22629            }
22630        }
22631
22632        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22633                + stats.dataSize);
22634
22635        final long startFreeBytes = measurePath.getUsableSpace();
22636        final long sizeBytes;
22637        if (moveCompleteApp) {
22638            sizeBytes = stats.codeSize + stats.dataSize;
22639        } else {
22640            sizeBytes = stats.codeSize;
22641        }
22642
22643        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22644            freezer.close();
22645            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22646                    "Not enough free space to move");
22647        }
22648
22649        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22650
22651        final CountDownLatch installedLatch = new CountDownLatch(1);
22652        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22653            @Override
22654            public void onUserActionRequired(Intent intent) throws RemoteException {
22655                throw new IllegalStateException();
22656            }
22657
22658            @Override
22659            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22660                    Bundle extras) throws RemoteException {
22661                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22662                        + PackageManager.installStatusToString(returnCode, msg));
22663
22664                installedLatch.countDown();
22665                freezer.close();
22666
22667                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22668                switch (status) {
22669                    case PackageInstaller.STATUS_SUCCESS:
22670                        mMoveCallbacks.notifyStatusChanged(moveId,
22671                                PackageManager.MOVE_SUCCEEDED);
22672                        break;
22673                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22674                        mMoveCallbacks.notifyStatusChanged(moveId,
22675                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22676                        break;
22677                    default:
22678                        mMoveCallbacks.notifyStatusChanged(moveId,
22679                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22680                        break;
22681                }
22682            }
22683        };
22684
22685        final MoveInfo move;
22686        if (moveCompleteApp) {
22687            // Kick off a thread to report progress estimates
22688            new Thread() {
22689                @Override
22690                public void run() {
22691                    while (true) {
22692                        try {
22693                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22694                                break;
22695                            }
22696                        } catch (InterruptedException ignored) {
22697                        }
22698
22699                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22700                        final int progress = 10 + (int) MathUtils.constrain(
22701                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22702                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22703                    }
22704                }
22705            }.start();
22706
22707            final String dataAppName = codeFile.getName();
22708            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22709                    dataAppName, appId, seinfo, targetSdkVersion);
22710        } else {
22711            move = null;
22712        }
22713
22714        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22715
22716        final Message msg = mHandler.obtainMessage(INIT_COPY);
22717        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22718        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22719                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22720                packageAbiOverride, null /*grantedPermissions*/,
22721                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
22722        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22723        msg.obj = params;
22724
22725        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22726                System.identityHashCode(msg.obj));
22727        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22728                System.identityHashCode(msg.obj));
22729
22730        mHandler.sendMessage(msg);
22731    }
22732
22733    @Override
22734    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22735        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22736
22737        final int realMoveId = mNextMoveId.getAndIncrement();
22738        final Bundle extras = new Bundle();
22739        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22740        mMoveCallbacks.notifyCreated(realMoveId, extras);
22741
22742        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22743            @Override
22744            public void onCreated(int moveId, Bundle extras) {
22745                // Ignored
22746            }
22747
22748            @Override
22749            public void onStatusChanged(int moveId, int status, long estMillis) {
22750                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22751            }
22752        };
22753
22754        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22755        storage.setPrimaryStorageUuid(volumeUuid, callback);
22756        return realMoveId;
22757    }
22758
22759    @Override
22760    public int getMoveStatus(int moveId) {
22761        mContext.enforceCallingOrSelfPermission(
22762                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22763        return mMoveCallbacks.mLastStatus.get(moveId);
22764    }
22765
22766    @Override
22767    public void registerMoveCallback(IPackageMoveObserver callback) {
22768        mContext.enforceCallingOrSelfPermission(
22769                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22770        mMoveCallbacks.register(callback);
22771    }
22772
22773    @Override
22774    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22775        mContext.enforceCallingOrSelfPermission(
22776                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22777        mMoveCallbacks.unregister(callback);
22778    }
22779
22780    @Override
22781    public boolean setInstallLocation(int loc) {
22782        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22783                null);
22784        if (getInstallLocation() == loc) {
22785            return true;
22786        }
22787        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22788                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22789            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22790                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22791            return true;
22792        }
22793        return false;
22794   }
22795
22796    @Override
22797    public int getInstallLocation() {
22798        // allow instant app access
22799        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22800                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22801                PackageHelper.APP_INSTALL_AUTO);
22802    }
22803
22804    /** Called by UserManagerService */
22805    void cleanUpUser(UserManagerService userManager, int userHandle) {
22806        synchronized (mPackages) {
22807            mDirtyUsers.remove(userHandle);
22808            mUserNeedsBadging.delete(userHandle);
22809            mSettings.removeUserLPw(userHandle);
22810            mPendingBroadcasts.remove(userHandle);
22811            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22812            removeUnusedPackagesLPw(userManager, userHandle);
22813        }
22814    }
22815
22816    /**
22817     * We're removing userHandle and would like to remove any downloaded packages
22818     * that are no longer in use by any other user.
22819     * @param userHandle the user being removed
22820     */
22821    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22822        final boolean DEBUG_CLEAN_APKS = false;
22823        int [] users = userManager.getUserIds();
22824        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22825        while (psit.hasNext()) {
22826            PackageSetting ps = psit.next();
22827            if (ps.pkg == null) {
22828                continue;
22829            }
22830            final String packageName = ps.pkg.packageName;
22831            // Skip over if system app
22832            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22833                continue;
22834            }
22835            if (DEBUG_CLEAN_APKS) {
22836                Slog.i(TAG, "Checking package " + packageName);
22837            }
22838            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22839            if (keep) {
22840                if (DEBUG_CLEAN_APKS) {
22841                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22842                }
22843            } else {
22844                for (int i = 0; i < users.length; i++) {
22845                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22846                        keep = true;
22847                        if (DEBUG_CLEAN_APKS) {
22848                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22849                                    + users[i]);
22850                        }
22851                        break;
22852                    }
22853                }
22854            }
22855            if (!keep) {
22856                if (DEBUG_CLEAN_APKS) {
22857                    Slog.i(TAG, "  Removing package " + packageName);
22858                }
22859                mHandler.post(new Runnable() {
22860                    public void run() {
22861                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22862                                userHandle, 0);
22863                    } //end run
22864                });
22865            }
22866        }
22867    }
22868
22869    /** Called by UserManagerService */
22870    void createNewUser(int userId, String[] disallowedPackages) {
22871        synchronized (mInstallLock) {
22872            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22873        }
22874        synchronized (mPackages) {
22875            scheduleWritePackageRestrictionsLocked(userId);
22876            scheduleWritePackageListLocked(userId);
22877            applyFactoryDefaultBrowserLPw(userId);
22878            primeDomainVerificationsLPw(userId);
22879        }
22880    }
22881
22882    void onNewUserCreated(final int userId) {
22883        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22884        synchronized(mPackages) {
22885            // If permission review for legacy apps is required, we represent
22886            // dagerous permissions for such apps as always granted runtime
22887            // permissions to keep per user flag state whether review is needed.
22888            // Hence, if a new user is added we have to propagate dangerous
22889            // permission grants for these legacy apps.
22890            if (mSettings.mPermissions.mPermissionReviewRequired) {
22891// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22892                mPermissionManager.updateAllPermissions(
22893                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22894                        mPermissionCallback);
22895            }
22896        }
22897    }
22898
22899    @Override
22900    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22901        mContext.enforceCallingOrSelfPermission(
22902                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22903                "Only package verification agents can read the verifier device identity");
22904
22905        synchronized (mPackages) {
22906            return mSettings.getVerifierDeviceIdentityLPw();
22907        }
22908    }
22909
22910    @Override
22911    public void setPermissionEnforced(String permission, boolean enforced) {
22912        // TODO: Now that we no longer change GID for storage, this should to away.
22913        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22914                "setPermissionEnforced");
22915        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22916            synchronized (mPackages) {
22917                if (mSettings.mReadExternalStorageEnforced == null
22918                        || mSettings.mReadExternalStorageEnforced != enforced) {
22919                    mSettings.mReadExternalStorageEnforced =
22920                            enforced ? Boolean.TRUE : Boolean.FALSE;
22921                    mSettings.writeLPr();
22922                }
22923            }
22924            // kill any non-foreground processes so we restart them and
22925            // grant/revoke the GID.
22926            final IActivityManager am = ActivityManager.getService();
22927            if (am != null) {
22928                final long token = Binder.clearCallingIdentity();
22929                try {
22930                    am.killProcessesBelowForeground("setPermissionEnforcement");
22931                } catch (RemoteException e) {
22932                } finally {
22933                    Binder.restoreCallingIdentity(token);
22934                }
22935            }
22936        } else {
22937            throw new IllegalArgumentException("No selective enforcement for " + permission);
22938        }
22939    }
22940
22941    @Override
22942    @Deprecated
22943    public boolean isPermissionEnforced(String permission) {
22944        // allow instant applications
22945        return true;
22946    }
22947
22948    @Override
22949    public boolean isStorageLow() {
22950        // allow instant applications
22951        final long token = Binder.clearCallingIdentity();
22952        try {
22953            final DeviceStorageMonitorInternal
22954                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22955            if (dsm != null) {
22956                return dsm.isMemoryLow();
22957            } else {
22958                return false;
22959            }
22960        } finally {
22961            Binder.restoreCallingIdentity(token);
22962        }
22963    }
22964
22965    @Override
22966    public IPackageInstaller getPackageInstaller() {
22967        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22968            return null;
22969        }
22970        return mInstallerService;
22971    }
22972
22973    @Override
22974    public IArtManager getArtManager() {
22975        return mArtManagerService;
22976    }
22977
22978    private boolean userNeedsBadging(int userId) {
22979        int index = mUserNeedsBadging.indexOfKey(userId);
22980        if (index < 0) {
22981            final UserInfo userInfo;
22982            final long token = Binder.clearCallingIdentity();
22983            try {
22984                userInfo = sUserManager.getUserInfo(userId);
22985            } finally {
22986                Binder.restoreCallingIdentity(token);
22987            }
22988            final boolean b;
22989            if (userInfo != null && userInfo.isManagedProfile()) {
22990                b = true;
22991            } else {
22992                b = false;
22993            }
22994            mUserNeedsBadging.put(userId, b);
22995            return b;
22996        }
22997        return mUserNeedsBadging.valueAt(index);
22998    }
22999
23000    @Override
23001    public KeySet getKeySetByAlias(String packageName, String alias) {
23002        if (packageName == null || alias == null) {
23003            return null;
23004        }
23005        synchronized(mPackages) {
23006            final PackageParser.Package pkg = mPackages.get(packageName);
23007            if (pkg == null) {
23008                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23009                throw new IllegalArgumentException("Unknown package: " + packageName);
23010            }
23011            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23012            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23013                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23014                throw new IllegalArgumentException("Unknown package: " + packageName);
23015            }
23016            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23017            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23018        }
23019    }
23020
23021    @Override
23022    public KeySet getSigningKeySet(String packageName) {
23023        if (packageName == null) {
23024            return null;
23025        }
23026        synchronized(mPackages) {
23027            final int callingUid = Binder.getCallingUid();
23028            final int callingUserId = UserHandle.getUserId(callingUid);
23029            final PackageParser.Package pkg = mPackages.get(packageName);
23030            if (pkg == null) {
23031                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23032                throw new IllegalArgumentException("Unknown package: " + packageName);
23033            }
23034            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23035            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23036                // filter and pretend the package doesn't exist
23037                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23038                        + ", uid:" + callingUid);
23039                throw new IllegalArgumentException("Unknown package: " + packageName);
23040            }
23041            if (pkg.applicationInfo.uid != callingUid
23042                    && Process.SYSTEM_UID != callingUid) {
23043                throw new SecurityException("May not access signing KeySet of other apps.");
23044            }
23045            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23046            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23047        }
23048    }
23049
23050    @Override
23051    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23052        final int callingUid = Binder.getCallingUid();
23053        if (getInstantAppPackageName(callingUid) != null) {
23054            return false;
23055        }
23056        if (packageName == null || ks == null) {
23057            return false;
23058        }
23059        synchronized(mPackages) {
23060            final PackageParser.Package pkg = mPackages.get(packageName);
23061            if (pkg == null
23062                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23063                            UserHandle.getUserId(callingUid))) {
23064                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23065                throw new IllegalArgumentException("Unknown package: " + packageName);
23066            }
23067            IBinder ksh = ks.getToken();
23068            if (ksh instanceof KeySetHandle) {
23069                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23070                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23071            }
23072            return false;
23073        }
23074    }
23075
23076    @Override
23077    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23078        final int callingUid = Binder.getCallingUid();
23079        if (getInstantAppPackageName(callingUid) != null) {
23080            return false;
23081        }
23082        if (packageName == null || ks == null) {
23083            return false;
23084        }
23085        synchronized(mPackages) {
23086            final PackageParser.Package pkg = mPackages.get(packageName);
23087            if (pkg == null
23088                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23089                            UserHandle.getUserId(callingUid))) {
23090                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23091                throw new IllegalArgumentException("Unknown package: " + packageName);
23092            }
23093            IBinder ksh = ks.getToken();
23094            if (ksh instanceof KeySetHandle) {
23095                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23096                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23097            }
23098            return false;
23099        }
23100    }
23101
23102    private void deletePackageIfUnusedLPr(final String packageName) {
23103        PackageSetting ps = mSettings.mPackages.get(packageName);
23104        if (ps == null) {
23105            return;
23106        }
23107        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23108            // TODO Implement atomic delete if package is unused
23109            // It is currently possible that the package will be deleted even if it is installed
23110            // after this method returns.
23111            mHandler.post(new Runnable() {
23112                public void run() {
23113                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23114                            0, PackageManager.DELETE_ALL_USERS);
23115                }
23116            });
23117        }
23118    }
23119
23120    /**
23121     * Check and throw if the given before/after packages would be considered a
23122     * downgrade.
23123     */
23124    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23125            throws PackageManagerException {
23126        if (after.getLongVersionCode() < before.getLongVersionCode()) {
23127            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23128                    "Update version code " + after.versionCode + " is older than current "
23129                    + before.getLongVersionCode());
23130        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23131            if (after.baseRevisionCode < before.baseRevisionCode) {
23132                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23133                        "Update base revision code " + after.baseRevisionCode
23134                        + " is older than current " + before.baseRevisionCode);
23135            }
23136
23137            if (!ArrayUtils.isEmpty(after.splitNames)) {
23138                for (int i = 0; i < after.splitNames.length; i++) {
23139                    final String splitName = after.splitNames[i];
23140                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23141                    if (j != -1) {
23142                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23143                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23144                                    "Update split " + splitName + " revision code "
23145                                    + after.splitRevisionCodes[i] + " is older than current "
23146                                    + before.splitRevisionCodes[j]);
23147                        }
23148                    }
23149                }
23150            }
23151        }
23152    }
23153
23154    private static class MoveCallbacks extends Handler {
23155        private static final int MSG_CREATED = 1;
23156        private static final int MSG_STATUS_CHANGED = 2;
23157
23158        private final RemoteCallbackList<IPackageMoveObserver>
23159                mCallbacks = new RemoteCallbackList<>();
23160
23161        private final SparseIntArray mLastStatus = new SparseIntArray();
23162
23163        public MoveCallbacks(Looper looper) {
23164            super(looper);
23165        }
23166
23167        public void register(IPackageMoveObserver callback) {
23168            mCallbacks.register(callback);
23169        }
23170
23171        public void unregister(IPackageMoveObserver callback) {
23172            mCallbacks.unregister(callback);
23173        }
23174
23175        @Override
23176        public void handleMessage(Message msg) {
23177            final SomeArgs args = (SomeArgs) msg.obj;
23178            final int n = mCallbacks.beginBroadcast();
23179            for (int i = 0; i < n; i++) {
23180                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23181                try {
23182                    invokeCallback(callback, msg.what, args);
23183                } catch (RemoteException ignored) {
23184                }
23185            }
23186            mCallbacks.finishBroadcast();
23187            args.recycle();
23188        }
23189
23190        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23191                throws RemoteException {
23192            switch (what) {
23193                case MSG_CREATED: {
23194                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23195                    break;
23196                }
23197                case MSG_STATUS_CHANGED: {
23198                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23199                    break;
23200                }
23201            }
23202        }
23203
23204        private void notifyCreated(int moveId, Bundle extras) {
23205            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23206
23207            final SomeArgs args = SomeArgs.obtain();
23208            args.argi1 = moveId;
23209            args.arg2 = extras;
23210            obtainMessage(MSG_CREATED, args).sendToTarget();
23211        }
23212
23213        private void notifyStatusChanged(int moveId, int status) {
23214            notifyStatusChanged(moveId, status, -1);
23215        }
23216
23217        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23218            Slog.v(TAG, "Move " + moveId + " status " + status);
23219
23220            final SomeArgs args = SomeArgs.obtain();
23221            args.argi1 = moveId;
23222            args.argi2 = status;
23223            args.arg3 = estMillis;
23224            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23225
23226            synchronized (mLastStatus) {
23227                mLastStatus.put(moveId, status);
23228            }
23229        }
23230    }
23231
23232    private final static class OnPermissionChangeListeners extends Handler {
23233        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23234
23235        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23236                new RemoteCallbackList<>();
23237
23238        public OnPermissionChangeListeners(Looper looper) {
23239            super(looper);
23240        }
23241
23242        @Override
23243        public void handleMessage(Message msg) {
23244            switch (msg.what) {
23245                case MSG_ON_PERMISSIONS_CHANGED: {
23246                    final int uid = msg.arg1;
23247                    handleOnPermissionsChanged(uid);
23248                } break;
23249            }
23250        }
23251
23252        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23253            mPermissionListeners.register(listener);
23254
23255        }
23256
23257        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23258            mPermissionListeners.unregister(listener);
23259        }
23260
23261        public void onPermissionsChanged(int uid) {
23262            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23263                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23264            }
23265        }
23266
23267        private void handleOnPermissionsChanged(int uid) {
23268            final int count = mPermissionListeners.beginBroadcast();
23269            try {
23270                for (int i = 0; i < count; i++) {
23271                    IOnPermissionsChangeListener callback = mPermissionListeners
23272                            .getBroadcastItem(i);
23273                    try {
23274                        callback.onPermissionsChanged(uid);
23275                    } catch (RemoteException e) {
23276                        Log.e(TAG, "Permission listener is dead", e);
23277                    }
23278                }
23279            } finally {
23280                mPermissionListeners.finishBroadcast();
23281            }
23282        }
23283    }
23284
23285    private class PackageManagerNative extends IPackageManagerNative.Stub {
23286        @Override
23287        public String[] getNamesForUids(int[] uids) throws RemoteException {
23288            final String[] results = PackageManagerService.this.getNamesForUids(uids);
23289            // massage results so they can be parsed by the native binder
23290            for (int i = results.length - 1; i >= 0; --i) {
23291                if (results[i] == null) {
23292                    results[i] = "";
23293                }
23294            }
23295            return results;
23296        }
23297
23298        // NB: this differentiates between preloads and sideloads
23299        @Override
23300        public String getInstallerForPackage(String packageName) throws RemoteException {
23301            final String installerName = getInstallerPackageName(packageName);
23302            if (!TextUtils.isEmpty(installerName)) {
23303                return installerName;
23304            }
23305            // differentiate between preload and sideload
23306            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23307            ApplicationInfo appInfo = getApplicationInfo(packageName,
23308                                    /*flags*/ 0,
23309                                    /*userId*/ callingUser);
23310            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23311                return "preload";
23312            }
23313            return "";
23314        }
23315
23316        @Override
23317        public long getVersionCodeForPackage(String packageName) throws RemoteException {
23318            try {
23319                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23320                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
23321                if (pInfo != null) {
23322                    return pInfo.getLongVersionCode();
23323                }
23324            } catch (Exception e) {
23325            }
23326            return 0;
23327        }
23328    }
23329
23330    private class PackageManagerInternalImpl extends PackageManagerInternal {
23331        @Override
23332        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23333                int flagValues, int userId) {
23334            PackageManagerService.this.updatePermissionFlags(
23335                    permName, packageName, flagMask, flagValues, userId);
23336        }
23337
23338        @Override
23339        public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23340            SigningDetails sd = getSigningDetails(packageName);
23341            if (sd == null) {
23342                return false;
23343            }
23344            return sd.hasSha256Certificate(restoringFromSigHash,
23345                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23346        }
23347
23348        @Override
23349        public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23350            SigningDetails sd = getSigningDetails(packageName);
23351            if (sd == null) {
23352                return false;
23353            }
23354            return sd.hasCertificate(restoringFromSig,
23355                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23356        }
23357
23358        private SigningDetails getSigningDetails(String packageName) {
23359            synchronized (mPackages) {
23360                if (packageName == null) {
23361                    return null;
23362                }
23363                PackageParser.Package p = mPackages.get(packageName);
23364                if (p == null) {
23365                    return null;
23366                }
23367                return p.mSigningDetails;
23368            }
23369        }
23370
23371        @Override
23372        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23373            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23374        }
23375
23376        @Override
23377        public boolean isInstantApp(String packageName, int userId) {
23378            return PackageManagerService.this.isInstantApp(packageName, userId);
23379        }
23380
23381        @Override
23382        public String getInstantAppPackageName(int uid) {
23383            return PackageManagerService.this.getInstantAppPackageName(uid);
23384        }
23385
23386        @Override
23387        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23388            synchronized (mPackages) {
23389                return PackageManagerService.this.filterAppAccessLPr(
23390                        (PackageSetting) pkg.mExtras, callingUid, userId);
23391            }
23392        }
23393
23394        @Override
23395        public PackageParser.Package getPackage(String packageName) {
23396            synchronized (mPackages) {
23397                packageName = resolveInternalPackageNameLPr(
23398                        packageName, PackageManager.VERSION_CODE_HIGHEST);
23399                return mPackages.get(packageName);
23400            }
23401        }
23402
23403        @Override
23404        public PackageList getPackageList(PackageListObserver observer) {
23405            synchronized (mPackages) {
23406                final int N = mPackages.size();
23407                final ArrayList<String> list = new ArrayList<>(N);
23408                for (int i = 0; i < N; i++) {
23409                    list.add(mPackages.keyAt(i));
23410                }
23411                final PackageList packageList = new PackageList(list, observer);
23412                if (observer != null) {
23413                    mPackageListObservers.add(packageList);
23414                }
23415                return packageList;
23416            }
23417        }
23418
23419        @Override
23420        public void removePackageListObserver(PackageListObserver observer) {
23421            synchronized (mPackages) {
23422                mPackageListObservers.remove(observer);
23423            }
23424        }
23425
23426        @Override
23427        public PackageParser.Package getDisabledPackage(String packageName) {
23428            synchronized (mPackages) {
23429                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
23430                return (ps != null) ? ps.pkg : null;
23431            }
23432        }
23433
23434        @Override
23435        public String getKnownPackageName(int knownPackage, int userId) {
23436            switch(knownPackage) {
23437                case PackageManagerInternal.PACKAGE_BROWSER:
23438                    return getDefaultBrowserPackageName(userId);
23439                case PackageManagerInternal.PACKAGE_INSTALLER:
23440                    return mRequiredInstallerPackage;
23441                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23442                    return mSetupWizardPackage;
23443                case PackageManagerInternal.PACKAGE_SYSTEM:
23444                    return "android";
23445                case PackageManagerInternal.PACKAGE_VERIFIER:
23446                    return mRequiredVerifierPackage;
23447                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23448                    return mSystemTextClassifierPackage;
23449            }
23450            return null;
23451        }
23452
23453        @Override
23454        public boolean isResolveActivityComponent(ComponentInfo component) {
23455            return mResolveActivity.packageName.equals(component.packageName)
23456                    && mResolveActivity.name.equals(component.name);
23457        }
23458
23459        @Override
23460        public void setLocationPackagesProvider(PackagesProvider provider) {
23461            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
23462        }
23463
23464        @Override
23465        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23466            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
23467        }
23468
23469        @Override
23470        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23471            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
23472        }
23473
23474        @Override
23475        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23476            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
23477        }
23478
23479        @Override
23480        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23481            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
23482        }
23483
23484        @Override
23485        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
23486            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
23487        }
23488
23489        @Override
23490        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23491            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
23492        }
23493
23494        @Override
23495        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23496            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
23497        }
23498
23499        @Override
23500        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23501            synchronized (mPackages) {
23502                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23503            }
23504            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
23505        }
23506
23507        @Override
23508        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23509            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
23510                    packageName, userId);
23511        }
23512
23513        @Override
23514        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
23515            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
23516                    packageName, userId);
23517        }
23518
23519        @Override
23520        public void setKeepUninstalledPackages(final List<String> packageList) {
23521            Preconditions.checkNotNull(packageList);
23522            List<String> removedFromList = null;
23523            synchronized (mPackages) {
23524                if (mKeepUninstalledPackages != null) {
23525                    final int packagesCount = mKeepUninstalledPackages.size();
23526                    for (int i = 0; i < packagesCount; i++) {
23527                        String oldPackage = mKeepUninstalledPackages.get(i);
23528                        if (packageList != null && packageList.contains(oldPackage)) {
23529                            continue;
23530                        }
23531                        if (removedFromList == null) {
23532                            removedFromList = new ArrayList<>();
23533                        }
23534                        removedFromList.add(oldPackage);
23535                    }
23536                }
23537                mKeepUninstalledPackages = new ArrayList<>(packageList);
23538                if (removedFromList != null) {
23539                    final int removedCount = removedFromList.size();
23540                    for (int i = 0; i < removedCount; i++) {
23541                        deletePackageIfUnusedLPr(removedFromList.get(i));
23542                    }
23543                }
23544            }
23545        }
23546
23547        @Override
23548        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23549            synchronized (mPackages) {
23550                return mPermissionManager.isPermissionsReviewRequired(
23551                        mPackages.get(packageName), userId);
23552            }
23553        }
23554
23555        @Override
23556        public PackageInfo getPackageInfo(
23557                String packageName, int flags, int filterCallingUid, int userId) {
23558            return PackageManagerService.this
23559                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23560                            flags, filterCallingUid, userId);
23561        }
23562
23563        @Override
23564        public int getPackageUid(String packageName, int flags, int userId) {
23565            return PackageManagerService.this
23566                    .getPackageUid(packageName, flags, userId);
23567        }
23568
23569        @Override
23570        public ApplicationInfo getApplicationInfo(
23571                String packageName, int flags, int filterCallingUid, int userId) {
23572            return PackageManagerService.this
23573                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23574        }
23575
23576        @Override
23577        public ActivityInfo getActivityInfo(
23578                ComponentName component, int flags, int filterCallingUid, int userId) {
23579            return PackageManagerService.this
23580                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23581        }
23582
23583        @Override
23584        public List<ResolveInfo> queryIntentActivities(
23585                Intent intent, int flags, int filterCallingUid, int userId) {
23586            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23587            return PackageManagerService.this
23588                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23589                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23590        }
23591
23592        @Override
23593        public List<ResolveInfo> queryIntentServices(
23594                Intent intent, int flags, int callingUid, int userId) {
23595            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23596            return PackageManagerService.this
23597                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23598                            false);
23599        }
23600
23601        @Override
23602        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23603                int userId) {
23604            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23605        }
23606
23607        @Override
23608        public ComponentName getDefaultHomeActivity(int userId) {
23609            return PackageManagerService.this.getDefaultHomeActivity(userId);
23610        }
23611
23612        @Override
23613        public void setDeviceAndProfileOwnerPackages(
23614                int deviceOwnerUserId, String deviceOwnerPackage,
23615                SparseArray<String> profileOwnerPackages) {
23616            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23617                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23618        }
23619
23620        @Override
23621        public boolean isPackageDataProtected(int userId, String packageName) {
23622            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23623        }
23624
23625        @Override
23626        public boolean isPackageEphemeral(int userId, String packageName) {
23627            synchronized (mPackages) {
23628                final PackageSetting ps = mSettings.mPackages.get(packageName);
23629                return ps != null ? ps.getInstantApp(userId) : false;
23630            }
23631        }
23632
23633        @Override
23634        public boolean wasPackageEverLaunched(String packageName, int userId) {
23635            synchronized (mPackages) {
23636                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23637            }
23638        }
23639
23640        @Override
23641        public void grantRuntimePermission(String packageName, String permName, int userId,
23642                boolean overridePolicy) {
23643            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23644                    permName, packageName, overridePolicy, getCallingUid(), userId,
23645                    mPermissionCallback);
23646        }
23647
23648        @Override
23649        public void revokeRuntimePermission(String packageName, String permName, int userId,
23650                boolean overridePolicy) {
23651            mPermissionManager.revokeRuntimePermission(
23652                    permName, packageName, overridePolicy, getCallingUid(), userId,
23653                    mPermissionCallback);
23654        }
23655
23656        @Override
23657        public String getNameForUid(int uid) {
23658            return PackageManagerService.this.getNameForUid(uid);
23659        }
23660
23661        @Override
23662        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23663                Intent origIntent, String resolvedType, String callingPackage,
23664                Bundle verificationBundle, int userId) {
23665            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23666                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23667                    userId);
23668        }
23669
23670        @Override
23671        public void grantEphemeralAccess(int userId, Intent intent,
23672                int targetAppId, int ephemeralAppId) {
23673            synchronized (mPackages) {
23674                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23675                        targetAppId, ephemeralAppId);
23676            }
23677        }
23678
23679        @Override
23680        public boolean isInstantAppInstallerComponent(ComponentName component) {
23681            synchronized (mPackages) {
23682                return mInstantAppInstallerActivity != null
23683                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23684            }
23685        }
23686
23687        @Override
23688        public void pruneInstantApps() {
23689            mInstantAppRegistry.pruneInstantApps();
23690        }
23691
23692        @Override
23693        public String getSetupWizardPackageName() {
23694            return mSetupWizardPackage;
23695        }
23696
23697        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23698            if (policy != null) {
23699                mExternalSourcesPolicy = policy;
23700            }
23701        }
23702
23703        @Override
23704        public boolean isPackagePersistent(String packageName) {
23705            synchronized (mPackages) {
23706                PackageParser.Package pkg = mPackages.get(packageName);
23707                return pkg != null
23708                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23709                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23710                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23711                        : false;
23712            }
23713        }
23714
23715        @Override
23716        public boolean isLegacySystemApp(Package pkg) {
23717            synchronized (mPackages) {
23718                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23719                return mPromoteSystemApps
23720                        && ps.isSystem()
23721                        && mExistingSystemPackages.contains(ps.name);
23722            }
23723        }
23724
23725        @Override
23726        public List<PackageInfo> getOverlayPackages(int userId) {
23727            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23728            synchronized (mPackages) {
23729                for (PackageParser.Package p : mPackages.values()) {
23730                    if (p.mOverlayTarget != null) {
23731                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23732                        if (pkg != null) {
23733                            overlayPackages.add(pkg);
23734                        }
23735                    }
23736                }
23737            }
23738            return overlayPackages;
23739        }
23740
23741        @Override
23742        public List<String> getTargetPackageNames(int userId) {
23743            List<String> targetPackages = new ArrayList<>();
23744            synchronized (mPackages) {
23745                for (PackageParser.Package p : mPackages.values()) {
23746                    if (p.mOverlayTarget == null) {
23747                        targetPackages.add(p.packageName);
23748                    }
23749                }
23750            }
23751            return targetPackages;
23752        }
23753
23754        @Override
23755        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23756                @Nullable List<String> overlayPackageNames) {
23757            synchronized (mPackages) {
23758                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23759                    Slog.e(TAG, "failed to find package " + targetPackageName);
23760                    return false;
23761                }
23762                ArrayList<String> overlayPaths = null;
23763                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23764                    final int N = overlayPackageNames.size();
23765                    overlayPaths = new ArrayList<>(N);
23766                    for (int i = 0; i < N; i++) {
23767                        final String packageName = overlayPackageNames.get(i);
23768                        final PackageParser.Package pkg = mPackages.get(packageName);
23769                        if (pkg == null) {
23770                            Slog.e(TAG, "failed to find package " + packageName);
23771                            return false;
23772                        }
23773                        overlayPaths.add(pkg.baseCodePath);
23774                    }
23775                }
23776
23777                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23778                ps.setOverlayPaths(overlayPaths, userId);
23779                return true;
23780            }
23781        }
23782
23783        @Override
23784        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23785                int flags, int userId, boolean resolveForStart) {
23786            return resolveIntentInternal(
23787                    intent, resolvedType, flags, userId, resolveForStart);
23788        }
23789
23790        @Override
23791        public ResolveInfo resolveService(Intent intent, String resolvedType,
23792                int flags, int userId, int callingUid) {
23793            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23794        }
23795
23796        @Override
23797        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23798            return PackageManagerService.this.resolveContentProviderInternal(
23799                    name, flags, userId);
23800        }
23801
23802        @Override
23803        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23804            synchronized (mPackages) {
23805                mIsolatedOwners.put(isolatedUid, ownerUid);
23806            }
23807        }
23808
23809        @Override
23810        public void removeIsolatedUid(int isolatedUid) {
23811            synchronized (mPackages) {
23812                mIsolatedOwners.delete(isolatedUid);
23813            }
23814        }
23815
23816        @Override
23817        public int getUidTargetSdkVersion(int uid) {
23818            synchronized (mPackages) {
23819                return getUidTargetSdkVersionLockedLPr(uid);
23820            }
23821        }
23822
23823        @Override
23824        public int getPackageTargetSdkVersion(String packageName) {
23825            synchronized (mPackages) {
23826                return getPackageTargetSdkVersionLockedLPr(packageName);
23827            }
23828        }
23829
23830        @Override
23831        public boolean canAccessInstantApps(int callingUid, int userId) {
23832            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23833        }
23834
23835        @Override
23836        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23837            synchronized (mPackages) {
23838                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23839            }
23840        }
23841
23842        @Override
23843        public void notifyPackageUse(String packageName, int reason) {
23844            synchronized (mPackages) {
23845                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23846            }
23847        }
23848    }
23849
23850    @Override
23851    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23852        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23853        synchronized (mPackages) {
23854            final long identity = Binder.clearCallingIdentity();
23855            try {
23856                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23857                        packageNames, userId);
23858            } finally {
23859                Binder.restoreCallingIdentity(identity);
23860            }
23861        }
23862    }
23863
23864    @Override
23865    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23866        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23867        synchronized (mPackages) {
23868            final long identity = Binder.clearCallingIdentity();
23869            try {
23870                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23871                        packageNames, userId);
23872            } finally {
23873                Binder.restoreCallingIdentity(identity);
23874            }
23875        }
23876    }
23877
23878    private static void enforceSystemOrPhoneCaller(String tag) {
23879        int callingUid = Binder.getCallingUid();
23880        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23881            throw new SecurityException(
23882                    "Cannot call " + tag + " from UID " + callingUid);
23883        }
23884    }
23885
23886    boolean isHistoricalPackageUsageAvailable() {
23887        return mPackageUsage.isHistoricalPackageUsageAvailable();
23888    }
23889
23890    /**
23891     * Return a <b>copy</b> of the collection of packages known to the package manager.
23892     * @return A copy of the values of mPackages.
23893     */
23894    Collection<PackageParser.Package> getPackages() {
23895        synchronized (mPackages) {
23896            return new ArrayList<>(mPackages.values());
23897        }
23898    }
23899
23900    /**
23901     * Logs process start information (including base APK hash) to the security log.
23902     * @hide
23903     */
23904    @Override
23905    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23906            String apkFile, int pid) {
23907        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23908            return;
23909        }
23910        if (!SecurityLog.isLoggingEnabled()) {
23911            return;
23912        }
23913        Bundle data = new Bundle();
23914        data.putLong("startTimestamp", System.currentTimeMillis());
23915        data.putString("processName", processName);
23916        data.putInt("uid", uid);
23917        data.putString("seinfo", seinfo);
23918        data.putString("apkFile", apkFile);
23919        data.putInt("pid", pid);
23920        Message msg = mProcessLoggingHandler.obtainMessage(
23921                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23922        msg.setData(data);
23923        mProcessLoggingHandler.sendMessage(msg);
23924    }
23925
23926    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23927        return mCompilerStats.getPackageStats(pkgName);
23928    }
23929
23930    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23931        return getOrCreateCompilerPackageStats(pkg.packageName);
23932    }
23933
23934    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23935        return mCompilerStats.getOrCreatePackageStats(pkgName);
23936    }
23937
23938    public void deleteCompilerPackageStats(String pkgName) {
23939        mCompilerStats.deletePackageStats(pkgName);
23940    }
23941
23942    @Override
23943    public int getInstallReason(String packageName, int userId) {
23944        final int callingUid = Binder.getCallingUid();
23945        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23946                true /* requireFullPermission */, false /* checkShell */,
23947                "get install reason");
23948        synchronized (mPackages) {
23949            final PackageSetting ps = mSettings.mPackages.get(packageName);
23950            if (filterAppAccessLPr(ps, callingUid, userId)) {
23951                return PackageManager.INSTALL_REASON_UNKNOWN;
23952            }
23953            if (ps != null) {
23954                return ps.getInstallReason(userId);
23955            }
23956        }
23957        return PackageManager.INSTALL_REASON_UNKNOWN;
23958    }
23959
23960    @Override
23961    public boolean canRequestPackageInstalls(String packageName, int userId) {
23962        return canRequestPackageInstallsInternal(packageName, 0, userId,
23963                true /* throwIfPermNotDeclared*/);
23964    }
23965
23966    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23967            boolean throwIfPermNotDeclared) {
23968        int callingUid = Binder.getCallingUid();
23969        int uid = getPackageUid(packageName, 0, userId);
23970        if (callingUid != uid && callingUid != Process.ROOT_UID
23971                && callingUid != Process.SYSTEM_UID) {
23972            throw new SecurityException(
23973                    "Caller uid " + callingUid + " does not own package " + packageName);
23974        }
23975        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23976        if (info == null) {
23977            return false;
23978        }
23979        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23980            return false;
23981        }
23982        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23983        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23984        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23985            if (throwIfPermNotDeclared) {
23986                throw new SecurityException("Need to declare " + appOpPermission
23987                        + " to call this api");
23988            } else {
23989                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23990                return false;
23991            }
23992        }
23993        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23994            return false;
23995        }
23996        if (mExternalSourcesPolicy != null) {
23997            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23998            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23999                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24000            }
24001        }
24002        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24003    }
24004
24005    @Override
24006    public ComponentName getInstantAppResolverSettingsComponent() {
24007        return mInstantAppResolverSettingsComponent;
24008    }
24009
24010    @Override
24011    public ComponentName getInstantAppInstallerComponent() {
24012        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24013            return null;
24014        }
24015        return mInstantAppInstallerActivity == null
24016                ? null : mInstantAppInstallerActivity.getComponentName();
24017    }
24018
24019    @Override
24020    public String getInstantAppAndroidId(String packageName, int userId) {
24021        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24022                "getInstantAppAndroidId");
24023        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24024                true /* requireFullPermission */, false /* checkShell */,
24025                "getInstantAppAndroidId");
24026        // Make sure the target is an Instant App.
24027        if (!isInstantApp(packageName, userId)) {
24028            return null;
24029        }
24030        synchronized (mPackages) {
24031            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24032        }
24033    }
24034
24035    boolean canHaveOatDir(String packageName) {
24036        synchronized (mPackages) {
24037            PackageParser.Package p = mPackages.get(packageName);
24038            if (p == null) {
24039                return false;
24040            }
24041            return p.canHaveOatDir();
24042        }
24043    }
24044
24045    private String getOatDir(PackageParser.Package pkg) {
24046        if (!pkg.canHaveOatDir()) {
24047            return null;
24048        }
24049        File codePath = new File(pkg.codePath);
24050        if (codePath.isDirectory()) {
24051            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24052        }
24053        return null;
24054    }
24055
24056    void deleteOatArtifactsOfPackage(String packageName) {
24057        final String[] instructionSets;
24058        final List<String> codePaths;
24059        final String oatDir;
24060        final PackageParser.Package pkg;
24061        synchronized (mPackages) {
24062            pkg = mPackages.get(packageName);
24063        }
24064        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24065        codePaths = pkg.getAllCodePaths();
24066        oatDir = getOatDir(pkg);
24067
24068        for (String codePath : codePaths) {
24069            for (String isa : instructionSets) {
24070                try {
24071                    mInstaller.deleteOdex(codePath, isa, oatDir);
24072                } catch (InstallerException e) {
24073                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24074                }
24075            }
24076        }
24077    }
24078
24079    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24080        Set<String> unusedPackages = new HashSet<>();
24081        long currentTimeInMillis = System.currentTimeMillis();
24082        synchronized (mPackages) {
24083            for (PackageParser.Package pkg : mPackages.values()) {
24084                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
24085                if (ps == null) {
24086                    continue;
24087                }
24088                PackageDexUsage.PackageUseInfo packageUseInfo =
24089                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24090                if (PackageManagerServiceUtils
24091                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24092                                downgradeTimeThresholdMillis, packageUseInfo,
24093                                pkg.getLatestPackageUseTimeInMills(),
24094                                pkg.getLatestForegroundPackageUseTimeInMills())) {
24095                    unusedPackages.add(pkg.packageName);
24096                }
24097            }
24098        }
24099        return unusedPackages;
24100    }
24101
24102    @Override
24103    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24104            int userId) {
24105        final int callingUid = Binder.getCallingUid();
24106        final int callingAppId = UserHandle.getAppId(callingUid);
24107
24108        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24109                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24110
24111        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24112                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24113            throw new SecurityException("Caller must have the "
24114                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24115        }
24116
24117        synchronized(mPackages) {
24118            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24119            scheduleWritePackageRestrictionsLocked(userId);
24120        }
24121    }
24122
24123    @Nullable
24124    @Override
24125    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24126        final int callingUid = Binder.getCallingUid();
24127        final int callingAppId = UserHandle.getAppId(callingUid);
24128
24129        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24130                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24131
24132        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24133                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24134            throw new SecurityException("Caller must have the "
24135                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24136        }
24137
24138        synchronized(mPackages) {
24139            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24140        }
24141    }
24142}
24143
24144interface PackageSender {
24145    /**
24146     * @param userIds User IDs where the action occurred on a full application
24147     * @param instantUserIds User IDs where the action occurred on an instant application
24148     */
24149    void sendPackageBroadcast(final String action, final String pkg,
24150        final Bundle extras, final int flags, final String targetPkg,
24151        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24152    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24153        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24154    void notifyPackageAdded(String packageName);
24155    void notifyPackageRemoved(String packageName);
24156}
24157