PackageManagerService.java revision 27ccbb12a56fde73b4fa8aa8eb63eead1b6daeed
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.SELinuxUtil;
189import android.content.pm.ServiceInfo;
190import android.content.pm.SharedLibraryInfo;
191import android.content.pm.Signature;
192import android.content.pm.UserInfo;
193import android.content.pm.VerifierDeviceIdentity;
194import android.content.pm.VerifierInfo;
195import android.content.pm.VersionedPackage;
196import android.content.pm.dex.ArtManager;
197import android.content.pm.dex.DexMetadataHelper;
198import android.content.pm.dex.IArtManager;
199import android.content.res.Resources;
200import android.database.ContentObserver;
201import android.graphics.Bitmap;
202import android.hardware.display.DisplayManager;
203import android.net.Uri;
204import android.os.Binder;
205import android.os.Build;
206import android.os.Bundle;
207import android.os.Debug;
208import android.os.Environment;
209import android.os.Environment.UserEnvironment;
210import android.os.FileUtils;
211import android.os.Handler;
212import android.os.IBinder;
213import android.os.Looper;
214import android.os.Message;
215import android.os.Parcel;
216import android.os.ParcelFileDescriptor;
217import android.os.PatternMatcher;
218import android.os.Process;
219import android.os.RemoteCallbackList;
220import android.os.RemoteException;
221import android.os.ResultReceiver;
222import android.os.SELinux;
223import android.os.ServiceManager;
224import android.os.ShellCallback;
225import android.os.SystemClock;
226import android.os.SystemProperties;
227import android.os.Trace;
228import android.os.UserHandle;
229import android.os.UserManager;
230import android.os.UserManagerInternal;
231import android.os.storage.IStorageManager;
232import android.os.storage.StorageEventListener;
233import android.os.storage.StorageManager;
234import android.os.storage.StorageManagerInternal;
235import android.os.storage.VolumeInfo;
236import android.os.storage.VolumeRecord;
237import android.provider.Settings.Global;
238import android.provider.Settings.Secure;
239import android.security.KeyStore;
240import android.security.SystemKeyStore;
241import android.service.pm.PackageServiceDumpProto;
242import android.service.textclassifier.TextClassifierService;
243import android.system.ErrnoException;
244import android.system.Os;
245import android.text.TextUtils;
246import android.text.format.DateUtils;
247import android.util.ArrayMap;
248import android.util.ArraySet;
249import android.util.Base64;
250import android.util.ByteStringUtils;
251import android.util.DisplayMetrics;
252import android.util.EventLog;
253import android.util.ExceptionUtils;
254import android.util.Log;
255import android.util.LogPrinter;
256import android.util.LongSparseArray;
257import android.util.LongSparseLongArray;
258import android.util.MathUtils;
259import android.util.PackageUtils;
260import android.util.Pair;
261import android.util.PrintStreamPrinter;
262import android.util.Slog;
263import android.util.SparseArray;
264import android.util.SparseBooleanArray;
265import android.util.SparseIntArray;
266import android.util.TimingsTraceLog;
267import android.util.Xml;
268import android.util.jar.StrictJarFile;
269import android.util.proto.ProtoOutputStream;
270import android.view.Display;
271
272import com.android.internal.R;
273import com.android.internal.annotations.GuardedBy;
274import com.android.internal.app.IMediaContainerService;
275import com.android.internal.app.ResolverActivity;
276import com.android.internal.content.NativeLibraryHelper;
277import com.android.internal.content.PackageHelper;
278import com.android.internal.logging.MetricsLogger;
279import com.android.internal.os.IParcelFileDescriptorFactory;
280import com.android.internal.os.SomeArgs;
281import com.android.internal.os.Zygote;
282import com.android.internal.telephony.CarrierAppUtils;
283import com.android.internal.util.ArrayUtils;
284import com.android.internal.util.ConcurrentUtils;
285import com.android.internal.util.DumpUtils;
286import com.android.internal.util.FastXmlSerializer;
287import com.android.internal.util.IndentingPrintWriter;
288import com.android.internal.util.Preconditions;
289import com.android.internal.util.XmlUtils;
290import com.android.server.AttributeCache;
291import com.android.server.DeviceIdleController;
292import com.android.server.EventLogTags;
293import com.android.server.FgThread;
294import com.android.server.IntentResolver;
295import com.android.server.LocalServices;
296import com.android.server.LockGuard;
297import com.android.server.ServiceThread;
298import com.android.server.SystemConfig;
299import com.android.server.SystemServerInitThreadPool;
300import com.android.server.Watchdog;
301import com.android.server.net.NetworkPolicyManagerInternal;
302import com.android.server.pm.Installer.InstallerException;
303import com.android.server.pm.Settings.DatabaseVersion;
304import com.android.server.pm.Settings.VersionInfo;
305import com.android.server.pm.dex.ArtManagerService;
306import com.android.server.pm.dex.DexLogger;
307import com.android.server.pm.dex.DexManager;
308import com.android.server.pm.dex.DexoptOptions;
309import com.android.server.pm.dex.PackageDexUsage;
310import com.android.server.pm.permission.BasePermission;
311import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
312import com.android.server.pm.permission.PermissionManagerService;
313import com.android.server.pm.permission.PermissionManagerInternal;
314import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
315import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
316import com.android.server.pm.permission.PermissionsState;
317import com.android.server.pm.permission.PermissionsState.PermissionState;
318import com.android.server.security.VerityUtils;
319import com.android.server.storage.DeviceStorageMonitorInternal;
320
321import dalvik.system.CloseGuard;
322import dalvik.system.VMRuntime;
323
324import libcore.io.IoUtils;
325
326import org.xmlpull.v1.XmlPullParser;
327import org.xmlpull.v1.XmlPullParserException;
328import org.xmlpull.v1.XmlSerializer;
329
330import java.io.BufferedOutputStream;
331import java.io.ByteArrayInputStream;
332import java.io.ByteArrayOutputStream;
333import java.io.File;
334import java.io.FileDescriptor;
335import java.io.FileInputStream;
336import java.io.FileOutputStream;
337import java.io.FilenameFilter;
338import java.io.IOException;
339import java.io.PrintWriter;
340import java.lang.annotation.Retention;
341import java.lang.annotation.RetentionPolicy;
342import java.nio.charset.StandardCharsets;
343import java.security.DigestException;
344import java.security.DigestInputStream;
345import java.security.MessageDigest;
346import java.security.NoSuchAlgorithmException;
347import java.security.PublicKey;
348import java.security.SecureRandom;
349import java.security.cert.CertificateException;
350import java.util.ArrayList;
351import java.util.Arrays;
352import java.util.Collection;
353import java.util.Collections;
354import java.util.Comparator;
355import java.util.HashMap;
356import java.util.HashSet;
357import java.util.Iterator;
358import java.util.LinkedHashSet;
359import java.util.List;
360import java.util.Map;
361import java.util.Objects;
362import java.util.Set;
363import java.util.concurrent.CountDownLatch;
364import java.util.concurrent.Future;
365import java.util.concurrent.TimeUnit;
366import java.util.concurrent.atomic.AtomicBoolean;
367import java.util.concurrent.atomic.AtomicInteger;
368
369/**
370 * Keep track of all those APKs everywhere.
371 * <p>
372 * Internally there are two important locks:
373 * <ul>
374 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
375 * and other related state. It is a fine-grained lock that should only be held
376 * momentarily, as it's one of the most contended locks in the system.
377 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
378 * operations typically involve heavy lifting of application data on disk. Since
379 * {@code installd} is single-threaded, and it's operations can often be slow,
380 * this lock should never be acquired while already holding {@link #mPackages}.
381 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
382 * holding {@link #mInstallLock}.
383 * </ul>
384 * Many internal methods rely on the caller to hold the appropriate locks, and
385 * this contract is expressed through method name suffixes:
386 * <ul>
387 * <li>fooLI(): the caller must hold {@link #mInstallLock}
388 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
389 * being modified must be frozen
390 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
391 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
392 * </ul>
393 * <p>
394 * Because this class is very central to the platform's security; please run all
395 * CTS and unit tests whenever making modifications:
396 *
397 * <pre>
398 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
399 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
400 * </pre>
401 */
402public class PackageManagerService extends IPackageManager.Stub
403        implements PackageSender {
404    static final String TAG = "PackageManager";
405    public static final boolean DEBUG_SETTINGS = false;
406    static final boolean DEBUG_PREFERRED = false;
407    static final boolean DEBUG_UPGRADE = false;
408    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
409    private static final boolean DEBUG_BACKUP = false;
410    public static final boolean DEBUG_INSTALL = false;
411    public static final boolean DEBUG_REMOVE = false;
412    private static final boolean DEBUG_BROADCASTS = false;
413    private static final boolean DEBUG_SHOW_INFO = false;
414    private static final boolean DEBUG_PACKAGE_INFO = false;
415    private static final boolean DEBUG_INTENT_MATCHING = false;
416    public static final boolean DEBUG_PACKAGE_SCANNING = false;
417    private static final boolean DEBUG_VERIFY = false;
418    private static final boolean DEBUG_FILTERS = false;
419    public static final boolean DEBUG_PERMISSIONS = false;
420    private static final boolean DEBUG_SHARED_LIBRARIES = false;
421    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
422
423    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
424    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
425    // user, but by default initialize to this.
426    public static final boolean DEBUG_DEXOPT = false;
427
428    private static final boolean DEBUG_ABI_SELECTION = false;
429    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
430    private static final boolean DEBUG_TRIAGED_MISSING = false;
431    private static final boolean DEBUG_APP_DATA = false;
432
433    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
434    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
435
436    private static final boolean HIDE_EPHEMERAL_APIS = false;
437
438    private static final boolean ENABLE_FREE_CACHE_V2 =
439            SystemProperties.getBoolean("fw.free_cache_v2", true);
440
441    private static final int RADIO_UID = Process.PHONE_UID;
442    private static final int LOG_UID = Process.LOG_UID;
443    private static final int NFC_UID = Process.NFC_UID;
444    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
445    private static final int SHELL_UID = Process.SHELL_UID;
446    private static final int SE_UID = Process.SE_UID;
447
448    // Suffix used during package installation when copying/moving
449    // package apks to install directory.
450    private static final String INSTALL_PACKAGE_SUFFIX = "-";
451
452    static final int SCAN_NO_DEX = 1<<0;
453    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
454    static final int SCAN_NEW_INSTALL = 1<<2;
455    static final int SCAN_UPDATE_TIME = 1<<3;
456    static final int SCAN_BOOTING = 1<<4;
457    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
458    static final int SCAN_REQUIRE_KNOWN = 1<<7;
459    static final int SCAN_MOVE = 1<<8;
460    static final int SCAN_INITIAL = 1<<9;
461    static final int SCAN_CHECK_ONLY = 1<<10;
462    static final int SCAN_DONT_KILL_APP = 1<<11;
463    static final int SCAN_IGNORE_FROZEN = 1<<12;
464    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
465    static final int SCAN_AS_INSTANT_APP = 1<<14;
466    static final int SCAN_AS_FULL_APP = 1<<15;
467    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
468    static final int SCAN_AS_SYSTEM = 1<<17;
469    static final int SCAN_AS_PRIVILEGED = 1<<18;
470    static final int SCAN_AS_OEM = 1<<19;
471    static final int SCAN_AS_VENDOR = 1<<20;
472    static final int SCAN_AS_PRODUCT = 1<<21;
473
474    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
475            SCAN_NO_DEX,
476            SCAN_UPDATE_SIGNATURE,
477            SCAN_NEW_INSTALL,
478            SCAN_UPDATE_TIME,
479            SCAN_BOOTING,
480            SCAN_DELETE_DATA_ON_FAILURES,
481            SCAN_REQUIRE_KNOWN,
482            SCAN_MOVE,
483            SCAN_INITIAL,
484            SCAN_CHECK_ONLY,
485            SCAN_DONT_KILL_APP,
486            SCAN_IGNORE_FROZEN,
487            SCAN_FIRST_BOOT_OR_UPGRADE,
488            SCAN_AS_INSTANT_APP,
489            SCAN_AS_FULL_APP,
490            SCAN_AS_VIRTUAL_PRELOAD,
491    })
492    @Retention(RetentionPolicy.SOURCE)
493    public @interface ScanFlags {}
494
495    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
496    /** Extension of the compressed packages */
497    public final static String COMPRESSED_EXTENSION = ".gz";
498    /** Suffix of stub packages on the system partition */
499    public final static String STUB_SUFFIX = "-Stub";
500
501    private static final int[] EMPTY_INT_ARRAY = new int[0];
502
503    private static final int TYPE_UNKNOWN = 0;
504    private static final int TYPE_ACTIVITY = 1;
505    private static final int TYPE_RECEIVER = 2;
506    private static final int TYPE_SERVICE = 3;
507    private static final int TYPE_PROVIDER = 4;
508    @IntDef(prefix = { "TYPE_" }, value = {
509            TYPE_UNKNOWN,
510            TYPE_ACTIVITY,
511            TYPE_RECEIVER,
512            TYPE_SERVICE,
513            TYPE_PROVIDER,
514    })
515    @Retention(RetentionPolicy.SOURCE)
516    public @interface ComponentType {}
517
518    /**
519     * Timeout (in milliseconds) after which the watchdog should declare that
520     * our handler thread is wedged.  The usual default for such things is one
521     * minute but we sometimes do very lengthy I/O operations on this thread,
522     * such as installing multi-gigabyte applications, so ours needs to be longer.
523     */
524    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
525
526    /**
527     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
528     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
529     * settings entry if available, otherwise we use the hardcoded default.  If it's been
530     * more than this long since the last fstrim, we force one during the boot sequence.
531     *
532     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
533     * one gets run at the next available charging+idle time.  This final mandatory
534     * no-fstrim check kicks in only of the other scheduling criteria is never met.
535     */
536    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
537
538    /**
539     * Whether verification is enabled by default.
540     */
541    private static final boolean DEFAULT_VERIFY_ENABLE = true;
542
543    /**
544     * The default maximum time to wait for the verification agent to return in
545     * milliseconds.
546     */
547    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
548
549    /**
550     * The default response for package verification timeout.
551     *
552     * This can be either PackageManager.VERIFICATION_ALLOW or
553     * PackageManager.VERIFICATION_REJECT.
554     */
555    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
556
557    public static final String PLATFORM_PACKAGE_NAME = "android";
558
559    public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
560
561    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
562            DEFAULT_CONTAINER_PACKAGE,
563            "com.android.defcontainer.DefaultContainerService");
564
565    private static final String KILL_APP_REASON_GIDS_CHANGED =
566            "permission grant or revoke changed gids";
567
568    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
569            "permissions revoked";
570
571    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
572
573    private static final String PACKAGE_SCHEME = "package";
574
575    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
576
577    private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
578
579    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
580
581    /** Canonical intent used to identify what counts as a "web browser" app */
582    private static final Intent sBrowserIntent;
583    static {
584        sBrowserIntent = new Intent();
585        sBrowserIntent.setAction(Intent.ACTION_VIEW);
586        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
587        sBrowserIntent.setData(Uri.parse("http:"));
588        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
589    }
590
591    /**
592     * The set of all protected actions [i.e. those actions for which a high priority
593     * intent filter is disallowed].
594     */
595    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
596    static {
597        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
598        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
599        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
600        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
601    }
602
603    // Compilation reasons.
604    public static final int REASON_UNKNOWN = -1;
605    public static final int REASON_FIRST_BOOT = 0;
606    public static final int REASON_BOOT = 1;
607    public static final int REASON_INSTALL = 2;
608    public static final int REASON_BACKGROUND_DEXOPT = 3;
609    public static final int REASON_AB_OTA = 4;
610    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
611    public static final int REASON_SHARED = 6;
612
613    public static final int REASON_LAST = REASON_SHARED;
614
615    /**
616     * Version number for the package parser cache. Increment this whenever the format or
617     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
618     */
619    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
620
621    /**
622     * Whether the package parser cache is enabled.
623     */
624    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
625
626    /**
627     * Permissions required in order to receive instant application lifecycle broadcasts.
628     */
629    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
630            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
631
632    final ServiceThread mHandlerThread;
633
634    final PackageHandler mHandler;
635
636    private final ProcessLoggingHandler mProcessLoggingHandler;
637
638    /**
639     * Messages for {@link #mHandler} that need to wait for system ready before
640     * being dispatched.
641     */
642    private ArrayList<Message> mPostSystemReadyMessages;
643
644    final int mSdkVersion = Build.VERSION.SDK_INT;
645
646    final Context mContext;
647    final boolean mFactoryTest;
648    final boolean mOnlyCore;
649    final DisplayMetrics mMetrics;
650    final int mDefParseFlags;
651    final String[] mSeparateProcesses;
652    final boolean mIsUpgrade;
653    final boolean mIsPreNUpgrade;
654    final boolean mIsPreNMR1Upgrade;
655
656    // Have we told the Activity Manager to whitelist the default container service by uid yet?
657    @GuardedBy("mPackages")
658    boolean mDefaultContainerWhitelisted = false;
659
660    @GuardedBy("mPackages")
661    private boolean mDexOptDialogShown;
662
663    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
664    // LOCK HELD.  Can be called with mInstallLock held.
665    @GuardedBy("mInstallLock")
666    final Installer mInstaller;
667
668    /** Directory where installed applications are stored */
669    private static final File sAppInstallDir =
670            new File(Environment.getDataDirectory(), "app");
671    /** Directory where installed application's 32-bit native libraries are copied. */
672    private static final File sAppLib32InstallDir =
673            new File(Environment.getDataDirectory(), "app-lib");
674    /** Directory where code and non-resource assets of forward-locked applications are stored */
675    private static final File sDrmAppPrivateInstallDir =
676            new File(Environment.getDataDirectory(), "app-private");
677
678    // ----------------------------------------------------------------
679
680    // Lock for state used when installing and doing other long running
681    // operations.  Methods that must be called with this lock held have
682    // the suffix "LI".
683    final Object mInstallLock = new Object();
684
685    // ----------------------------------------------------------------
686
687    // Keys are String (package name), values are Package.  This also serves
688    // as the lock for the global state.  Methods that must be called with
689    // this lock held have the prefix "LP".
690    @GuardedBy("mPackages")
691    final ArrayMap<String, PackageParser.Package> mPackages =
692            new ArrayMap<String, PackageParser.Package>();
693
694    final ArrayMap<String, Set<String>> mKnownCodebase =
695            new ArrayMap<String, Set<String>>();
696
697    // Keys are isolated uids and values are the uid of the application
698    // that created the isolated proccess.
699    @GuardedBy("mPackages")
700    final SparseIntArray mIsolatedOwners = new SparseIntArray();
701
702    /**
703     * Tracks new system packages [received in an OTA] that we expect to
704     * find updated user-installed versions. Keys are package name, values
705     * are package location.
706     */
707    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
708    /**
709     * Tracks high priority intent filters for protected actions. During boot, certain
710     * filter actions are protected and should never be allowed to have a high priority
711     * intent filter for them. However, there is one, and only one exception -- the
712     * setup wizard. It must be able to define a high priority intent filter for these
713     * actions to ensure there are no escapes from the wizard. We need to delay processing
714     * of these during boot as we need to look at all of the system packages in order
715     * to know which component is the setup wizard.
716     */
717    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
718    /**
719     * Whether or not processing protected filters should be deferred.
720     */
721    private boolean mDeferProtectedFilters = true;
722
723    /**
724     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
725     */
726    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
727    /**
728     * Whether or not system app permissions should be promoted from install to runtime.
729     */
730    boolean mPromoteSystemApps;
731
732    @GuardedBy("mPackages")
733    final Settings mSettings;
734
735    /**
736     * Set of package names that are currently "frozen", which means active
737     * surgery is being done on the code/data for that package. The platform
738     * will refuse to launch frozen packages to avoid race conditions.
739     *
740     * @see PackageFreezer
741     */
742    @GuardedBy("mPackages")
743    final ArraySet<String> mFrozenPackages = new ArraySet<>();
744
745    final ProtectedPackages mProtectedPackages;
746
747    @GuardedBy("mLoadedVolumes")
748    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
749
750    boolean mFirstBoot;
751
752    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
753
754    @GuardedBy("mAvailableFeatures")
755    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
756
757    private final InstantAppRegistry mInstantAppRegistry;
758
759    @GuardedBy("mPackages")
760    int mChangedPackagesSequenceNumber;
761    /**
762     * List of changed [installed, removed or updated] packages.
763     * mapping from user id -> sequence number -> package name
764     */
765    @GuardedBy("mPackages")
766    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
767    /**
768     * The sequence number of the last change to a package.
769     * mapping from user id -> package name -> sequence number
770     */
771    @GuardedBy("mPackages")
772    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
773
774    @GuardedBy("mPackages")
775    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
776
777    class PackageParserCallback implements PackageParser.Callback {
778        @Override public final boolean hasFeature(String feature) {
779            return PackageManagerService.this.hasSystemFeature(feature, 0);
780        }
781
782        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
783                Collection<PackageParser.Package> allPackages, String targetPackageName) {
784            List<PackageParser.Package> overlayPackages = null;
785            for (PackageParser.Package p : allPackages) {
786                if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
787                    if (overlayPackages == null) {
788                        overlayPackages = new ArrayList<PackageParser.Package>();
789                    }
790                    overlayPackages.add(p);
791                }
792            }
793            if (overlayPackages != null) {
794                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
795                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
796                        return p1.mOverlayPriority - p2.mOverlayPriority;
797                    }
798                };
799                Collections.sort(overlayPackages, cmp);
800            }
801            return overlayPackages;
802        }
803
804        @GuardedBy("mInstallLock")
805        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
806                String targetPackageName, String targetPath) {
807            if ("android".equals(targetPackageName)) {
808                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
809                // native AssetManager.
810                return null;
811            }
812            List<PackageParser.Package> overlayPackages =
813                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
814            if (overlayPackages == null || overlayPackages.isEmpty()) {
815                return null;
816            }
817            List<String> overlayPathList = null;
818            for (PackageParser.Package overlayPackage : overlayPackages) {
819                if (targetPath == null) {
820                    if (overlayPathList == null) {
821                        overlayPathList = new ArrayList<String>();
822                    }
823                    overlayPathList.add(overlayPackage.baseCodePath);
824                    continue;
825                }
826
827                try {
828                    // Creates idmaps for system to parse correctly the Android manifest of the
829                    // target package.
830                    //
831                    // OverlayManagerService will update each of them with a correct gid from its
832                    // target package app id.
833                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
834                            UserHandle.getSharedAppGid(
835                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
836                    if (overlayPathList == null) {
837                        overlayPathList = new ArrayList<String>();
838                    }
839                    overlayPathList.add(overlayPackage.baseCodePath);
840                } catch (InstallerException e) {
841                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
842                            overlayPackage.baseCodePath);
843                }
844            }
845            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
846        }
847
848        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
849            synchronized (mPackages) {
850                return getStaticOverlayPathsLocked(
851                        mPackages.values(), targetPackageName, targetPath);
852            }
853        }
854
855        @Override public final String[] getOverlayApks(String targetPackageName) {
856            return getStaticOverlayPaths(targetPackageName, null);
857        }
858
859        @Override public final String[] getOverlayPaths(String targetPackageName,
860                String targetPath) {
861            return getStaticOverlayPaths(targetPackageName, targetPath);
862        }
863    }
864
865    class ParallelPackageParserCallback extends PackageParserCallback {
866        List<PackageParser.Package> mOverlayPackages = null;
867
868        void findStaticOverlayPackages() {
869            synchronized (mPackages) {
870                for (PackageParser.Package p : mPackages.values()) {
871                    if (p.mOverlayIsStatic) {
872                        if (mOverlayPackages == null) {
873                            mOverlayPackages = new ArrayList<PackageParser.Package>();
874                        }
875                        mOverlayPackages.add(p);
876                    }
877                }
878            }
879        }
880
881        @Override
882        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
883            // We can trust mOverlayPackages without holding mPackages because package uninstall
884            // can't happen while running parallel parsing.
885            // Moreover holding mPackages on each parsing thread causes dead-lock.
886            return mOverlayPackages == null ? null :
887                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
888        }
889    }
890
891    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
892    final ParallelPackageParserCallback mParallelPackageParserCallback =
893            new ParallelPackageParserCallback();
894
895    public static final class SharedLibraryEntry {
896        public final @Nullable String path;
897        public final @Nullable String apk;
898        public final @NonNull SharedLibraryInfo info;
899
900        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
901                String declaringPackageName, long declaringPackageVersionCode) {
902            path = _path;
903            apk = _apk;
904            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
905                    declaringPackageName, declaringPackageVersionCode), null);
906        }
907    }
908
909    // Currently known shared libraries.
910    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
911    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
912            new ArrayMap<>();
913
914    // All available activities, for your resolving pleasure.
915    final ActivityIntentResolver mActivities =
916            new ActivityIntentResolver();
917
918    // All available receivers, for your resolving pleasure.
919    final ActivityIntentResolver mReceivers =
920            new ActivityIntentResolver();
921
922    // All available services, for your resolving pleasure.
923    final ServiceIntentResolver mServices = new ServiceIntentResolver();
924
925    // All available providers, for your resolving pleasure.
926    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
927
928    // Mapping from provider base names (first directory in content URI codePath)
929    // to the provider information.
930    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
931            new ArrayMap<String, PackageParser.Provider>();
932
933    // Mapping from instrumentation class names to info about them.
934    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
935            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
936
937    // Packages whose data we have transfered into another package, thus
938    // should no longer exist.
939    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
940
941    // Broadcast actions that are only available to the system.
942    @GuardedBy("mProtectedBroadcasts")
943    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
944
945    /** List of packages waiting for verification. */
946    final SparseArray<PackageVerificationState> mPendingVerification
947            = new SparseArray<PackageVerificationState>();
948
949    final PackageInstallerService mInstallerService;
950
951    final ArtManagerService mArtManagerService;
952
953    private final PackageDexOptimizer mPackageDexOptimizer;
954    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
955    // is used by other apps).
956    private final DexManager mDexManager;
957
958    private AtomicInteger mNextMoveId = new AtomicInteger();
959    private final MoveCallbacks mMoveCallbacks;
960
961    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
962
963    // Cache of users who need badging.
964    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
965
966    /** Token for keys in mPendingVerification. */
967    private int mPendingVerificationToken = 0;
968
969    volatile boolean mSystemReady;
970    volatile boolean mSafeMode;
971    volatile boolean mHasSystemUidErrors;
972    private volatile boolean mWebInstantAppsDisabled;
973
974    ApplicationInfo mAndroidApplication;
975    final ActivityInfo mResolveActivity = new ActivityInfo();
976    final ResolveInfo mResolveInfo = new ResolveInfo();
977    ComponentName mResolveComponentName;
978    PackageParser.Package mPlatformPackage;
979    ComponentName mCustomResolverComponentName;
980
981    boolean mResolverReplaced = false;
982
983    private final @Nullable ComponentName mIntentFilterVerifierComponent;
984    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
985
986    private int mIntentFilterVerificationToken = 0;
987
988    /** The service connection to the ephemeral resolver */
989    final InstantAppResolverConnection mInstantAppResolverConnection;
990    /** Component used to show resolver settings for Instant Apps */
991    final ComponentName mInstantAppResolverSettingsComponent;
992
993    /** Activity used to install instant applications */
994    ActivityInfo mInstantAppInstallerActivity;
995    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
996
997    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
998            = new SparseArray<IntentFilterVerificationState>();
999
1000    // TODO remove this and go through mPermissonManager directly
1001    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1002    private final PermissionManagerInternal mPermissionManager;
1003
1004    // List of packages names to keep cached, even if they are uninstalled for all users
1005    private List<String> mKeepUninstalledPackages;
1006
1007    private UserManagerInternal mUserManagerInternal;
1008    private ActivityManagerInternal mActivityManagerInternal;
1009
1010    private DeviceIdleController.LocalService mDeviceIdleController;
1011
1012    private File mCacheDir;
1013
1014    private Future<?> mPrepareAppDataFuture;
1015
1016    private static class IFVerificationParams {
1017        PackageParser.Package pkg;
1018        boolean replacing;
1019        int userId;
1020        int verifierUid;
1021
1022        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1023                int _userId, int _verifierUid) {
1024            pkg = _pkg;
1025            replacing = _replacing;
1026            userId = _userId;
1027            replacing = _replacing;
1028            verifierUid = _verifierUid;
1029        }
1030    }
1031
1032    private interface IntentFilterVerifier<T extends IntentFilter> {
1033        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1034                                               T filter, String packageName);
1035        void startVerifications(int userId);
1036        void receiveVerificationResponse(int verificationId);
1037    }
1038
1039    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1040        private Context mContext;
1041        private ComponentName mIntentFilterVerifierComponent;
1042        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1043
1044        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1045            mContext = context;
1046            mIntentFilterVerifierComponent = verifierComponent;
1047        }
1048
1049        private String getDefaultScheme() {
1050            return IntentFilter.SCHEME_HTTPS;
1051        }
1052
1053        @Override
1054        public void startVerifications(int userId) {
1055            // Launch verifications requests
1056            int count = mCurrentIntentFilterVerifications.size();
1057            for (int n=0; n<count; n++) {
1058                int verificationId = mCurrentIntentFilterVerifications.get(n);
1059                final IntentFilterVerificationState ivs =
1060                        mIntentFilterVerificationStates.get(verificationId);
1061
1062                String packageName = ivs.getPackageName();
1063
1064                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1065                final int filterCount = filters.size();
1066                ArraySet<String> domainsSet = new ArraySet<>();
1067                for (int m=0; m<filterCount; m++) {
1068                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1069                    domainsSet.addAll(filter.getHostsList());
1070                }
1071                synchronized (mPackages) {
1072                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1073                            packageName, domainsSet) != null) {
1074                        scheduleWriteSettingsLocked();
1075                    }
1076                }
1077                sendVerificationRequest(verificationId, ivs);
1078            }
1079            mCurrentIntentFilterVerifications.clear();
1080        }
1081
1082        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1083            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1084            verificationIntent.putExtra(
1085                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1086                    verificationId);
1087            verificationIntent.putExtra(
1088                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1089                    getDefaultScheme());
1090            verificationIntent.putExtra(
1091                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1092                    ivs.getHostsString());
1093            verificationIntent.putExtra(
1094                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1095                    ivs.getPackageName());
1096            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1097            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1098
1099            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1100            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1101                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1102                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1103
1104            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1105            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1106                    "Sending IntentFilter verification broadcast");
1107        }
1108
1109        public void receiveVerificationResponse(int verificationId) {
1110            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1111
1112            final boolean verified = ivs.isVerified();
1113
1114            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1115            final int count = filters.size();
1116            if (DEBUG_DOMAIN_VERIFICATION) {
1117                Slog.i(TAG, "Received verification response " + verificationId
1118                        + " for " + count + " filters, verified=" + verified);
1119            }
1120            for (int n=0; n<count; n++) {
1121                PackageParser.ActivityIntentInfo filter = filters.get(n);
1122                filter.setVerified(verified);
1123
1124                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1125                        + " verified with result:" + verified + " and hosts:"
1126                        + ivs.getHostsString());
1127            }
1128
1129            mIntentFilterVerificationStates.remove(verificationId);
1130
1131            final String packageName = ivs.getPackageName();
1132            IntentFilterVerificationInfo ivi = null;
1133
1134            synchronized (mPackages) {
1135                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1136            }
1137            if (ivi == null) {
1138                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1139                        + verificationId + " packageName:" + packageName);
1140                return;
1141            }
1142            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1143                    "Updating IntentFilterVerificationInfo for package " + packageName
1144                            +" verificationId:" + verificationId);
1145
1146            synchronized (mPackages) {
1147                if (verified) {
1148                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1149                } else {
1150                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1151                }
1152                scheduleWriteSettingsLocked();
1153
1154                final int userId = ivs.getUserId();
1155                if (userId != UserHandle.USER_ALL) {
1156                    final int userStatus =
1157                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1158
1159                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1160                    boolean needUpdate = false;
1161
1162                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1163                    // already been set by the User thru the Disambiguation dialog
1164                    switch (userStatus) {
1165                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1166                            if (verified) {
1167                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1168                            } else {
1169                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1170                            }
1171                            needUpdate = true;
1172                            break;
1173
1174                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1175                            if (verified) {
1176                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1177                                needUpdate = true;
1178                            }
1179                            break;
1180
1181                        default:
1182                            // Nothing to do
1183                    }
1184
1185                    if (needUpdate) {
1186                        mSettings.updateIntentFilterVerificationStatusLPw(
1187                                packageName, updatedStatus, userId);
1188                        scheduleWritePackageRestrictionsLocked(userId);
1189                    }
1190                }
1191            }
1192        }
1193
1194        @Override
1195        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1196                    ActivityIntentInfo filter, String packageName) {
1197            if (!hasValidDomains(filter)) {
1198                return false;
1199            }
1200            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1201            if (ivs == null) {
1202                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1203                        packageName);
1204            }
1205            if (DEBUG_DOMAIN_VERIFICATION) {
1206                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1207            }
1208            ivs.addFilter(filter);
1209            return true;
1210        }
1211
1212        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1213                int userId, int verificationId, String packageName) {
1214            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1215                    verifierUid, userId, packageName);
1216            ivs.setPendingState();
1217            synchronized (mPackages) {
1218                mIntentFilterVerificationStates.append(verificationId, ivs);
1219                mCurrentIntentFilterVerifications.add(verificationId);
1220            }
1221            return ivs;
1222        }
1223    }
1224
1225    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1226        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1227                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1228                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1229    }
1230
1231    // Set of pending broadcasts for aggregating enable/disable of components.
1232    static class PendingPackageBroadcasts {
1233        // for each user id, a map of <package name -> components within that package>
1234        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1235
1236        public PendingPackageBroadcasts() {
1237            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1238        }
1239
1240        public ArrayList<String> get(int userId, String packageName) {
1241            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1242            return packages.get(packageName);
1243        }
1244
1245        public void put(int userId, String packageName, ArrayList<String> components) {
1246            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1247            packages.put(packageName, components);
1248        }
1249
1250        public void remove(int userId, String packageName) {
1251            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1252            if (packages != null) {
1253                packages.remove(packageName);
1254            }
1255        }
1256
1257        public void remove(int userId) {
1258            mUidMap.remove(userId);
1259        }
1260
1261        public int userIdCount() {
1262            return mUidMap.size();
1263        }
1264
1265        public int userIdAt(int n) {
1266            return mUidMap.keyAt(n);
1267        }
1268
1269        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1270            return mUidMap.get(userId);
1271        }
1272
1273        public int size() {
1274            // total number of pending broadcast entries across all userIds
1275            int num = 0;
1276            for (int i = 0; i< mUidMap.size(); i++) {
1277                num += mUidMap.valueAt(i).size();
1278            }
1279            return num;
1280        }
1281
1282        public void clear() {
1283            mUidMap.clear();
1284        }
1285
1286        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1287            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1288            if (map == null) {
1289                map = new ArrayMap<String, ArrayList<String>>();
1290                mUidMap.put(userId, map);
1291            }
1292            return map;
1293        }
1294    }
1295    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1296
1297    // Service Connection to remote media container service to copy
1298    // package uri's from external media onto secure containers
1299    // or internal storage.
1300    private IMediaContainerService mContainerService = null;
1301
1302    static final int SEND_PENDING_BROADCAST = 1;
1303    static final int MCS_BOUND = 3;
1304    static final int END_COPY = 4;
1305    static final int INIT_COPY = 5;
1306    static final int MCS_UNBIND = 6;
1307    static final int START_CLEANING_PACKAGE = 7;
1308    static final int FIND_INSTALL_LOC = 8;
1309    static final int POST_INSTALL = 9;
1310    static final int MCS_RECONNECT = 10;
1311    static final int MCS_GIVE_UP = 11;
1312    static final int WRITE_SETTINGS = 13;
1313    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1314    static final int PACKAGE_VERIFIED = 15;
1315    static final int CHECK_PENDING_VERIFICATION = 16;
1316    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1317    static final int INTENT_FILTER_VERIFIED = 18;
1318    static final int WRITE_PACKAGE_LIST = 19;
1319    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1320
1321    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1322
1323    // Delay time in millisecs
1324    static final int BROADCAST_DELAY = 10 * 1000;
1325
1326    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1327            2 * 60 * 60 * 1000L; /* two hours */
1328
1329    static UserManagerService sUserManager;
1330
1331    // Stores a list of users whose package restrictions file needs to be updated
1332    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1333
1334    final private DefaultContainerConnection mDefContainerConn =
1335            new DefaultContainerConnection();
1336    class DefaultContainerConnection implements ServiceConnection {
1337        public void onServiceConnected(ComponentName name, IBinder service) {
1338            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1339            final IMediaContainerService imcs = IMediaContainerService.Stub
1340                    .asInterface(Binder.allowBlocking(service));
1341            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1342        }
1343
1344        public void onServiceDisconnected(ComponentName name) {
1345            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1346        }
1347    }
1348
1349    // Recordkeeping of restore-after-install operations that are currently in flight
1350    // between the Package Manager and the Backup Manager
1351    static class PostInstallData {
1352        public InstallArgs args;
1353        public PackageInstalledInfo res;
1354
1355        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1356            args = _a;
1357            res = _r;
1358        }
1359    }
1360
1361    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1362    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1363
1364    // XML tags for backup/restore of various bits of state
1365    private static final String TAG_PREFERRED_BACKUP = "pa";
1366    private static final String TAG_DEFAULT_APPS = "da";
1367    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1368
1369    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1370    private static final String TAG_ALL_GRANTS = "rt-grants";
1371    private static final String TAG_GRANT = "grant";
1372    private static final String ATTR_PACKAGE_NAME = "pkg";
1373
1374    private static final String TAG_PERMISSION = "perm";
1375    private static final String ATTR_PERMISSION_NAME = "name";
1376    private static final String ATTR_IS_GRANTED = "g";
1377    private static final String ATTR_USER_SET = "set";
1378    private static final String ATTR_USER_FIXED = "fixed";
1379    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1380
1381    // System/policy permission grants are not backed up
1382    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1383            FLAG_PERMISSION_POLICY_FIXED
1384            | FLAG_PERMISSION_SYSTEM_FIXED
1385            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1386
1387    // And we back up these user-adjusted states
1388    private static final int USER_RUNTIME_GRANT_MASK =
1389            FLAG_PERMISSION_USER_SET
1390            | FLAG_PERMISSION_USER_FIXED
1391            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1392
1393    final @Nullable String mRequiredVerifierPackage;
1394    final @NonNull String mRequiredInstallerPackage;
1395    final @NonNull String mRequiredUninstallerPackage;
1396    final @Nullable String mSetupWizardPackage;
1397    final @Nullable String mStorageManagerPackage;
1398    final @Nullable String mSystemTextClassifierPackage;
1399    final @NonNull String mServicesSystemSharedLibraryPackageName;
1400    final @NonNull String mSharedSystemSharedLibraryPackageName;
1401
1402    private final PackageUsage mPackageUsage = new PackageUsage();
1403    private final CompilerStats mCompilerStats = new CompilerStats();
1404
1405    class PackageHandler extends Handler {
1406        private boolean mBound = false;
1407        final ArrayList<HandlerParams> mPendingInstalls =
1408            new ArrayList<HandlerParams>();
1409
1410        private boolean connectToService() {
1411            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1412                    " DefaultContainerService");
1413            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1414            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1415            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1416                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1417                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1418                mBound = true;
1419                return true;
1420            }
1421            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1422            return false;
1423        }
1424
1425        private void disconnectService() {
1426            mContainerService = null;
1427            mBound = false;
1428            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1429            mContext.unbindService(mDefContainerConn);
1430            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1431        }
1432
1433        PackageHandler(Looper looper) {
1434            super(looper);
1435        }
1436
1437        public void handleMessage(Message msg) {
1438            try {
1439                doHandleMessage(msg);
1440            } finally {
1441                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1442            }
1443        }
1444
1445        void doHandleMessage(Message msg) {
1446            switch (msg.what) {
1447                case INIT_COPY: {
1448                    HandlerParams params = (HandlerParams) msg.obj;
1449                    int idx = mPendingInstalls.size();
1450                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1451                    // If a bind was already initiated we dont really
1452                    // need to do anything. The pending install
1453                    // will be processed later on.
1454                    if (!mBound) {
1455                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1456                                System.identityHashCode(mHandler));
1457                        // If this is the only one pending we might
1458                        // have to bind to the service again.
1459                        if (!connectToService()) {
1460                            Slog.e(TAG, "Failed to bind to media container service");
1461                            params.serviceError();
1462                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1463                                    System.identityHashCode(mHandler));
1464                            if (params.traceMethod != null) {
1465                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1466                                        params.traceCookie);
1467                            }
1468                            return;
1469                        } else {
1470                            // Once we bind to the service, the first
1471                            // pending request will be processed.
1472                            mPendingInstalls.add(idx, params);
1473                        }
1474                    } else {
1475                        mPendingInstalls.add(idx, params);
1476                        // Already bound to the service. Just make
1477                        // sure we trigger off processing the first request.
1478                        if (idx == 0) {
1479                            mHandler.sendEmptyMessage(MCS_BOUND);
1480                        }
1481                    }
1482                    break;
1483                }
1484                case MCS_BOUND: {
1485                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1486                    if (msg.obj != null) {
1487                        mContainerService = (IMediaContainerService) msg.obj;
1488                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1489                                System.identityHashCode(mHandler));
1490                    }
1491                    if (mContainerService == null) {
1492                        if (!mBound) {
1493                            // Something seriously wrong since we are not bound and we are not
1494                            // waiting for connection. Bail out.
1495                            Slog.e(TAG, "Cannot bind to media container service");
1496                            for (HandlerParams params : mPendingInstalls) {
1497                                // Indicate service bind error
1498                                params.serviceError();
1499                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1500                                        System.identityHashCode(params));
1501                                if (params.traceMethod != null) {
1502                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1503                                            params.traceMethod, params.traceCookie);
1504                                }
1505                                return;
1506                            }
1507                            mPendingInstalls.clear();
1508                        } else {
1509                            Slog.w(TAG, "Waiting to connect to media container service");
1510                        }
1511                    } else if (mPendingInstalls.size() > 0) {
1512                        HandlerParams params = mPendingInstalls.get(0);
1513                        if (params != null) {
1514                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1515                                    System.identityHashCode(params));
1516                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1517                            if (params.startCopy()) {
1518                                // We are done...  look for more work or to
1519                                // go idle.
1520                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1521                                        "Checking for more work or unbind...");
1522                                // Delete pending install
1523                                if (mPendingInstalls.size() > 0) {
1524                                    mPendingInstalls.remove(0);
1525                                }
1526                                if (mPendingInstalls.size() == 0) {
1527                                    if (mBound) {
1528                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1529                                                "Posting delayed MCS_UNBIND");
1530                                        removeMessages(MCS_UNBIND);
1531                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1532                                        // Unbind after a little delay, to avoid
1533                                        // continual thrashing.
1534                                        sendMessageDelayed(ubmsg, 10000);
1535                                    }
1536                                } else {
1537                                    // There are more pending requests in queue.
1538                                    // Just post MCS_BOUND message to trigger processing
1539                                    // of next pending install.
1540                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1541                                            "Posting MCS_BOUND for next work");
1542                                    mHandler.sendEmptyMessage(MCS_BOUND);
1543                                }
1544                            }
1545                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1546                        }
1547                    } else {
1548                        // Should never happen ideally.
1549                        Slog.w(TAG, "Empty queue");
1550                    }
1551                    break;
1552                }
1553                case MCS_RECONNECT: {
1554                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1555                    if (mPendingInstalls.size() > 0) {
1556                        if (mBound) {
1557                            disconnectService();
1558                        }
1559                        if (!connectToService()) {
1560                            Slog.e(TAG, "Failed to bind to media container service");
1561                            for (HandlerParams params : mPendingInstalls) {
1562                                // Indicate service bind error
1563                                params.serviceError();
1564                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1565                                        System.identityHashCode(params));
1566                            }
1567                            mPendingInstalls.clear();
1568                        }
1569                    }
1570                    break;
1571                }
1572                case MCS_UNBIND: {
1573                    // If there is no actual work left, then time to unbind.
1574                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1575
1576                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1577                        if (mBound) {
1578                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1579
1580                            disconnectService();
1581                        }
1582                    } else if (mPendingInstalls.size() > 0) {
1583                        // There are more pending requests in queue.
1584                        // Just post MCS_BOUND message to trigger processing
1585                        // of next pending install.
1586                        mHandler.sendEmptyMessage(MCS_BOUND);
1587                    }
1588
1589                    break;
1590                }
1591                case MCS_GIVE_UP: {
1592                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1593                    HandlerParams params = mPendingInstalls.remove(0);
1594                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1595                            System.identityHashCode(params));
1596                    break;
1597                }
1598                case SEND_PENDING_BROADCAST: {
1599                    String packages[];
1600                    ArrayList<String> components[];
1601                    int size = 0;
1602                    int uids[];
1603                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1604                    synchronized (mPackages) {
1605                        if (mPendingBroadcasts == null) {
1606                            return;
1607                        }
1608                        size = mPendingBroadcasts.size();
1609                        if (size <= 0) {
1610                            // Nothing to be done. Just return
1611                            return;
1612                        }
1613                        packages = new String[size];
1614                        components = new ArrayList[size];
1615                        uids = new int[size];
1616                        int i = 0;  // filling out the above arrays
1617
1618                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1619                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1620                            Iterator<Map.Entry<String, ArrayList<String>>> it
1621                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1622                                            .entrySet().iterator();
1623                            while (it.hasNext() && i < size) {
1624                                Map.Entry<String, ArrayList<String>> ent = it.next();
1625                                packages[i] = ent.getKey();
1626                                components[i] = ent.getValue();
1627                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1628                                uids[i] = (ps != null)
1629                                        ? UserHandle.getUid(packageUserId, ps.appId)
1630                                        : -1;
1631                                i++;
1632                            }
1633                        }
1634                        size = i;
1635                        mPendingBroadcasts.clear();
1636                    }
1637                    // Send broadcasts
1638                    for (int i = 0; i < size; i++) {
1639                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1640                    }
1641                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1642                    break;
1643                }
1644                case START_CLEANING_PACKAGE: {
1645                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1646                    final String packageName = (String)msg.obj;
1647                    final int userId = msg.arg1;
1648                    final boolean andCode = msg.arg2 != 0;
1649                    synchronized (mPackages) {
1650                        if (userId == UserHandle.USER_ALL) {
1651                            int[] users = sUserManager.getUserIds();
1652                            for (int user : users) {
1653                                mSettings.addPackageToCleanLPw(
1654                                        new PackageCleanItem(user, packageName, andCode));
1655                            }
1656                        } else {
1657                            mSettings.addPackageToCleanLPw(
1658                                    new PackageCleanItem(userId, packageName, andCode));
1659                        }
1660                    }
1661                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1662                    startCleaningPackages();
1663                } break;
1664                case POST_INSTALL: {
1665                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1666
1667                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1668                    final boolean didRestore = (msg.arg2 != 0);
1669                    mRunningInstalls.delete(msg.arg1);
1670
1671                    if (data != null) {
1672                        InstallArgs args = data.args;
1673                        PackageInstalledInfo parentRes = data.res;
1674
1675                        final boolean grantPermissions = (args.installFlags
1676                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1677                        final boolean killApp = (args.installFlags
1678                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1679                        final boolean virtualPreload = ((args.installFlags
1680                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1681                        final String[] grantedPermissions = args.installGrantPermissions;
1682
1683                        // Handle the parent package
1684                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1685                                virtualPreload, grantedPermissions, didRestore,
1686                                args.installerPackageName, args.observer);
1687
1688                        // Handle the child packages
1689                        final int childCount = (parentRes.addedChildPackages != null)
1690                                ? parentRes.addedChildPackages.size() : 0;
1691                        for (int i = 0; i < childCount; i++) {
1692                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1693                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1694                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1695                                    args.installerPackageName, args.observer);
1696                        }
1697
1698                        // Log tracing if needed
1699                        if (args.traceMethod != null) {
1700                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1701                                    args.traceCookie);
1702                        }
1703                    } else {
1704                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1705                    }
1706
1707                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1708                } break;
1709                case WRITE_SETTINGS: {
1710                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1711                    synchronized (mPackages) {
1712                        removeMessages(WRITE_SETTINGS);
1713                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1714                        mSettings.writeLPr();
1715                        mDirtyUsers.clear();
1716                    }
1717                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1718                } break;
1719                case WRITE_PACKAGE_RESTRICTIONS: {
1720                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1721                    synchronized (mPackages) {
1722                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1723                        for (int userId : mDirtyUsers) {
1724                            mSettings.writePackageRestrictionsLPr(userId);
1725                        }
1726                        mDirtyUsers.clear();
1727                    }
1728                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1729                } break;
1730                case WRITE_PACKAGE_LIST: {
1731                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1732                    synchronized (mPackages) {
1733                        removeMessages(WRITE_PACKAGE_LIST);
1734                        mSettings.writePackageListLPr(msg.arg1);
1735                    }
1736                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1737                } break;
1738                case CHECK_PENDING_VERIFICATION: {
1739                    final int verificationId = msg.arg1;
1740                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1741
1742                    if ((state != null) && !state.timeoutExtended()) {
1743                        final InstallArgs args = state.getInstallArgs();
1744                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1745
1746                        Slog.i(TAG, "Verification timed out for " + originUri);
1747                        mPendingVerification.remove(verificationId);
1748
1749                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1750
1751                        final UserHandle user = args.getUser();
1752                        if (getDefaultVerificationResponse(user)
1753                                == PackageManager.VERIFICATION_ALLOW) {
1754                            Slog.i(TAG, "Continuing with installation of " + originUri);
1755                            state.setVerifierResponse(Binder.getCallingUid(),
1756                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1757                            broadcastPackageVerified(verificationId, originUri,
1758                                    PackageManager.VERIFICATION_ALLOW, user);
1759                            try {
1760                                ret = args.copyApk(mContainerService, true);
1761                            } catch (RemoteException e) {
1762                                Slog.e(TAG, "Could not contact the ContainerService");
1763                            }
1764                        } else {
1765                            broadcastPackageVerified(verificationId, originUri,
1766                                    PackageManager.VERIFICATION_REJECT, user);
1767                        }
1768
1769                        Trace.asyncTraceEnd(
1770                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1771
1772                        processPendingInstall(args, ret);
1773                        mHandler.sendEmptyMessage(MCS_UNBIND);
1774                    }
1775                    break;
1776                }
1777                case PACKAGE_VERIFIED: {
1778                    final int verificationId = msg.arg1;
1779
1780                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1781                    if (state == null) {
1782                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1783                        break;
1784                    }
1785
1786                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1787
1788                    state.setVerifierResponse(response.callerUid, response.code);
1789
1790                    if (state.isVerificationComplete()) {
1791                        mPendingVerification.remove(verificationId);
1792
1793                        final InstallArgs args = state.getInstallArgs();
1794                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1795
1796                        int ret;
1797                        if (state.isInstallAllowed()) {
1798                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1799                            broadcastPackageVerified(verificationId, originUri,
1800                                    response.code, state.getInstallArgs().getUser());
1801                            try {
1802                                ret = args.copyApk(mContainerService, true);
1803                            } catch (RemoteException e) {
1804                                Slog.e(TAG, "Could not contact the ContainerService");
1805                            }
1806                        } else {
1807                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1808                        }
1809
1810                        Trace.asyncTraceEnd(
1811                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1812
1813                        processPendingInstall(args, ret);
1814                        mHandler.sendEmptyMessage(MCS_UNBIND);
1815                    }
1816
1817                    break;
1818                }
1819                case START_INTENT_FILTER_VERIFICATIONS: {
1820                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1821                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1822                            params.replacing, params.pkg);
1823                    break;
1824                }
1825                case INTENT_FILTER_VERIFIED: {
1826                    final int verificationId = msg.arg1;
1827
1828                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1829                            verificationId);
1830                    if (state == null) {
1831                        Slog.w(TAG, "Invalid IntentFilter verification token "
1832                                + verificationId + " received");
1833                        break;
1834                    }
1835
1836                    final int userId = state.getUserId();
1837
1838                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1839                            "Processing IntentFilter verification with token:"
1840                            + verificationId + " and userId:" + userId);
1841
1842                    final IntentFilterVerificationResponse response =
1843                            (IntentFilterVerificationResponse) msg.obj;
1844
1845                    state.setVerifierResponse(response.callerUid, response.code);
1846
1847                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1848                            "IntentFilter verification with token:" + verificationId
1849                            + " and userId:" + userId
1850                            + " is settings verifier response with response code:"
1851                            + response.code);
1852
1853                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1854                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1855                                + response.getFailedDomainsString());
1856                    }
1857
1858                    if (state.isVerificationComplete()) {
1859                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1860                    } else {
1861                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1862                                "IntentFilter verification with token:" + verificationId
1863                                + " was not said to be complete");
1864                    }
1865
1866                    break;
1867                }
1868                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1869                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1870                            mInstantAppResolverConnection,
1871                            (InstantAppRequest) msg.obj,
1872                            mInstantAppInstallerActivity,
1873                            mHandler);
1874                }
1875            }
1876        }
1877    }
1878
1879    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1880        @Override
1881        public void onGidsChanged(int appId, int userId) {
1882            mHandler.post(new Runnable() {
1883                @Override
1884                public void run() {
1885                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1886                }
1887            });
1888        }
1889        @Override
1890        public void onPermissionGranted(int uid, int userId) {
1891            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1892
1893            // Not critical; if this is lost, the application has to request again.
1894            synchronized (mPackages) {
1895                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1896            }
1897        }
1898        @Override
1899        public void onInstallPermissionGranted() {
1900            synchronized (mPackages) {
1901                scheduleWriteSettingsLocked();
1902            }
1903        }
1904        @Override
1905        public void onPermissionRevoked(int uid, int userId) {
1906            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1907
1908            synchronized (mPackages) {
1909                // Critical; after this call the application should never have the permission
1910                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1911            }
1912
1913            final int appId = UserHandle.getAppId(uid);
1914            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1915        }
1916        @Override
1917        public void onInstallPermissionRevoked() {
1918            synchronized (mPackages) {
1919                scheduleWriteSettingsLocked();
1920            }
1921        }
1922        @Override
1923        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1924            synchronized (mPackages) {
1925                for (int userId : updatedUserIds) {
1926                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1927                }
1928            }
1929        }
1930        @Override
1931        public void onInstallPermissionUpdated() {
1932            synchronized (mPackages) {
1933                scheduleWriteSettingsLocked();
1934            }
1935        }
1936        @Override
1937        public void onPermissionRemoved() {
1938            synchronized (mPackages) {
1939                mSettings.writeLPr();
1940            }
1941        }
1942    };
1943
1944    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1945            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1946            boolean launchedForRestore, String installerPackage,
1947            IPackageInstallObserver2 installObserver) {
1948        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1949            // Send the removed broadcasts
1950            if (res.removedInfo != null) {
1951                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1952            }
1953
1954            // Now that we successfully installed the package, grant runtime
1955            // permissions if requested before broadcasting the install. Also
1956            // for legacy apps in permission review mode we clear the permission
1957            // review flag which is used to emulate runtime permissions for
1958            // legacy apps.
1959            if (grantPermissions) {
1960                final int callingUid = Binder.getCallingUid();
1961                mPermissionManager.grantRequestedRuntimePermissions(
1962                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1963                        mPermissionCallback);
1964            }
1965
1966            final boolean update = res.removedInfo != null
1967                    && res.removedInfo.removedPackage != null;
1968            final String installerPackageName =
1969                    res.installerPackageName != null
1970                            ? res.installerPackageName
1971                            : res.removedInfo != null
1972                                    ? res.removedInfo.installerPackageName
1973                                    : null;
1974
1975            // If this is the first time we have child packages for a disabled privileged
1976            // app that had no children, we grant requested runtime permissions to the new
1977            // children if the parent on the system image had them already granted.
1978            if (res.pkg.parentPackage != null) {
1979                final int callingUid = Binder.getCallingUid();
1980                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1981                        res.pkg, callingUid, mPermissionCallback);
1982            }
1983
1984            synchronized (mPackages) {
1985                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1986            }
1987
1988            final String packageName = res.pkg.applicationInfo.packageName;
1989
1990            // Determine the set of users who are adding this package for
1991            // the first time vs. those who are seeing an update.
1992            int[] firstUserIds = EMPTY_INT_ARRAY;
1993            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1994            int[] updateUserIds = EMPTY_INT_ARRAY;
1995            int[] instantUserIds = EMPTY_INT_ARRAY;
1996            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1997            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1998            for (int newUser : res.newUsers) {
1999                final boolean isInstantApp = ps.getInstantApp(newUser);
2000                if (allNewUsers) {
2001                    if (isInstantApp) {
2002                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2003                    } else {
2004                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2005                    }
2006                    continue;
2007                }
2008                boolean isNew = true;
2009                for (int origUser : res.origUsers) {
2010                    if (origUser == newUser) {
2011                        isNew = false;
2012                        break;
2013                    }
2014                }
2015                if (isNew) {
2016                    if (isInstantApp) {
2017                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2018                    } else {
2019                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2020                    }
2021                } else {
2022                    if (isInstantApp) {
2023                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2024                    } else {
2025                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2026                    }
2027                }
2028            }
2029
2030            // Send installed broadcasts if the package is not a static shared lib.
2031            if (res.pkg.staticSharedLibName == null) {
2032                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2033
2034                // Send added for users that see the package for the first time
2035                // sendPackageAddedForNewUsers also deals with system apps
2036                int appId = UserHandle.getAppId(res.uid);
2037                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2038                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2039                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2040
2041                // Send added for users that don't see the package for the first time
2042                Bundle extras = new Bundle(1);
2043                extras.putInt(Intent.EXTRA_UID, res.uid);
2044                if (update) {
2045                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2046                }
2047                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2048                        extras, 0 /*flags*/,
2049                        null /*targetPackage*/, null /*finishedReceiver*/,
2050                        updateUserIds, instantUserIds);
2051                if (installerPackageName != null) {
2052                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2053                            extras, 0 /*flags*/,
2054                            installerPackageName, null /*finishedReceiver*/,
2055                            updateUserIds, instantUserIds);
2056                }
2057
2058                // Send replaced for users that don't see the package for the first time
2059                if (update) {
2060                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2061                            packageName, extras, 0 /*flags*/,
2062                            null /*targetPackage*/, null /*finishedReceiver*/,
2063                            updateUserIds, instantUserIds);
2064                    if (installerPackageName != null) {
2065                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2066                                extras, 0 /*flags*/,
2067                                installerPackageName, null /*finishedReceiver*/,
2068                                updateUserIds, instantUserIds);
2069                    }
2070                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2071                            null /*package*/, null /*extras*/, 0 /*flags*/,
2072                            packageName /*targetPackage*/,
2073                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2074                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2075                    // First-install and we did a restore, so we're responsible for the
2076                    // first-launch broadcast.
2077                    if (DEBUG_BACKUP) {
2078                        Slog.i(TAG, "Post-restore of " + packageName
2079                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2080                    }
2081                    sendFirstLaunchBroadcast(packageName, installerPackage,
2082                            firstUserIds, firstInstantUserIds);
2083                }
2084
2085                // Send broadcast package appeared if forward locked/external for all users
2086                // treat asec-hosted packages like removable media on upgrade
2087                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2088                    if (DEBUG_INSTALL) {
2089                        Slog.i(TAG, "upgrading pkg " + res.pkg
2090                                + " is ASEC-hosted -> AVAILABLE");
2091                    }
2092                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2093                    ArrayList<String> pkgList = new ArrayList<>(1);
2094                    pkgList.add(packageName);
2095                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2096                }
2097            }
2098
2099            // Work that needs to happen on first install within each user
2100            if (firstUserIds != null && firstUserIds.length > 0) {
2101                synchronized (mPackages) {
2102                    for (int userId : firstUserIds) {
2103                        // If this app is a browser and it's newly-installed for some
2104                        // users, clear any default-browser state in those users. The
2105                        // app's nature doesn't depend on the user, so we can just check
2106                        // its browser nature in any user and generalize.
2107                        if (packageIsBrowser(packageName, userId)) {
2108                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2109                        }
2110
2111                        // We may also need to apply pending (restored) runtime
2112                        // permission grants within these users.
2113                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2114                    }
2115                }
2116            }
2117
2118            if (allNewUsers && !update) {
2119                notifyPackageAdded(packageName);
2120            }
2121
2122            // Log current value of "unknown sources" setting
2123            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2124                    getUnknownSourcesSettings());
2125
2126            // Remove the replaced package's older resources safely now
2127            // We delete after a gc for applications  on sdcard.
2128            if (res.removedInfo != null && res.removedInfo.args != null) {
2129                Runtime.getRuntime().gc();
2130                synchronized (mInstallLock) {
2131                    res.removedInfo.args.doPostDeleteLI(true);
2132                }
2133            } else {
2134                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2135                // and not block here.
2136                VMRuntime.getRuntime().requestConcurrentGC();
2137            }
2138
2139            // Notify DexManager that the package was installed for new users.
2140            // The updated users should already be indexed and the package code paths
2141            // should not change.
2142            // Don't notify the manager for ephemeral apps as they are not expected to
2143            // survive long enough to benefit of background optimizations.
2144            for (int userId : firstUserIds) {
2145                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2146                // There's a race currently where some install events may interleave with an uninstall.
2147                // This can lead to package info being null (b/36642664).
2148                if (info != null) {
2149                    mDexManager.notifyPackageInstalled(info, userId);
2150                }
2151            }
2152        }
2153
2154        // If someone is watching installs - notify them
2155        if (installObserver != null) {
2156            try {
2157                Bundle extras = extrasForInstallResult(res);
2158                installObserver.onPackageInstalled(res.name, res.returnCode,
2159                        res.returnMsg, extras);
2160            } catch (RemoteException e) {
2161                Slog.i(TAG, "Observer no longer exists.");
2162            }
2163        }
2164    }
2165
2166    private StorageEventListener mStorageListener = new StorageEventListener() {
2167        @Override
2168        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2169            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2170                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2171                    final String volumeUuid = vol.getFsUuid();
2172
2173                    // Clean up any users or apps that were removed or recreated
2174                    // while this volume was missing
2175                    sUserManager.reconcileUsers(volumeUuid);
2176                    reconcileApps(volumeUuid);
2177
2178                    // Clean up any install sessions that expired or were
2179                    // cancelled while this volume was missing
2180                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2181
2182                    loadPrivatePackages(vol);
2183
2184                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2185                    unloadPrivatePackages(vol);
2186                }
2187            }
2188        }
2189
2190        @Override
2191        public void onVolumeForgotten(String fsUuid) {
2192            if (TextUtils.isEmpty(fsUuid)) {
2193                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2194                return;
2195            }
2196
2197            // Remove any apps installed on the forgotten volume
2198            synchronized (mPackages) {
2199                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2200                for (PackageSetting ps : packages) {
2201                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2202                    deletePackageVersioned(new VersionedPackage(ps.name,
2203                            PackageManager.VERSION_CODE_HIGHEST),
2204                            new LegacyPackageDeleteObserver(null).getBinder(),
2205                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2206                    // Try very hard to release any references to this package
2207                    // so we don't risk the system server being killed due to
2208                    // open FDs
2209                    AttributeCache.instance().removePackage(ps.name);
2210                }
2211
2212                mSettings.onVolumeForgotten(fsUuid);
2213                mSettings.writeLPr();
2214            }
2215        }
2216    };
2217
2218    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2219        Bundle extras = null;
2220        switch (res.returnCode) {
2221            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2222                extras = new Bundle();
2223                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2224                        res.origPermission);
2225                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2226                        res.origPackage);
2227                break;
2228            }
2229            case PackageManager.INSTALL_SUCCEEDED: {
2230                extras = new Bundle();
2231                extras.putBoolean(Intent.EXTRA_REPLACING,
2232                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2233                break;
2234            }
2235        }
2236        return extras;
2237    }
2238
2239    void scheduleWriteSettingsLocked() {
2240        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2241            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2242        }
2243    }
2244
2245    void scheduleWritePackageListLocked(int userId) {
2246        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2247            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2248            msg.arg1 = userId;
2249            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2250        }
2251    }
2252
2253    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2254        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2255        scheduleWritePackageRestrictionsLocked(userId);
2256    }
2257
2258    void scheduleWritePackageRestrictionsLocked(int userId) {
2259        final int[] userIds = (userId == UserHandle.USER_ALL)
2260                ? sUserManager.getUserIds() : new int[]{userId};
2261        for (int nextUserId : userIds) {
2262            if (!sUserManager.exists(nextUserId)) return;
2263            mDirtyUsers.add(nextUserId);
2264            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2265                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2266            }
2267        }
2268    }
2269
2270    public static PackageManagerService main(Context context, Installer installer,
2271            boolean factoryTest, boolean onlyCore) {
2272        // Self-check for initial settings.
2273        PackageManagerServiceCompilerMapping.checkProperties();
2274
2275        PackageManagerService m = new PackageManagerService(context, installer,
2276                factoryTest, onlyCore);
2277        m.enableSystemUserPackages();
2278        ServiceManager.addService("package", m);
2279        final PackageManagerNative pmn = m.new PackageManagerNative();
2280        ServiceManager.addService("package_native", pmn);
2281        return m;
2282    }
2283
2284    private void enableSystemUserPackages() {
2285        if (!UserManager.isSplitSystemUser()) {
2286            return;
2287        }
2288        // For system user, enable apps based on the following conditions:
2289        // - app is whitelisted or belong to one of these groups:
2290        //   -- system app which has no launcher icons
2291        //   -- system app which has INTERACT_ACROSS_USERS permission
2292        //   -- system IME app
2293        // - app is not in the blacklist
2294        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2295        Set<String> enableApps = new ArraySet<>();
2296        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2297                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2298                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2299        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2300        enableApps.addAll(wlApps);
2301        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2302                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2303        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2304        enableApps.removeAll(blApps);
2305        Log.i(TAG, "Applications installed for system user: " + enableApps);
2306        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2307                UserHandle.SYSTEM);
2308        final int allAppsSize = allAps.size();
2309        synchronized (mPackages) {
2310            for (int i = 0; i < allAppsSize; i++) {
2311                String pName = allAps.get(i);
2312                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2313                // Should not happen, but we shouldn't be failing if it does
2314                if (pkgSetting == null) {
2315                    continue;
2316                }
2317                boolean install = enableApps.contains(pName);
2318                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2319                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2320                            + " for system user");
2321                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2322                }
2323            }
2324            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2325        }
2326    }
2327
2328    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2329        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2330                Context.DISPLAY_SERVICE);
2331        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2332    }
2333
2334    /**
2335     * Requests that files preopted on a secondary system partition be copied to the data partition
2336     * if possible.  Note that the actual copying of the files is accomplished by init for security
2337     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2338     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2339     */
2340    private static void requestCopyPreoptedFiles() {
2341        final int WAIT_TIME_MS = 100;
2342        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2343        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2344            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2345            // We will wait for up to 100 seconds.
2346            final long timeStart = SystemClock.uptimeMillis();
2347            final long timeEnd = timeStart + 100 * 1000;
2348            long timeNow = timeStart;
2349            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2350                try {
2351                    Thread.sleep(WAIT_TIME_MS);
2352                } catch (InterruptedException e) {
2353                    // Do nothing
2354                }
2355                timeNow = SystemClock.uptimeMillis();
2356                if (timeNow > timeEnd) {
2357                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2358                    Slog.wtf(TAG, "cppreopt did not finish!");
2359                    break;
2360                }
2361            }
2362
2363            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2364        }
2365    }
2366
2367    public PackageManagerService(Context context, Installer installer,
2368            boolean factoryTest, boolean onlyCore) {
2369        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2370        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2371        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2372                SystemClock.uptimeMillis());
2373
2374        if (mSdkVersion <= 0) {
2375            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2376        }
2377
2378        mContext = context;
2379
2380        mFactoryTest = factoryTest;
2381        mOnlyCore = onlyCore;
2382        mMetrics = new DisplayMetrics();
2383        mInstaller = installer;
2384
2385        // Create sub-components that provide services / data. Order here is important.
2386        synchronized (mInstallLock) {
2387        synchronized (mPackages) {
2388            // Expose private service for system components to use.
2389            LocalServices.addService(
2390                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2391            sUserManager = new UserManagerService(context, this,
2392                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2393            mPermissionManager = PermissionManagerService.create(context,
2394                    new DefaultPermissionGrantedCallback() {
2395                        @Override
2396                        public void onDefaultRuntimePermissionsGranted(int userId) {
2397                            synchronized(mPackages) {
2398                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2399                            }
2400                        }
2401                    }, mPackages /*externalLock*/);
2402            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2403            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2404        }
2405        }
2406        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2407                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2408        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2409                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2410        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2411                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2412        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2413                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2414        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2415                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2416        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2417                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2418        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2419                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2420
2421        String separateProcesses = SystemProperties.get("debug.separate_processes");
2422        if (separateProcesses != null && separateProcesses.length() > 0) {
2423            if ("*".equals(separateProcesses)) {
2424                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2425                mSeparateProcesses = null;
2426                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2427            } else {
2428                mDefParseFlags = 0;
2429                mSeparateProcesses = separateProcesses.split(",");
2430                Slog.w(TAG, "Running with debug.separate_processes: "
2431                        + separateProcesses);
2432            }
2433        } else {
2434            mDefParseFlags = 0;
2435            mSeparateProcesses = null;
2436        }
2437
2438        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2439                "*dexopt*");
2440        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2441                installer, mInstallLock);
2442        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2443                dexManagerListener);
2444        mArtManagerService = new ArtManagerService(this, installer, mInstallLock);
2445        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2446
2447        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2448                FgThread.get().getLooper());
2449
2450        getDefaultDisplayMetrics(context, mMetrics);
2451
2452        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2453        SystemConfig systemConfig = SystemConfig.getInstance();
2454        mAvailableFeatures = systemConfig.getAvailableFeatures();
2455        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2456
2457        mProtectedPackages = new ProtectedPackages(mContext);
2458
2459        synchronized (mInstallLock) {
2460        // writer
2461        synchronized (mPackages) {
2462            mHandlerThread = new ServiceThread(TAG,
2463                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2464            mHandlerThread.start();
2465            mHandler = new PackageHandler(mHandlerThread.getLooper());
2466            mProcessLoggingHandler = new ProcessLoggingHandler();
2467            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2468            mInstantAppRegistry = new InstantAppRegistry(this);
2469
2470            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2471            final int builtInLibCount = libConfig.size();
2472            for (int i = 0; i < builtInLibCount; i++) {
2473                String name = libConfig.keyAt(i);
2474                String path = libConfig.valueAt(i);
2475                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2476                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2477            }
2478
2479            SELinuxMMAC.readInstallPolicy();
2480
2481            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2482            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2483            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2484
2485            // Clean up orphaned packages for which the code path doesn't exist
2486            // and they are an update to a system app - caused by bug/32321269
2487            final int packageSettingCount = mSettings.mPackages.size();
2488            for (int i = packageSettingCount - 1; i >= 0; i--) {
2489                PackageSetting ps = mSettings.mPackages.valueAt(i);
2490                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2491                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2492                    mSettings.mPackages.removeAt(i);
2493                    mSettings.enableSystemPackageLPw(ps.name);
2494                }
2495            }
2496
2497            if (mFirstBoot) {
2498                requestCopyPreoptedFiles();
2499            }
2500
2501            String customResolverActivity = Resources.getSystem().getString(
2502                    R.string.config_customResolverActivity);
2503            if (TextUtils.isEmpty(customResolverActivity)) {
2504                customResolverActivity = null;
2505            } else {
2506                mCustomResolverComponentName = ComponentName.unflattenFromString(
2507                        customResolverActivity);
2508            }
2509
2510            long startTime = SystemClock.uptimeMillis();
2511
2512            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2513                    startTime);
2514
2515            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2516            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2517
2518            if (bootClassPath == null) {
2519                Slog.w(TAG, "No BOOTCLASSPATH found!");
2520            }
2521
2522            if (systemServerClassPath == null) {
2523                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2524            }
2525
2526            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2527
2528            final VersionInfo ver = mSettings.getInternalVersion();
2529            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2530            if (mIsUpgrade) {
2531                logCriticalInfo(Log.INFO,
2532                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2533            }
2534
2535            // when upgrading from pre-M, promote system app permissions from install to runtime
2536            mPromoteSystemApps =
2537                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2538
2539            // When upgrading from pre-N, we need to handle package extraction like first boot,
2540            // as there is no profiling data available.
2541            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2542
2543            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2544
2545            // save off the names of pre-existing system packages prior to scanning; we don't
2546            // want to automatically grant runtime permissions for new system apps
2547            if (mPromoteSystemApps) {
2548                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2549                while (pkgSettingIter.hasNext()) {
2550                    PackageSetting ps = pkgSettingIter.next();
2551                    if (isSystemApp(ps)) {
2552                        mExistingSystemPackages.add(ps.name);
2553                    }
2554                }
2555            }
2556
2557            mCacheDir = preparePackageParserCache(mIsUpgrade);
2558
2559            // Set flag to monitor and not change apk file paths when
2560            // scanning install directories.
2561            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2562
2563            if (mIsUpgrade || mFirstBoot) {
2564                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2565            }
2566
2567            // Collect vendor/product overlay packages. (Do this before scanning any apps.)
2568            // For security and version matching reason, only consider
2569            // overlay packages if they reside in the right directory.
2570            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2571                    mDefParseFlags
2572                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2573                    scanFlags
2574                    | SCAN_AS_SYSTEM
2575                    | SCAN_AS_VENDOR,
2576                    0);
2577            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2578                    mDefParseFlags
2579                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2580                    scanFlags
2581                    | SCAN_AS_SYSTEM
2582                    | SCAN_AS_PRODUCT,
2583                    0);
2584
2585            mParallelPackageParserCallback.findStaticOverlayPackages();
2586
2587            // Find base frameworks (resource packages without code).
2588            scanDirTracedLI(frameworkDir,
2589                    mDefParseFlags
2590                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2591                    scanFlags
2592                    | SCAN_NO_DEX
2593                    | SCAN_AS_SYSTEM
2594                    | SCAN_AS_PRIVILEGED,
2595                    0);
2596
2597            // Collect privileged system packages.
2598            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2599            scanDirTracedLI(privilegedAppDir,
2600                    mDefParseFlags
2601                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2602                    scanFlags
2603                    | SCAN_AS_SYSTEM
2604                    | SCAN_AS_PRIVILEGED,
2605                    0);
2606
2607            // Collect ordinary system packages.
2608            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2609            scanDirTracedLI(systemAppDir,
2610                    mDefParseFlags
2611                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2612                    scanFlags
2613                    | SCAN_AS_SYSTEM,
2614                    0);
2615
2616            // Collect privileged vendor packages.
2617            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2618            try {
2619                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2620            } catch (IOException e) {
2621                // failed to look up canonical path, continue with original one
2622            }
2623            scanDirTracedLI(privilegedVendorAppDir,
2624                    mDefParseFlags
2625                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2626                    scanFlags
2627                    | SCAN_AS_SYSTEM
2628                    | SCAN_AS_VENDOR
2629                    | SCAN_AS_PRIVILEGED,
2630                    0);
2631
2632            // Collect ordinary vendor packages.
2633            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2634            try {
2635                vendorAppDir = vendorAppDir.getCanonicalFile();
2636            } catch (IOException e) {
2637                // failed to look up canonical path, continue with original one
2638            }
2639            scanDirTracedLI(vendorAppDir,
2640                    mDefParseFlags
2641                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2642                    scanFlags
2643                    | SCAN_AS_SYSTEM
2644                    | SCAN_AS_VENDOR,
2645                    0);
2646
2647            // Collect privileged odm packages. /odm is another vendor partition
2648            // other than /vendor.
2649            File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
2650                        "priv-app");
2651            try {
2652                privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
2653            } catch (IOException e) {
2654                // failed to look up canonical path, continue with original one
2655            }
2656            scanDirTracedLI(privilegedOdmAppDir,
2657                    mDefParseFlags
2658                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2659                    scanFlags
2660                    | SCAN_AS_SYSTEM
2661                    | SCAN_AS_VENDOR
2662                    | SCAN_AS_PRIVILEGED,
2663                    0);
2664
2665            // Collect ordinary odm packages. /odm is another vendor partition
2666            // other than /vendor.
2667            File odmAppDir = new File(Environment.getOdmDirectory(), "app");
2668            try {
2669                odmAppDir = odmAppDir.getCanonicalFile();
2670            } catch (IOException e) {
2671                // failed to look up canonical path, continue with original one
2672            }
2673            scanDirTracedLI(odmAppDir,
2674                    mDefParseFlags
2675                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2676                    scanFlags
2677                    | SCAN_AS_SYSTEM
2678                    | SCAN_AS_VENDOR,
2679                    0);
2680
2681            // Collect all OEM packages.
2682            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2683            scanDirTracedLI(oemAppDir,
2684                    mDefParseFlags
2685                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2686                    scanFlags
2687                    | SCAN_AS_SYSTEM
2688                    | SCAN_AS_OEM,
2689                    0);
2690
2691            // Collected privileged product packages.
2692            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2693            try {
2694                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2695            } catch (IOException e) {
2696                // failed to look up canonical path, continue with original one
2697            }
2698            scanDirTracedLI(privilegedProductAppDir,
2699                    mDefParseFlags
2700                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2701                    scanFlags
2702                    | SCAN_AS_SYSTEM
2703                    | SCAN_AS_PRODUCT
2704                    | SCAN_AS_PRIVILEGED,
2705                    0);
2706
2707            // Collect ordinary product packages.
2708            File productAppDir = new File(Environment.getProductDirectory(), "app");
2709            try {
2710                productAppDir = productAppDir.getCanonicalFile();
2711            } catch (IOException e) {
2712                // failed to look up canonical path, continue with original one
2713            }
2714            scanDirTracedLI(productAppDir,
2715                    mDefParseFlags
2716                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2717                    scanFlags
2718                    | SCAN_AS_SYSTEM
2719                    | SCAN_AS_PRODUCT,
2720                    0);
2721
2722            // Prune any system packages that no longer exist.
2723            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2724            // Stub packages must either be replaced with full versions in the /data
2725            // partition or be disabled.
2726            final List<String> stubSystemApps = new ArrayList<>();
2727            if (!mOnlyCore) {
2728                // do this first before mucking with mPackages for the "expecting better" case
2729                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2730                while (pkgIterator.hasNext()) {
2731                    final PackageParser.Package pkg = pkgIterator.next();
2732                    if (pkg.isStub) {
2733                        stubSystemApps.add(pkg.packageName);
2734                    }
2735                }
2736
2737                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2738                while (psit.hasNext()) {
2739                    PackageSetting ps = psit.next();
2740
2741                    /*
2742                     * If this is not a system app, it can't be a
2743                     * disable system app.
2744                     */
2745                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2746                        continue;
2747                    }
2748
2749                    /*
2750                     * If the package is scanned, it's not erased.
2751                     */
2752                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2753                    if (scannedPkg != null) {
2754                        /*
2755                         * If the system app is both scanned and in the
2756                         * disabled packages list, then it must have been
2757                         * added via OTA. Remove it from the currently
2758                         * scanned package so the previously user-installed
2759                         * application can be scanned.
2760                         */
2761                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2762                            logCriticalInfo(Log.WARN,
2763                                    "Expecting better updated system app for " + ps.name
2764                                    + "; removing system app.  Last known"
2765                                    + " codePath=" + ps.codePathString
2766                                    + ", versionCode=" + ps.versionCode
2767                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2768                            removePackageLI(scannedPkg, true);
2769                            mExpectingBetter.put(ps.name, ps.codePath);
2770                        }
2771
2772                        continue;
2773                    }
2774
2775                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2776                        psit.remove();
2777                        logCriticalInfo(Log.WARN, "System package " + ps.name
2778                                + " no longer exists; it's data will be wiped");
2779                        // Actual deletion of code and data will be handled by later
2780                        // reconciliation step
2781                    } else {
2782                        // we still have a disabled system package, but, it still might have
2783                        // been removed. check the code path still exists and check there's
2784                        // still a package. the latter can happen if an OTA keeps the same
2785                        // code path, but, changes the package name.
2786                        final PackageSetting disabledPs =
2787                                mSettings.getDisabledSystemPkgLPr(ps.name);
2788                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2789                                || disabledPs.pkg == null) {
2790                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2791                        }
2792                    }
2793                }
2794            }
2795
2796            //delete tmp files
2797            deleteTempPackageFiles();
2798
2799            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2800
2801            // Remove any shared userIDs that have no associated packages
2802            mSettings.pruneSharedUsersLPw();
2803            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2804            final int systemPackagesCount = mPackages.size();
2805            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2806                    + " ms, packageCount: " + systemPackagesCount
2807                    + " , timePerPackage: "
2808                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2809                    + " , cached: " + cachedSystemApps);
2810            if (mIsUpgrade && systemPackagesCount > 0) {
2811                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2812                        ((int) systemScanTime) / systemPackagesCount);
2813            }
2814            if (!mOnlyCore) {
2815                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2816                        SystemClock.uptimeMillis());
2817                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2818
2819                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2820                        | PackageParser.PARSE_FORWARD_LOCK,
2821                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2822
2823                // Remove disable package settings for updated system apps that were
2824                // removed via an OTA. If the update is no longer present, remove the
2825                // app completely. Otherwise, revoke their system privileges.
2826                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2827                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2828                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2829                    final String msg;
2830                    if (deletedPkg == null) {
2831                        // should have found an update, but, we didn't; remove everything
2832                        msg = "Updated system package " + deletedAppName
2833                                + " no longer exists; removing its data";
2834                        // Actual deletion of code and data will be handled by later
2835                        // reconciliation step
2836                    } else {
2837                        // found an update; revoke system privileges
2838                        msg = "Updated system package + " + deletedAppName
2839                                + " no longer exists; revoking system privileges";
2840
2841                        // Don't do anything if a stub is removed from the system image. If
2842                        // we were to remove the uncompressed version from the /data partition,
2843                        // this is where it'd be done.
2844
2845                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2846                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2847                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2848                    }
2849                    logCriticalInfo(Log.WARN, msg);
2850                }
2851
2852                /*
2853                 * Make sure all system apps that we expected to appear on
2854                 * the userdata partition actually showed up. If they never
2855                 * appeared, crawl back and revive the system version.
2856                 */
2857                for (int i = 0; i < mExpectingBetter.size(); i++) {
2858                    final String packageName = mExpectingBetter.keyAt(i);
2859                    if (!mPackages.containsKey(packageName)) {
2860                        final File scanFile = mExpectingBetter.valueAt(i);
2861
2862                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2863                                + " but never showed up; reverting to system");
2864
2865                        final @ParseFlags int reparseFlags;
2866                        final @ScanFlags int rescanFlags;
2867                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2868                            reparseFlags =
2869                                    mDefParseFlags |
2870                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2871                            rescanFlags =
2872                                    scanFlags
2873                                    | SCAN_AS_SYSTEM
2874                                    | SCAN_AS_PRIVILEGED;
2875                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2876                            reparseFlags =
2877                                    mDefParseFlags |
2878                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2879                            rescanFlags =
2880                                    scanFlags
2881                                    | SCAN_AS_SYSTEM;
2882                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
2883                                || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
2884                            reparseFlags =
2885                                    mDefParseFlags |
2886                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2887                            rescanFlags =
2888                                    scanFlags
2889                                    | SCAN_AS_SYSTEM
2890                                    | SCAN_AS_VENDOR
2891                                    | SCAN_AS_PRIVILEGED;
2892                        } else if (FileUtils.contains(vendorAppDir, scanFile)
2893                                || FileUtils.contains(odmAppDir, scanFile)) {
2894                            reparseFlags =
2895                                    mDefParseFlags |
2896                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2897                            rescanFlags =
2898                                    scanFlags
2899                                    | SCAN_AS_SYSTEM
2900                                    | SCAN_AS_VENDOR;
2901                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2902                            reparseFlags =
2903                                    mDefParseFlags |
2904                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2905                            rescanFlags =
2906                                    scanFlags
2907                                    | SCAN_AS_SYSTEM
2908                                    | SCAN_AS_OEM;
2909                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
2910                            reparseFlags =
2911                                    mDefParseFlags |
2912                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2913                            rescanFlags =
2914                                    scanFlags
2915                                    | SCAN_AS_SYSTEM
2916                                    | SCAN_AS_PRODUCT
2917                                    | SCAN_AS_PRIVILEGED;
2918                        } else if (FileUtils.contains(productAppDir, scanFile)) {
2919                            reparseFlags =
2920                                    mDefParseFlags |
2921                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2922                            rescanFlags =
2923                                    scanFlags
2924                                    | SCAN_AS_SYSTEM
2925                                    | SCAN_AS_PRODUCT;
2926                        } else {
2927                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2928                            continue;
2929                        }
2930
2931                        mSettings.enableSystemPackageLPw(packageName);
2932
2933                        try {
2934                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2935                        } catch (PackageManagerException e) {
2936                            Slog.e(TAG, "Failed to parse original system package: "
2937                                    + e.getMessage());
2938                        }
2939                    }
2940                }
2941
2942                // Uncompress and install any stubbed system applications.
2943                // This must be done last to ensure all stubs are replaced or disabled.
2944                decompressSystemApplications(stubSystemApps, scanFlags);
2945
2946                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2947                                - cachedSystemApps;
2948
2949                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2950                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2951                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2952                        + " ms, packageCount: " + dataPackagesCount
2953                        + " , timePerPackage: "
2954                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2955                        + " , cached: " + cachedNonSystemApps);
2956                if (mIsUpgrade && dataPackagesCount > 0) {
2957                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2958                            ((int) dataScanTime) / dataPackagesCount);
2959                }
2960            }
2961            mExpectingBetter.clear();
2962
2963            // Resolve the storage manager.
2964            mStorageManagerPackage = getStorageManagerPackageName();
2965
2966            // Resolve protected action filters. Only the setup wizard is allowed to
2967            // have a high priority filter for these actions.
2968            mSetupWizardPackage = getSetupWizardPackageName();
2969            if (mProtectedFilters.size() > 0) {
2970                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2971                    Slog.i(TAG, "No setup wizard;"
2972                        + " All protected intents capped to priority 0");
2973                }
2974                for (ActivityIntentInfo filter : mProtectedFilters) {
2975                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2976                        if (DEBUG_FILTERS) {
2977                            Slog.i(TAG, "Found setup wizard;"
2978                                + " allow priority " + filter.getPriority() + ";"
2979                                + " package: " + filter.activity.info.packageName
2980                                + " activity: " + filter.activity.className
2981                                + " priority: " + filter.getPriority());
2982                        }
2983                        // skip setup wizard; allow it to keep the high priority filter
2984                        continue;
2985                    }
2986                    if (DEBUG_FILTERS) {
2987                        Slog.i(TAG, "Protected action; cap priority to 0;"
2988                                + " package: " + filter.activity.info.packageName
2989                                + " activity: " + filter.activity.className
2990                                + " origPrio: " + filter.getPriority());
2991                    }
2992                    filter.setPriority(0);
2993                }
2994            }
2995
2996            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
2997
2998            mDeferProtectedFilters = false;
2999            mProtectedFilters.clear();
3000
3001            // Now that we know all of the shared libraries, update all clients to have
3002            // the correct library paths.
3003            updateAllSharedLibrariesLPw(null);
3004
3005            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3006                // NOTE: We ignore potential failures here during a system scan (like
3007                // the rest of the commands above) because there's precious little we
3008                // can do about it. A settings error is reported, though.
3009                final List<String> changedAbiCodePath =
3010                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
3011                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3012                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3013                        final String codePathString = changedAbiCodePath.get(i);
3014                        try {
3015                            mInstaller.rmdex(codePathString,
3016                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
3017                        } catch (InstallerException ignored) {
3018                        }
3019                    }
3020                }
3021                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3022                // SELinux domain.
3023                setting.fixSeInfoLocked();
3024            }
3025
3026            // Now that we know all the packages we are keeping,
3027            // read and update their last usage times.
3028            mPackageUsage.read(mPackages);
3029            mCompilerStats.read();
3030
3031            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3032                    SystemClock.uptimeMillis());
3033            Slog.i(TAG, "Time to scan packages: "
3034                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
3035                    + " seconds");
3036
3037            // If the platform SDK has changed since the last time we booted,
3038            // we need to re-grant app permission to catch any new ones that
3039            // appear.  This is really a hack, and means that apps can in some
3040            // cases get permissions that the user didn't initially explicitly
3041            // allow...  it would be nice to have some better way to handle
3042            // this situation.
3043            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3044            if (sdkUpdated) {
3045                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3046                        + mSdkVersion + "; regranting permissions for internal storage");
3047            }
3048            mPermissionManager.updateAllPermissions(
3049                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3050                    mPermissionCallback);
3051            ver.sdkVersion = mSdkVersion;
3052
3053            // If this is the first boot or an update from pre-M, and it is a normal
3054            // boot, then we need to initialize the default preferred apps across
3055            // all defined users.
3056            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3057                for (UserInfo user : sUserManager.getUsers(true)) {
3058                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
3059                    applyFactoryDefaultBrowserLPw(user.id);
3060                    primeDomainVerificationsLPw(user.id);
3061                }
3062            }
3063
3064            // Prepare storage for system user really early during boot,
3065            // since core system apps like SettingsProvider and SystemUI
3066            // can't wait for user to start
3067            final int storageFlags;
3068            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3069                storageFlags = StorageManager.FLAG_STORAGE_DE;
3070            } else {
3071                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3072            }
3073            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3074                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3075                    true /* onlyCoreApps */);
3076            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3077                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3078                        Trace.TRACE_TAG_PACKAGE_MANAGER);
3079                traceLog.traceBegin("AppDataFixup");
3080                try {
3081                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3082                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3083                } catch (InstallerException e) {
3084                    Slog.w(TAG, "Trouble fixing GIDs", e);
3085                }
3086                traceLog.traceEnd();
3087
3088                traceLog.traceBegin("AppDataPrepare");
3089                if (deferPackages == null || deferPackages.isEmpty()) {
3090                    return;
3091                }
3092                int count = 0;
3093                for (String pkgName : deferPackages) {
3094                    PackageParser.Package pkg = null;
3095                    synchronized (mPackages) {
3096                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
3097                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3098                            pkg = ps.pkg;
3099                        }
3100                    }
3101                    if (pkg != null) {
3102                        synchronized (mInstallLock) {
3103                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3104                                    true /* maybeMigrateAppData */);
3105                        }
3106                        count++;
3107                    }
3108                }
3109                traceLog.traceEnd();
3110                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3111            }, "prepareAppData");
3112
3113            // If this is first boot after an OTA, and a normal boot, then
3114            // we need to clear code cache directories.
3115            // Note that we do *not* clear the application profiles. These remain valid
3116            // across OTAs and are used to drive profile verification (post OTA) and
3117            // profile compilation (without waiting to collect a fresh set of profiles).
3118            if (mIsUpgrade && !onlyCore) {
3119                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3120                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3121                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3122                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3123                        // No apps are running this early, so no need to freeze
3124                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3125                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3126                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3127                    }
3128                }
3129                ver.fingerprint = Build.FINGERPRINT;
3130            }
3131
3132            checkDefaultBrowser();
3133
3134            // clear only after permissions and other defaults have been updated
3135            mExistingSystemPackages.clear();
3136            mPromoteSystemApps = false;
3137
3138            // All the changes are done during package scanning.
3139            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3140
3141            // can downgrade to reader
3142            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3143            mSettings.writeLPr();
3144            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3145            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3146                    SystemClock.uptimeMillis());
3147
3148            if (!mOnlyCore) {
3149                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3150                mRequiredInstallerPackage = getRequiredInstallerLPr();
3151                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3152                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3153                if (mIntentFilterVerifierComponent != null) {
3154                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3155                            mIntentFilterVerifierComponent);
3156                } else {
3157                    mIntentFilterVerifier = null;
3158                }
3159                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3160                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3161                        SharedLibraryInfo.VERSION_UNDEFINED);
3162                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3163                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3164                        SharedLibraryInfo.VERSION_UNDEFINED);
3165            } else {
3166                mRequiredVerifierPackage = null;
3167                mRequiredInstallerPackage = null;
3168                mRequiredUninstallerPackage = null;
3169                mIntentFilterVerifierComponent = null;
3170                mIntentFilterVerifier = null;
3171                mServicesSystemSharedLibraryPackageName = null;
3172                mSharedSystemSharedLibraryPackageName = null;
3173            }
3174
3175            mInstallerService = new PackageInstallerService(context, this);
3176            final Pair<ComponentName, String> instantAppResolverComponent =
3177                    getInstantAppResolverLPr();
3178            if (instantAppResolverComponent != null) {
3179                if (DEBUG_INSTANT) {
3180                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3181                }
3182                mInstantAppResolverConnection = new InstantAppResolverConnection(
3183                        mContext, instantAppResolverComponent.first,
3184                        instantAppResolverComponent.second);
3185                mInstantAppResolverSettingsComponent =
3186                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3187            } else {
3188                mInstantAppResolverConnection = null;
3189                mInstantAppResolverSettingsComponent = null;
3190            }
3191            updateInstantAppInstallerLocked(null);
3192
3193            // Read and update the usage of dex files.
3194            // Do this at the end of PM init so that all the packages have their
3195            // data directory reconciled.
3196            // At this point we know the code paths of the packages, so we can validate
3197            // the disk file and build the internal cache.
3198            // The usage file is expected to be small so loading and verifying it
3199            // should take a fairly small time compare to the other activities (e.g. package
3200            // scanning).
3201            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3202            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3203            for (int userId : currentUserIds) {
3204                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3205            }
3206            mDexManager.load(userPackages);
3207            if (mIsUpgrade) {
3208                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3209                        (int) (SystemClock.uptimeMillis() - startTime));
3210            }
3211        } // synchronized (mPackages)
3212        } // synchronized (mInstallLock)
3213
3214        // Now after opening every single application zip, make sure they
3215        // are all flushed.  Not really needed, but keeps things nice and
3216        // tidy.
3217        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3218        Runtime.getRuntime().gc();
3219        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3220
3221        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3222        FallbackCategoryProvider.loadFallbacks();
3223        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3224
3225        // The initial scanning above does many calls into installd while
3226        // holding the mPackages lock, but we're mostly interested in yelling
3227        // once we have a booted system.
3228        mInstaller.setWarnIfHeld(mPackages);
3229
3230        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3231    }
3232
3233    /**
3234     * Uncompress and install stub applications.
3235     * <p>In order to save space on the system partition, some applications are shipped in a
3236     * compressed form. In addition the compressed bits for the full application, the
3237     * system image contains a tiny stub comprised of only the Android manifest.
3238     * <p>During the first boot, attempt to uncompress and install the full application. If
3239     * the application can't be installed for any reason, disable the stub and prevent
3240     * uncompressing the full application during future boots.
3241     * <p>In order to forcefully attempt an installation of a full application, go to app
3242     * settings and enable the application.
3243     */
3244    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3245        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3246            final String pkgName = stubSystemApps.get(i);
3247            // skip if the system package is already disabled
3248            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3249                stubSystemApps.remove(i);
3250                continue;
3251            }
3252            // skip if the package isn't installed (?!); this should never happen
3253            final PackageParser.Package pkg = mPackages.get(pkgName);
3254            if (pkg == null) {
3255                stubSystemApps.remove(i);
3256                continue;
3257            }
3258            // skip if the package has been disabled by the user
3259            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3260            if (ps != null) {
3261                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3262                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3263                    stubSystemApps.remove(i);
3264                    continue;
3265                }
3266            }
3267
3268            if (DEBUG_COMPRESSION) {
3269                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3270            }
3271
3272            // uncompress the binary to its eventual destination on /data
3273            final File scanFile = decompressPackage(pkg);
3274            if (scanFile == null) {
3275                continue;
3276            }
3277
3278            // install the package to replace the stub on /system
3279            try {
3280                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3281                removePackageLI(pkg, true /*chatty*/);
3282                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3283                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3284                        UserHandle.USER_SYSTEM, "android");
3285                stubSystemApps.remove(i);
3286                continue;
3287            } catch (PackageManagerException e) {
3288                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3289            }
3290
3291            // any failed attempt to install the package will be cleaned up later
3292        }
3293
3294        // disable any stub still left; these failed to install the full application
3295        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3296            final String pkgName = stubSystemApps.get(i);
3297            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3298            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3299                    UserHandle.USER_SYSTEM, "android");
3300            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3301        }
3302    }
3303
3304    /**
3305     * Decompresses the given package on the system image onto
3306     * the /data partition.
3307     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3308     */
3309    private File decompressPackage(PackageParser.Package pkg) {
3310        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3311        if (compressedFiles == null || compressedFiles.length == 0) {
3312            if (DEBUG_COMPRESSION) {
3313                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3314            }
3315            return null;
3316        }
3317        final File dstCodePath =
3318                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3319        int ret = PackageManager.INSTALL_SUCCEEDED;
3320        try {
3321            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3322            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3323            for (File srcFile : compressedFiles) {
3324                final String srcFileName = srcFile.getName();
3325                final String dstFileName = srcFileName.substring(
3326                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3327                final File dstFile = new File(dstCodePath, dstFileName);
3328                ret = decompressFile(srcFile, dstFile);
3329                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3330                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3331                            + "; pkg: " + pkg.packageName
3332                            + ", file: " + dstFileName);
3333                    break;
3334                }
3335            }
3336        } catch (ErrnoException e) {
3337            logCriticalInfo(Log.ERROR, "Failed to decompress"
3338                    + "; pkg: " + pkg.packageName
3339                    + ", err: " + e.errno);
3340        }
3341        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3342            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3343            NativeLibraryHelper.Handle handle = null;
3344            try {
3345                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3346                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3347                        null /*abiOverride*/);
3348            } catch (IOException e) {
3349                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3350                        + "; pkg: " + pkg.packageName);
3351                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3352            } finally {
3353                IoUtils.closeQuietly(handle);
3354            }
3355        }
3356        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3357            if (dstCodePath == null || !dstCodePath.exists()) {
3358                return null;
3359            }
3360            removeCodePathLI(dstCodePath);
3361            return null;
3362        }
3363
3364        return dstCodePath;
3365    }
3366
3367    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3368        // we're only interested in updating the installer appliction when 1) it's not
3369        // already set or 2) the modified package is the installer
3370        if (mInstantAppInstallerActivity != null
3371                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3372                        .equals(modifiedPackage)) {
3373            return;
3374        }
3375        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3376    }
3377
3378    private static File preparePackageParserCache(boolean isUpgrade) {
3379        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3380            return null;
3381        }
3382
3383        // Disable package parsing on eng builds to allow for faster incremental development.
3384        if (Build.IS_ENG) {
3385            return null;
3386        }
3387
3388        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3389            Slog.i(TAG, "Disabling package parser cache due to system property.");
3390            return null;
3391        }
3392
3393        // The base directory for the package parser cache lives under /data/system/.
3394        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3395                "package_cache");
3396        if (cacheBaseDir == null) {
3397            return null;
3398        }
3399
3400        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3401        // This also serves to "GC" unused entries when the package cache version changes (which
3402        // can only happen during upgrades).
3403        if (isUpgrade) {
3404            FileUtils.deleteContents(cacheBaseDir);
3405        }
3406
3407
3408        // Return the versioned package cache directory. This is something like
3409        // "/data/system/package_cache/1"
3410        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3411
3412        if (cacheDir == null) {
3413            // Something went wrong. Attempt to delete everything and return.
3414            Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3415            FileUtils.deleteContentsAndDir(cacheBaseDir);
3416            return null;
3417        }
3418
3419        // The following is a workaround to aid development on non-numbered userdebug
3420        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3421        // the system partition is newer.
3422        //
3423        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3424        // that starts with "eng." to signify that this is an engineering build and not
3425        // destined for release.
3426        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3427            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3428
3429            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3430            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3431            // in general and should not be used for production changes. In this specific case,
3432            // we know that they will work.
3433            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3434            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3435                FileUtils.deleteContents(cacheBaseDir);
3436                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3437            }
3438        }
3439
3440        return cacheDir;
3441    }
3442
3443    @Override
3444    public boolean isFirstBoot() {
3445        // allow instant applications
3446        return mFirstBoot;
3447    }
3448
3449    @Override
3450    public boolean isOnlyCoreApps() {
3451        // allow instant applications
3452        return mOnlyCore;
3453    }
3454
3455    @Override
3456    public boolean isUpgrade() {
3457        // allow instant applications
3458        // The system property allows testing ota flow when upgraded to the same image.
3459        return mIsUpgrade || SystemProperties.getBoolean(
3460                "persist.pm.mock-upgrade", false /* default */);
3461    }
3462
3463    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3464        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3465
3466        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3467                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3468                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3469        if (matches.size() == 1) {
3470            return matches.get(0).getComponentInfo().packageName;
3471        } else if (matches.size() == 0) {
3472            Log.e(TAG, "There should probably be a verifier, but, none were found");
3473            return null;
3474        }
3475        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3476    }
3477
3478    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3479        synchronized (mPackages) {
3480            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3481            if (libraryEntry == null) {
3482                throw new IllegalStateException("Missing required shared library:" + name);
3483            }
3484            return libraryEntry.apk;
3485        }
3486    }
3487
3488    private @NonNull String getRequiredInstallerLPr() {
3489        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3490        intent.addCategory(Intent.CATEGORY_DEFAULT);
3491        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3492
3493        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3494                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3495                UserHandle.USER_SYSTEM);
3496        if (matches.size() == 1) {
3497            ResolveInfo resolveInfo = matches.get(0);
3498            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3499                throw new RuntimeException("The installer must be a privileged app");
3500            }
3501            return matches.get(0).getComponentInfo().packageName;
3502        } else {
3503            throw new RuntimeException("There must be exactly one installer; found " + matches);
3504        }
3505    }
3506
3507    private @NonNull String getRequiredUninstallerLPr() {
3508        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3509        intent.addCategory(Intent.CATEGORY_DEFAULT);
3510        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3511
3512        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3513                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3514                UserHandle.USER_SYSTEM);
3515        if (resolveInfo == null ||
3516                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3517            throw new RuntimeException("There must be exactly one uninstaller; found "
3518                    + resolveInfo);
3519        }
3520        return resolveInfo.getComponentInfo().packageName;
3521    }
3522
3523    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3524        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3525
3526        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3527                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3528                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3529        ResolveInfo best = null;
3530        final int N = matches.size();
3531        for (int i = 0; i < N; i++) {
3532            final ResolveInfo cur = matches.get(i);
3533            final String packageName = cur.getComponentInfo().packageName;
3534            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3535                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3536                continue;
3537            }
3538
3539            if (best == null || cur.priority > best.priority) {
3540                best = cur;
3541            }
3542        }
3543
3544        if (best != null) {
3545            return best.getComponentInfo().getComponentName();
3546        }
3547        Slog.w(TAG, "Intent filter verifier not found");
3548        return null;
3549    }
3550
3551    @Override
3552    public @Nullable ComponentName getInstantAppResolverComponent() {
3553        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3554            return null;
3555        }
3556        synchronized (mPackages) {
3557            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3558            if (instantAppResolver == null) {
3559                return null;
3560            }
3561            return instantAppResolver.first;
3562        }
3563    }
3564
3565    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3566        final String[] packageArray =
3567                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3568        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3569            if (DEBUG_INSTANT) {
3570                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3571            }
3572            return null;
3573        }
3574
3575        final int callingUid = Binder.getCallingUid();
3576        final int resolveFlags =
3577                MATCH_DIRECT_BOOT_AWARE
3578                | MATCH_DIRECT_BOOT_UNAWARE
3579                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3580        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3581        final Intent resolverIntent = new Intent(actionName);
3582        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3583                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3584        final int N = resolvers.size();
3585        if (N == 0) {
3586            if (DEBUG_INSTANT) {
3587                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3588            }
3589            return null;
3590        }
3591
3592        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3593        for (int i = 0; i < N; i++) {
3594            final ResolveInfo info = resolvers.get(i);
3595
3596            if (info.serviceInfo == null) {
3597                continue;
3598            }
3599
3600            final String packageName = info.serviceInfo.packageName;
3601            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3602                if (DEBUG_INSTANT) {
3603                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3604                            + " pkg: " + packageName + ", info:" + info);
3605                }
3606                continue;
3607            }
3608
3609            if (DEBUG_INSTANT) {
3610                Slog.v(TAG, "Ephemeral resolver found;"
3611                        + " pkg: " + packageName + ", info:" + info);
3612            }
3613            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3614        }
3615        if (DEBUG_INSTANT) {
3616            Slog.v(TAG, "Ephemeral resolver NOT found");
3617        }
3618        return null;
3619    }
3620
3621    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3622        String[] orderedActions = Build.IS_ENG
3623                ? new String[]{
3624                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3625                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3626                : new String[]{
3627                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3628
3629        final int resolveFlags =
3630                MATCH_DIRECT_BOOT_AWARE
3631                        | MATCH_DIRECT_BOOT_UNAWARE
3632                        | Intent.FLAG_IGNORE_EPHEMERAL
3633                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3634        final Intent intent = new Intent();
3635        intent.addCategory(Intent.CATEGORY_DEFAULT);
3636        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3637        List<ResolveInfo> matches = null;
3638        for (String action : orderedActions) {
3639            intent.setAction(action);
3640            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3641                    resolveFlags, UserHandle.USER_SYSTEM);
3642            if (matches.isEmpty()) {
3643                if (DEBUG_INSTANT) {
3644                    Slog.d(TAG, "Instant App installer not found with " + action);
3645                }
3646            } else {
3647                break;
3648            }
3649        }
3650        Iterator<ResolveInfo> iter = matches.iterator();
3651        while (iter.hasNext()) {
3652            final ResolveInfo rInfo = iter.next();
3653            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3654            if (ps != null) {
3655                final PermissionsState permissionsState = ps.getPermissionsState();
3656                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3657                        || Build.IS_ENG) {
3658                    continue;
3659                }
3660            }
3661            iter.remove();
3662        }
3663        if (matches.size() == 0) {
3664            return null;
3665        } else if (matches.size() == 1) {
3666            return (ActivityInfo) matches.get(0).getComponentInfo();
3667        } else {
3668            throw new RuntimeException(
3669                    "There must be at most one ephemeral installer; found " + matches);
3670        }
3671    }
3672
3673    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3674            @NonNull ComponentName resolver) {
3675        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3676                .addCategory(Intent.CATEGORY_DEFAULT)
3677                .setPackage(resolver.getPackageName());
3678        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3679        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3680                UserHandle.USER_SYSTEM);
3681        if (matches.isEmpty()) {
3682            return null;
3683        }
3684        return matches.get(0).getComponentInfo().getComponentName();
3685    }
3686
3687    private void primeDomainVerificationsLPw(int userId) {
3688        if (DEBUG_DOMAIN_VERIFICATION) {
3689            Slog.d(TAG, "Priming domain verifications in user " + userId);
3690        }
3691
3692        SystemConfig systemConfig = SystemConfig.getInstance();
3693        ArraySet<String> packages = systemConfig.getLinkedApps();
3694
3695        for (String packageName : packages) {
3696            PackageParser.Package pkg = mPackages.get(packageName);
3697            if (pkg != null) {
3698                if (!pkg.isSystem()) {
3699                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3700                    continue;
3701                }
3702
3703                ArraySet<String> domains = null;
3704                for (PackageParser.Activity a : pkg.activities) {
3705                    for (ActivityIntentInfo filter : a.intents) {
3706                        if (hasValidDomains(filter)) {
3707                            if (domains == null) {
3708                                domains = new ArraySet<String>();
3709                            }
3710                            domains.addAll(filter.getHostsList());
3711                        }
3712                    }
3713                }
3714
3715                if (domains != null && domains.size() > 0) {
3716                    if (DEBUG_DOMAIN_VERIFICATION) {
3717                        Slog.v(TAG, "      + " + packageName);
3718                    }
3719                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3720                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3721                    // and then 'always' in the per-user state actually used for intent resolution.
3722                    final IntentFilterVerificationInfo ivi;
3723                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3724                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3725                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3726                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3727                } else {
3728                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3729                            + "' does not handle web links");
3730                }
3731            } else {
3732                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3733            }
3734        }
3735
3736        scheduleWritePackageRestrictionsLocked(userId);
3737        scheduleWriteSettingsLocked();
3738    }
3739
3740    private void applyFactoryDefaultBrowserLPw(int userId) {
3741        // The default browser app's package name is stored in a string resource,
3742        // with a product-specific overlay used for vendor customization.
3743        String browserPkg = mContext.getResources().getString(
3744                com.android.internal.R.string.default_browser);
3745        if (!TextUtils.isEmpty(browserPkg)) {
3746            // non-empty string => required to be a known package
3747            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3748            if (ps == null) {
3749                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3750                browserPkg = null;
3751            } else {
3752                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3753            }
3754        }
3755
3756        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3757        // default.  If there's more than one, just leave everything alone.
3758        if (browserPkg == null) {
3759            calculateDefaultBrowserLPw(userId);
3760        }
3761    }
3762
3763    private void calculateDefaultBrowserLPw(int userId) {
3764        List<String> allBrowsers = resolveAllBrowserApps(userId);
3765        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3766        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3767    }
3768
3769    private List<String> resolveAllBrowserApps(int userId) {
3770        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3771        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3772                PackageManager.MATCH_ALL, userId);
3773
3774        final int count = list.size();
3775        List<String> result = new ArrayList<String>(count);
3776        for (int i=0; i<count; i++) {
3777            ResolveInfo info = list.get(i);
3778            if (info.activityInfo == null
3779                    || !info.handleAllWebDataURI
3780                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3781                    || result.contains(info.activityInfo.packageName)) {
3782                continue;
3783            }
3784            result.add(info.activityInfo.packageName);
3785        }
3786
3787        return result;
3788    }
3789
3790    private boolean packageIsBrowser(String packageName, int userId) {
3791        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3792                PackageManager.MATCH_ALL, userId);
3793        final int N = list.size();
3794        for (int i = 0; i < N; i++) {
3795            ResolveInfo info = list.get(i);
3796            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3797                return true;
3798            }
3799        }
3800        return false;
3801    }
3802
3803    private void checkDefaultBrowser() {
3804        final int myUserId = UserHandle.myUserId();
3805        final String packageName = getDefaultBrowserPackageName(myUserId);
3806        if (packageName != null) {
3807            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3808            if (info == null) {
3809                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3810                synchronized (mPackages) {
3811                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3812                }
3813            }
3814        }
3815    }
3816
3817    @Override
3818    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3819            throws RemoteException {
3820        try {
3821            return super.onTransact(code, data, reply, flags);
3822        } catch (RuntimeException e) {
3823            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3824                Slog.wtf(TAG, "Package Manager Crash", e);
3825            }
3826            throw e;
3827        }
3828    }
3829
3830    static int[] appendInts(int[] cur, int[] add) {
3831        if (add == null) return cur;
3832        if (cur == null) return add;
3833        final int N = add.length;
3834        for (int i=0; i<N; i++) {
3835            cur = appendInt(cur, add[i]);
3836        }
3837        return cur;
3838    }
3839
3840    /**
3841     * Returns whether or not a full application can see an instant application.
3842     * <p>
3843     * Currently, there are three cases in which this can occur:
3844     * <ol>
3845     * <li>The calling application is a "special" process. Special processes
3846     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3847     * <li>The calling application has the permission
3848     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3849     * <li>The calling application is the default launcher on the
3850     *     system partition.</li>
3851     * </ol>
3852     */
3853    private boolean canViewInstantApps(int callingUid, int userId) {
3854        if (callingUid < Process.FIRST_APPLICATION_UID) {
3855            return true;
3856        }
3857        if (mContext.checkCallingOrSelfPermission(
3858                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3859            return true;
3860        }
3861        if (mContext.checkCallingOrSelfPermission(
3862                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3863            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3864            if (homeComponent != null
3865                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3866                return true;
3867            }
3868        }
3869        return false;
3870    }
3871
3872    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3873        if (!sUserManager.exists(userId)) return null;
3874        if (ps == null) {
3875            return null;
3876        }
3877        final int callingUid = Binder.getCallingUid();
3878        // Filter out ephemeral app metadata:
3879        //   * The system/shell/root can see metadata for any app
3880        //   * An installed app can see metadata for 1) other installed apps
3881        //     and 2) ephemeral apps that have explicitly interacted with it
3882        //   * Ephemeral apps can only see their own data and exposed installed apps
3883        //   * Holding a signature permission allows seeing instant apps
3884        if (filterAppAccessLPr(ps, callingUid, userId)) {
3885            return null;
3886        }
3887
3888        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3889                && ps.isSystem()) {
3890            flags |= MATCH_ANY_USER;
3891        }
3892
3893        final PackageUserState state = ps.readUserState(userId);
3894        PackageParser.Package p = ps.pkg;
3895        if (p != null) {
3896            final PermissionsState permissionsState = ps.getPermissionsState();
3897
3898            // Compute GIDs only if requested
3899            final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3900                    ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3901            // Compute granted permissions only if package has requested permissions
3902            final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3903                    ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3904
3905            PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3906                    ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3907
3908            if (packageInfo == null) {
3909                return null;
3910            }
3911
3912            packageInfo.packageName = packageInfo.applicationInfo.packageName =
3913                    resolveExternalPackageNameLPr(p);
3914
3915            return packageInfo;
3916        } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3917            PackageInfo pi = new PackageInfo();
3918            pi.packageName = ps.name;
3919            pi.setLongVersionCode(ps.versionCode);
3920            pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3921            pi.firstInstallTime = ps.firstInstallTime;
3922            pi.lastUpdateTime = ps.lastUpdateTime;
3923
3924            ApplicationInfo ai = new ApplicationInfo();
3925            ai.packageName = ps.name;
3926            ai.uid = UserHandle.getUid(userId, ps.appId);
3927            ai.primaryCpuAbi = ps.primaryCpuAbiString;
3928            ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3929            ai.versionCode = ps.versionCode;
3930            ai.flags = ps.pkgFlags;
3931            ai.privateFlags = ps.pkgPrivateFlags;
3932            pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
3933
3934            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3935                    + ps.name + "]. Provides a minimum info.");
3936            return pi;
3937        } else {
3938            return null;
3939        }
3940    }
3941
3942    @Override
3943    public void checkPackageStartable(String packageName, int userId) {
3944        final int callingUid = Binder.getCallingUid();
3945        if (getInstantAppPackageName(callingUid) != null) {
3946            throw new SecurityException("Instant applications don't have access to this method");
3947        }
3948        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3949        synchronized (mPackages) {
3950            final PackageSetting ps = mSettings.mPackages.get(packageName);
3951            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3952                throw new SecurityException("Package " + packageName + " was not found!");
3953            }
3954
3955            if (!ps.getInstalled(userId)) {
3956                throw new SecurityException(
3957                        "Package " + packageName + " was not installed for user " + userId + "!");
3958            }
3959
3960            if (mSafeMode && !ps.isSystem()) {
3961                throw new SecurityException("Package " + packageName + " not a system app!");
3962            }
3963
3964            if (mFrozenPackages.contains(packageName)) {
3965                throw new SecurityException("Package " + packageName + " is currently frozen!");
3966            }
3967
3968            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3969                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3970            }
3971        }
3972    }
3973
3974    @Override
3975    public boolean isPackageAvailable(String packageName, int userId) {
3976        if (!sUserManager.exists(userId)) return false;
3977        final int callingUid = Binder.getCallingUid();
3978        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3979                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3980        synchronized (mPackages) {
3981            PackageParser.Package p = mPackages.get(packageName);
3982            if (p != null) {
3983                final PackageSetting ps = (PackageSetting) p.mExtras;
3984                if (filterAppAccessLPr(ps, callingUid, userId)) {
3985                    return false;
3986                }
3987                if (ps != null) {
3988                    final PackageUserState state = ps.readUserState(userId);
3989                    if (state != null) {
3990                        return PackageParser.isAvailable(state);
3991                    }
3992                }
3993            }
3994        }
3995        return false;
3996    }
3997
3998    @Override
3999    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4000        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4001                flags, Binder.getCallingUid(), userId);
4002    }
4003
4004    @Override
4005    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4006            int flags, int userId) {
4007        return getPackageInfoInternal(versionedPackage.getPackageName(),
4008                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4009    }
4010
4011    /**
4012     * Important: The provided filterCallingUid is used exclusively to filter out packages
4013     * that can be seen based on user state. It's typically the original caller uid prior
4014     * to clearing. Because it can only be provided by trusted code, it's value can be
4015     * trusted and will be used as-is; unlike userId which will be validated by this method.
4016     */
4017    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4018            int flags, int filterCallingUid, int userId) {
4019        if (!sUserManager.exists(userId)) return null;
4020        flags = updateFlagsForPackage(flags, userId, packageName);
4021        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4022                false /* requireFullPermission */, false /* checkShell */, "get package info");
4023
4024        // reader
4025        synchronized (mPackages) {
4026            // Normalize package name to handle renamed packages and static libs
4027            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4028
4029            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4030            if (matchFactoryOnly) {
4031                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4032                if (ps != null) {
4033                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4034                        return null;
4035                    }
4036                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4037                        return null;
4038                    }
4039                    return generatePackageInfo(ps, flags, userId);
4040                }
4041            }
4042
4043            PackageParser.Package p = mPackages.get(packageName);
4044            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4045                return null;
4046            }
4047            if (DEBUG_PACKAGE_INFO)
4048                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4049            if (p != null) {
4050                final PackageSetting ps = (PackageSetting) p.mExtras;
4051                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4052                    return null;
4053                }
4054                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4055                    return null;
4056                }
4057                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4058            }
4059            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4060                final PackageSetting ps = mSettings.mPackages.get(packageName);
4061                if (ps == null) return null;
4062                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4063                    return null;
4064                }
4065                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4066                    return null;
4067                }
4068                return generatePackageInfo(ps, flags, userId);
4069            }
4070        }
4071        return null;
4072    }
4073
4074    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4075        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4076            return true;
4077        }
4078        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4079            return true;
4080        }
4081        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4082            return true;
4083        }
4084        return false;
4085    }
4086
4087    private boolean isComponentVisibleToInstantApp(
4088            @Nullable ComponentName component, @ComponentType int type) {
4089        if (type == TYPE_ACTIVITY) {
4090            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4091            if (activity == null) {
4092                return false;
4093            }
4094            final boolean visibleToInstantApp =
4095                    (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4096            final boolean explicitlyVisibleToInstantApp =
4097                    (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4098            return visibleToInstantApp && explicitlyVisibleToInstantApp;
4099        } else if (type == TYPE_RECEIVER) {
4100            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4101            if (activity == null) {
4102                return false;
4103            }
4104            final boolean visibleToInstantApp =
4105                    (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4106            final boolean explicitlyVisibleToInstantApp =
4107                    (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4108            return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4109        } else if (type == TYPE_SERVICE) {
4110            final PackageParser.Service service = mServices.mServices.get(component);
4111            return service != null
4112                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4113                    : false;
4114        } else if (type == TYPE_PROVIDER) {
4115            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4116            return provider != null
4117                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4118                    : false;
4119        } else if (type == TYPE_UNKNOWN) {
4120            return isComponentVisibleToInstantApp(component);
4121        }
4122        return false;
4123    }
4124
4125    /**
4126     * Returns whether or not access to the application should be filtered.
4127     * <p>
4128     * Access may be limited based upon whether the calling or target applications
4129     * are instant applications.
4130     *
4131     * @see #canAccessInstantApps(int)
4132     */
4133    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4134            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4135        // if we're in an isolated process, get the real calling UID
4136        if (Process.isIsolated(callingUid)) {
4137            callingUid = mIsolatedOwners.get(callingUid);
4138        }
4139        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4140        final boolean callerIsInstantApp = instantAppPkgName != null;
4141        if (ps == null) {
4142            if (callerIsInstantApp) {
4143                // pretend the application exists, but, needs to be filtered
4144                return true;
4145            }
4146            return false;
4147        }
4148        // if the target and caller are the same application, don't filter
4149        if (isCallerSameApp(ps.name, callingUid)) {
4150            return false;
4151        }
4152        if (callerIsInstantApp) {
4153            // both caller and target are both instant, but, different applications, filter
4154            if (ps.getInstantApp(userId)) {
4155                return true;
4156            }
4157            // request for a specific component; if it hasn't been explicitly exposed through
4158            // property or instrumentation target, filter
4159            if (component != null) {
4160                final PackageParser.Instrumentation instrumentation =
4161                        mInstrumentation.get(component);
4162                if (instrumentation != null
4163                        && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4164                    return false;
4165                }
4166                return !isComponentVisibleToInstantApp(component, componentType);
4167            }
4168            // request for application; if no components have been explicitly exposed, filter
4169            return !ps.pkg.visibleToInstantApps;
4170        }
4171        if (ps.getInstantApp(userId)) {
4172            // caller can see all components of all instant applications, don't filter
4173            if (canViewInstantApps(callingUid, userId)) {
4174                return false;
4175            }
4176            // request for a specific instant application component, filter
4177            if (component != null) {
4178                return true;
4179            }
4180            // request for an instant application; if the caller hasn't been granted access, filter
4181            return !mInstantAppRegistry.isInstantAccessGranted(
4182                    userId, UserHandle.getAppId(callingUid), ps.appId);
4183        }
4184        return false;
4185    }
4186
4187    /**
4188     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4189     */
4190    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4191        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4192    }
4193
4194    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4195            int flags) {
4196        // Callers can access only the libs they depend on, otherwise they need to explicitly
4197        // ask for the shared libraries given the caller is allowed to access all static libs.
4198        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4199            // System/shell/root get to see all static libs
4200            final int appId = UserHandle.getAppId(uid);
4201            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4202                    || appId == Process.ROOT_UID) {
4203                return false;
4204            }
4205        }
4206
4207        // No package means no static lib as it is always on internal storage
4208        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4209            return false;
4210        }
4211
4212        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4213                ps.pkg.staticSharedLibVersion);
4214        if (libEntry == null) {
4215            return false;
4216        }
4217
4218        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4219        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4220        if (uidPackageNames == null) {
4221            return true;
4222        }
4223
4224        for (String uidPackageName : uidPackageNames) {
4225            if (ps.name.equals(uidPackageName)) {
4226                return false;
4227            }
4228            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4229            if (uidPs != null) {
4230                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4231                        libEntry.info.getName());
4232                if (index < 0) {
4233                    continue;
4234                }
4235                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4236                    return false;
4237                }
4238            }
4239        }
4240        return true;
4241    }
4242
4243    @Override
4244    public String[] currentToCanonicalPackageNames(String[] names) {
4245        final int callingUid = Binder.getCallingUid();
4246        if (getInstantAppPackageName(callingUid) != null) {
4247            return names;
4248        }
4249        final String[] out = new String[names.length];
4250        // reader
4251        synchronized (mPackages) {
4252            final int callingUserId = UserHandle.getUserId(callingUid);
4253            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4254            for (int i=names.length-1; i>=0; i--) {
4255                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4256                boolean translateName = false;
4257                if (ps != null && ps.realName != null) {
4258                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4259                    translateName = !targetIsInstantApp
4260                            || canViewInstantApps
4261                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4262                                    UserHandle.getAppId(callingUid), ps.appId);
4263                }
4264                out[i] = translateName ? ps.realName : names[i];
4265            }
4266        }
4267        return out;
4268    }
4269
4270    @Override
4271    public String[] canonicalToCurrentPackageNames(String[] names) {
4272        final int callingUid = Binder.getCallingUid();
4273        if (getInstantAppPackageName(callingUid) != null) {
4274            return names;
4275        }
4276        final String[] out = new String[names.length];
4277        // reader
4278        synchronized (mPackages) {
4279            final int callingUserId = UserHandle.getUserId(callingUid);
4280            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4281            for (int i=names.length-1; i>=0; i--) {
4282                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4283                boolean translateName = false;
4284                if (cur != null) {
4285                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4286                    final boolean targetIsInstantApp =
4287                            ps != null && ps.getInstantApp(callingUserId);
4288                    translateName = !targetIsInstantApp
4289                            || canViewInstantApps
4290                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4291                                    UserHandle.getAppId(callingUid), ps.appId);
4292                }
4293                out[i] = translateName ? cur : names[i];
4294            }
4295        }
4296        return out;
4297    }
4298
4299    @Override
4300    public int getPackageUid(String packageName, int flags, int userId) {
4301        if (!sUserManager.exists(userId)) return -1;
4302        final int callingUid = Binder.getCallingUid();
4303        flags = updateFlagsForPackage(flags, userId, packageName);
4304        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4305                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4306
4307        // reader
4308        synchronized (mPackages) {
4309            final PackageParser.Package p = mPackages.get(packageName);
4310            if (p != null && p.isMatch(flags)) {
4311                PackageSetting ps = (PackageSetting) p.mExtras;
4312                if (filterAppAccessLPr(ps, callingUid, userId)) {
4313                    return -1;
4314                }
4315                return UserHandle.getUid(userId, p.applicationInfo.uid);
4316            }
4317            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4318                final PackageSetting ps = mSettings.mPackages.get(packageName);
4319                if (ps != null && ps.isMatch(flags)
4320                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4321                    return UserHandle.getUid(userId, ps.appId);
4322                }
4323            }
4324        }
4325
4326        return -1;
4327    }
4328
4329    @Override
4330    public int[] getPackageGids(String packageName, int flags, int userId) {
4331        if (!sUserManager.exists(userId)) return null;
4332        final int callingUid = Binder.getCallingUid();
4333        flags = updateFlagsForPackage(flags, userId, packageName);
4334        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4335                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4336
4337        // reader
4338        synchronized (mPackages) {
4339            final PackageParser.Package p = mPackages.get(packageName);
4340            if (p != null && p.isMatch(flags)) {
4341                PackageSetting ps = (PackageSetting) p.mExtras;
4342                if (filterAppAccessLPr(ps, callingUid, userId)) {
4343                    return null;
4344                }
4345                // TODO: Shouldn't this be checking for package installed state for userId and
4346                // return null?
4347                return ps.getPermissionsState().computeGids(userId);
4348            }
4349            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4350                final PackageSetting ps = mSettings.mPackages.get(packageName);
4351                if (ps != null && ps.isMatch(flags)
4352                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4353                    return ps.getPermissionsState().computeGids(userId);
4354                }
4355            }
4356        }
4357
4358        return null;
4359    }
4360
4361    @Override
4362    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4363        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4364    }
4365
4366    @Override
4367    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4368            int flags) {
4369        final List<PermissionInfo> permissionList =
4370                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4371        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4372    }
4373
4374    @Override
4375    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4376        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4377    }
4378
4379    @Override
4380    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4381        final List<PermissionGroupInfo> permissionList =
4382                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4383        return (permissionList == null)
4384                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4385    }
4386
4387    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4388            int filterCallingUid, int userId) {
4389        if (!sUserManager.exists(userId)) return null;
4390        PackageSetting ps = mSettings.mPackages.get(packageName);
4391        if (ps != null) {
4392            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4393                return null;
4394            }
4395            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4396                return null;
4397            }
4398            if (ps.pkg == null) {
4399                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4400                if (pInfo != null) {
4401                    return pInfo.applicationInfo;
4402                }
4403                return null;
4404            }
4405            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4406                    ps.readUserState(userId), userId);
4407            if (ai != null) {
4408                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4409            }
4410            return ai;
4411        }
4412        return null;
4413    }
4414
4415    @Override
4416    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4417        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4418    }
4419
4420    /**
4421     * Important: The provided filterCallingUid is used exclusively to filter out applications
4422     * that can be seen based on user state. It's typically the original caller uid prior
4423     * to clearing. Because it can only be provided by trusted code, it's value can be
4424     * trusted and will be used as-is; unlike userId which will be validated by this method.
4425     */
4426    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4427            int filterCallingUid, int userId) {
4428        if (!sUserManager.exists(userId)) return null;
4429        flags = updateFlagsForApplication(flags, userId, packageName);
4430        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4431                false /* requireFullPermission */, false /* checkShell */, "get application info");
4432
4433        // writer
4434        synchronized (mPackages) {
4435            // Normalize package name to handle renamed packages and static libs
4436            packageName = resolveInternalPackageNameLPr(packageName,
4437                    PackageManager.VERSION_CODE_HIGHEST);
4438
4439            PackageParser.Package p = mPackages.get(packageName);
4440            if (DEBUG_PACKAGE_INFO) Log.v(
4441                    TAG, "getApplicationInfo " + packageName
4442                    + ": " + p);
4443            if (p != null) {
4444                PackageSetting ps = mSettings.mPackages.get(packageName);
4445                if (ps == null) return null;
4446                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4447                    return null;
4448                }
4449                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4450                    return null;
4451                }
4452                // Note: isEnabledLP() does not apply here - always return info
4453                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4454                        p, flags, ps.readUserState(userId), userId);
4455                if (ai != null) {
4456                    ai.packageName = resolveExternalPackageNameLPr(p);
4457                }
4458                return ai;
4459            }
4460            if ("android".equals(packageName)||"system".equals(packageName)) {
4461                return mAndroidApplication;
4462            }
4463            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4464                // Already generates the external package name
4465                return generateApplicationInfoFromSettingsLPw(packageName,
4466                        flags, filterCallingUid, userId);
4467            }
4468        }
4469        return null;
4470    }
4471
4472    private String normalizePackageNameLPr(String packageName) {
4473        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4474        return normalizedPackageName != null ? normalizedPackageName : packageName;
4475    }
4476
4477    @Override
4478    public void deletePreloadsFileCache() {
4479        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4480            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4481        }
4482        File dir = Environment.getDataPreloadsFileCacheDirectory();
4483        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4484        FileUtils.deleteContents(dir);
4485    }
4486
4487    @Override
4488    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4489            final int storageFlags, final IPackageDataObserver observer) {
4490        mContext.enforceCallingOrSelfPermission(
4491                android.Manifest.permission.CLEAR_APP_CACHE, null);
4492        mHandler.post(() -> {
4493            boolean success = false;
4494            try {
4495                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4496                success = true;
4497            } catch (IOException e) {
4498                Slog.w(TAG, e);
4499            }
4500            if (observer != null) {
4501                try {
4502                    observer.onRemoveCompleted(null, success);
4503                } catch (RemoteException e) {
4504                    Slog.w(TAG, e);
4505                }
4506            }
4507        });
4508    }
4509
4510    @Override
4511    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4512            final int storageFlags, final IntentSender pi) {
4513        mContext.enforceCallingOrSelfPermission(
4514                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4515        mHandler.post(() -> {
4516            boolean success = false;
4517            try {
4518                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4519                success = true;
4520            } catch (IOException e) {
4521                Slog.w(TAG, e);
4522            }
4523            if (pi != null) {
4524                try {
4525                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4526                } catch (SendIntentException e) {
4527                    Slog.w(TAG, e);
4528                }
4529            }
4530        });
4531    }
4532
4533    /**
4534     * Blocking call to clear various types of cached data across the system
4535     * until the requested bytes are available.
4536     */
4537    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4538        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4539        final File file = storage.findPathForUuid(volumeUuid);
4540        if (file.getUsableSpace() >= bytes) return;
4541
4542        if (ENABLE_FREE_CACHE_V2) {
4543            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4544                    volumeUuid);
4545            final boolean aggressive = (storageFlags
4546                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4547            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4548
4549            // 1. Pre-flight to determine if we have any chance to succeed
4550            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4551            if (internalVolume && (aggressive || SystemProperties
4552                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4553                deletePreloadsFileCache();
4554                if (file.getUsableSpace() >= bytes) return;
4555            }
4556
4557            // 3. Consider parsed APK data (aggressive only)
4558            if (internalVolume && aggressive) {
4559                FileUtils.deleteContents(mCacheDir);
4560                if (file.getUsableSpace() >= bytes) return;
4561            }
4562
4563            // 4. Consider cached app data (above quotas)
4564            try {
4565                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4566                        Installer.FLAG_FREE_CACHE_V2);
4567            } catch (InstallerException ignored) {
4568            }
4569            if (file.getUsableSpace() >= bytes) return;
4570
4571            // 5. Consider shared libraries with refcount=0 and age>min cache period
4572            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4573                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4574                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4575                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4576                return;
4577            }
4578
4579            // 6. Consider dexopt output (aggressive only)
4580            // TODO: Implement
4581
4582            // 7. Consider installed instant apps unused longer than min cache period
4583            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4584                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4585                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4586                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4587                return;
4588            }
4589
4590            // 8. Consider cached app data (below quotas)
4591            try {
4592                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4593                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4594            } catch (InstallerException ignored) {
4595            }
4596            if (file.getUsableSpace() >= bytes) return;
4597
4598            // 9. Consider DropBox entries
4599            // TODO: Implement
4600
4601            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4602            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4603                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4604                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4605                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4606                return;
4607            }
4608        } else {
4609            try {
4610                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4611            } catch (InstallerException ignored) {
4612            }
4613            if (file.getUsableSpace() >= bytes) return;
4614        }
4615
4616        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4617    }
4618
4619    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4620            throws IOException {
4621        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4622        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4623
4624        List<VersionedPackage> packagesToDelete = null;
4625        final long now = System.currentTimeMillis();
4626
4627        synchronized (mPackages) {
4628            final int[] allUsers = sUserManager.getUserIds();
4629            final int libCount = mSharedLibraries.size();
4630            for (int i = 0; i < libCount; i++) {
4631                final LongSparseArray<SharedLibraryEntry> versionedLib
4632                        = mSharedLibraries.valueAt(i);
4633                if (versionedLib == null) {
4634                    continue;
4635                }
4636                final int versionCount = versionedLib.size();
4637                for (int j = 0; j < versionCount; j++) {
4638                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4639                    // Skip packages that are not static shared libs.
4640                    if (!libInfo.isStatic()) {
4641                        break;
4642                    }
4643                    // Important: We skip static shared libs used for some user since
4644                    // in such a case we need to keep the APK on the device. The check for
4645                    // a lib being used for any user is performed by the uninstall call.
4646                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4647                    // Resolve the package name - we use synthetic package names internally
4648                    final String internalPackageName = resolveInternalPackageNameLPr(
4649                            declaringPackage.getPackageName(),
4650                            declaringPackage.getLongVersionCode());
4651                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4652                    // Skip unused static shared libs cached less than the min period
4653                    // to prevent pruning a lib needed by a subsequently installed package.
4654                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4655                        continue;
4656                    }
4657                    if (packagesToDelete == null) {
4658                        packagesToDelete = new ArrayList<>();
4659                    }
4660                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4661                            declaringPackage.getLongVersionCode()));
4662                }
4663            }
4664        }
4665
4666        if (packagesToDelete != null) {
4667            final int packageCount = packagesToDelete.size();
4668            for (int i = 0; i < packageCount; i++) {
4669                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4670                // Delete the package synchronously (will fail of the lib used for any user).
4671                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4672                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4673                                == PackageManager.DELETE_SUCCEEDED) {
4674                    if (volume.getUsableSpace() >= neededSpace) {
4675                        return true;
4676                    }
4677                }
4678            }
4679        }
4680
4681        return false;
4682    }
4683
4684    /**
4685     * Update given flags based on encryption status of current user.
4686     */
4687    private int updateFlags(int flags, int userId) {
4688        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4689                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4690            // Caller expressed an explicit opinion about what encryption
4691            // aware/unaware components they want to see, so fall through and
4692            // give them what they want
4693        } else {
4694            // Caller expressed no opinion, so match based on user state
4695            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4696                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4697            } else {
4698                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4699            }
4700        }
4701        return flags;
4702    }
4703
4704    private UserManagerInternal getUserManagerInternal() {
4705        if (mUserManagerInternal == null) {
4706            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4707        }
4708        return mUserManagerInternal;
4709    }
4710
4711    private ActivityManagerInternal getActivityManagerInternal() {
4712        if (mActivityManagerInternal == null) {
4713            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4714        }
4715        return mActivityManagerInternal;
4716    }
4717
4718
4719    private DeviceIdleController.LocalService getDeviceIdleController() {
4720        if (mDeviceIdleController == null) {
4721            mDeviceIdleController =
4722                    LocalServices.getService(DeviceIdleController.LocalService.class);
4723        }
4724        return mDeviceIdleController;
4725    }
4726
4727    /**
4728     * Update given flags when being used to request {@link PackageInfo}.
4729     */
4730    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4731        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4732        boolean triaged = true;
4733        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4734                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4735            // Caller is asking for component details, so they'd better be
4736            // asking for specific encryption matching behavior, or be triaged
4737            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4738                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4739                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4740                triaged = false;
4741            }
4742        }
4743        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4744                | PackageManager.MATCH_SYSTEM_ONLY
4745                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4746            triaged = false;
4747        }
4748        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4749            mPermissionManager.enforceCrossUserPermission(
4750                    Binder.getCallingUid(), userId, false, false,
4751                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4752                    + Debug.getCallers(5));
4753        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4754                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4755            // If the caller wants all packages and has a restricted profile associated with it,
4756            // then match all users. This is to make sure that launchers that need to access work
4757            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4758            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4759            flags |= PackageManager.MATCH_ANY_USER;
4760        }
4761        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4762            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4763                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4764        }
4765        return updateFlags(flags, userId);
4766    }
4767
4768    /**
4769     * Update given flags when being used to request {@link ApplicationInfo}.
4770     */
4771    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4772        return updateFlagsForPackage(flags, userId, cookie);
4773    }
4774
4775    /**
4776     * Update given flags when being used to request {@link ComponentInfo}.
4777     */
4778    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4779        if (cookie instanceof Intent) {
4780            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4781                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4782            }
4783        }
4784
4785        boolean triaged = true;
4786        // Caller is asking for component details, so they'd better be
4787        // asking for specific encryption matching behavior, or be triaged
4788        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4789                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4790                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4791            triaged = false;
4792        }
4793        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4794            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4795                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4796        }
4797
4798        return updateFlags(flags, userId);
4799    }
4800
4801    /**
4802     * Update given intent when being used to request {@link ResolveInfo}.
4803     */
4804    private Intent updateIntentForResolve(Intent intent) {
4805        if (intent.getSelector() != null) {
4806            intent = intent.getSelector();
4807        }
4808        if (DEBUG_PREFERRED) {
4809            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4810        }
4811        return intent;
4812    }
4813
4814    /**
4815     * Update given flags when being used to request {@link ResolveInfo}.
4816     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4817     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4818     * flag set. However, this flag is only honoured in three circumstances:
4819     * <ul>
4820     * <li>when called from a system process</li>
4821     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4822     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4823     * action and a {@code android.intent.category.BROWSABLE} category</li>
4824     * </ul>
4825     */
4826    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4827        return updateFlagsForResolve(flags, userId, intent, callingUid,
4828                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4829    }
4830    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4831            boolean wantInstantApps) {
4832        return updateFlagsForResolve(flags, userId, intent, callingUid,
4833                wantInstantApps, false /*onlyExposedExplicitly*/);
4834    }
4835    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4836            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4837        // Safe mode means we shouldn't match any third-party components
4838        if (mSafeMode) {
4839            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4840        }
4841        if (getInstantAppPackageName(callingUid) != null) {
4842            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4843            if (onlyExposedExplicitly) {
4844                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4845            }
4846            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4847            flags |= PackageManager.MATCH_INSTANT;
4848        } else {
4849            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4850            final boolean allowMatchInstant = wantInstantApps
4851                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4852            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4853                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4854            if (!allowMatchInstant) {
4855                flags &= ~PackageManager.MATCH_INSTANT;
4856            }
4857        }
4858        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4859    }
4860
4861    @Override
4862    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4863        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4864    }
4865
4866    /**
4867     * Important: The provided filterCallingUid is used exclusively to filter out activities
4868     * that can be seen based on user state. It's typically the original caller uid prior
4869     * to clearing. Because it can only be provided by trusted code, it's value can be
4870     * trusted and will be used as-is; unlike userId which will be validated by this method.
4871     */
4872    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4873            int filterCallingUid, int userId) {
4874        if (!sUserManager.exists(userId)) return null;
4875        flags = updateFlagsForComponent(flags, userId, component);
4876
4877        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4878            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4879                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
4880        }
4881
4882        synchronized (mPackages) {
4883            PackageParser.Activity a = mActivities.mActivities.get(component);
4884
4885            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4886            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4887                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4888                if (ps == null) return null;
4889                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4890                    return null;
4891                }
4892                return PackageParser.generateActivityInfo(
4893                        a, flags, ps.readUserState(userId), userId);
4894            }
4895            if (mResolveComponentName.equals(component)) {
4896                return PackageParser.generateActivityInfo(
4897                        mResolveActivity, flags, new PackageUserState(), userId);
4898            }
4899        }
4900        return null;
4901    }
4902
4903    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4904        if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4905            return false;
4906        }
4907        final long token = Binder.clearCallingIdentity();
4908        try {
4909            final int callingUserId = UserHandle.getUserId(callingUid);
4910            if (ActivityManager.getCurrentUser() != callingUserId) {
4911                return false;
4912            }
4913            return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4914        } finally {
4915            Binder.restoreCallingIdentity(token);
4916        }
4917    }
4918
4919    @Override
4920    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4921            String resolvedType) {
4922        synchronized (mPackages) {
4923            if (component.equals(mResolveComponentName)) {
4924                // The resolver supports EVERYTHING!
4925                return true;
4926            }
4927            final int callingUid = Binder.getCallingUid();
4928            final int callingUserId = UserHandle.getUserId(callingUid);
4929            PackageParser.Activity a = mActivities.mActivities.get(component);
4930            if (a == null) {
4931                return false;
4932            }
4933            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4934            if (ps == null) {
4935                return false;
4936            }
4937            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4938                return false;
4939            }
4940            for (int i=0; i<a.intents.size(); i++) {
4941                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4942                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4943                    return true;
4944                }
4945            }
4946            return false;
4947        }
4948    }
4949
4950    @Override
4951    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4952        if (!sUserManager.exists(userId)) return null;
4953        final int callingUid = Binder.getCallingUid();
4954        flags = updateFlagsForComponent(flags, userId, component);
4955        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4956                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4957        synchronized (mPackages) {
4958            PackageParser.Activity a = mReceivers.mActivities.get(component);
4959            if (DEBUG_PACKAGE_INFO) Log.v(
4960                TAG, "getReceiverInfo " + component + ": " + a);
4961            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4962                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4963                if (ps == null) return null;
4964                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4965                    return null;
4966                }
4967                return PackageParser.generateActivityInfo(
4968                        a, flags, ps.readUserState(userId), userId);
4969            }
4970        }
4971        return null;
4972    }
4973
4974    @Override
4975    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4976            int flags, int userId) {
4977        if (!sUserManager.exists(userId)) return null;
4978        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4979        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4980            return null;
4981        }
4982
4983        flags = updateFlagsForPackage(flags, userId, null);
4984
4985        final boolean canSeeStaticLibraries =
4986                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4987                        == PERMISSION_GRANTED
4988                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4989                        == PERMISSION_GRANTED
4990                || canRequestPackageInstallsInternal(packageName,
4991                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4992                        false  /* throwIfPermNotDeclared*/)
4993                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4994                        == PERMISSION_GRANTED;
4995
4996        synchronized (mPackages) {
4997            List<SharedLibraryInfo> result = null;
4998
4999            final int libCount = mSharedLibraries.size();
5000            for (int i = 0; i < libCount; i++) {
5001                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5002                if (versionedLib == null) {
5003                    continue;
5004                }
5005
5006                final int versionCount = versionedLib.size();
5007                for (int j = 0; j < versionCount; j++) {
5008                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5009                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
5010                        break;
5011                    }
5012                    final long identity = Binder.clearCallingIdentity();
5013                    try {
5014                        PackageInfo packageInfo = getPackageInfoVersioned(
5015                                libInfo.getDeclaringPackage(), flags
5016                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5017                        if (packageInfo == null) {
5018                            continue;
5019                        }
5020                    } finally {
5021                        Binder.restoreCallingIdentity(identity);
5022                    }
5023
5024                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5025                            libInfo.getLongVersion(), libInfo.getType(),
5026                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5027                            flags, userId));
5028
5029                    if (result == null) {
5030                        result = new ArrayList<>();
5031                    }
5032                    result.add(resLibInfo);
5033                }
5034            }
5035
5036            return result != null ? new ParceledListSlice<>(result) : null;
5037        }
5038    }
5039
5040    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5041            SharedLibraryInfo libInfo, int flags, int userId) {
5042        List<VersionedPackage> versionedPackages = null;
5043        final int packageCount = mSettings.mPackages.size();
5044        for (int i = 0; i < packageCount; i++) {
5045            PackageSetting ps = mSettings.mPackages.valueAt(i);
5046
5047            if (ps == null) {
5048                continue;
5049            }
5050
5051            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5052                continue;
5053            }
5054
5055            final String libName = libInfo.getName();
5056            if (libInfo.isStatic()) {
5057                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5058                if (libIdx < 0) {
5059                    continue;
5060                }
5061                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5062                    continue;
5063                }
5064                if (versionedPackages == null) {
5065                    versionedPackages = new ArrayList<>();
5066                }
5067                // If the dependent is a static shared lib, use the public package name
5068                String dependentPackageName = ps.name;
5069                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5070                    dependentPackageName = ps.pkg.manifestPackageName;
5071                }
5072                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5073            } else if (ps.pkg != null) {
5074                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5075                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5076                    if (versionedPackages == null) {
5077                        versionedPackages = new ArrayList<>();
5078                    }
5079                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5080                }
5081            }
5082        }
5083
5084        return versionedPackages;
5085    }
5086
5087    @Override
5088    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5089        if (!sUserManager.exists(userId)) return null;
5090        final int callingUid = Binder.getCallingUid();
5091        flags = updateFlagsForComponent(flags, userId, component);
5092        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5093                false /* requireFullPermission */, false /* checkShell */, "get service info");
5094        synchronized (mPackages) {
5095            PackageParser.Service s = mServices.mServices.get(component);
5096            if (DEBUG_PACKAGE_INFO) Log.v(
5097                TAG, "getServiceInfo " + component + ": " + s);
5098            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5099                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5100                if (ps == null) return null;
5101                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5102                    return null;
5103                }
5104                return PackageParser.generateServiceInfo(
5105                        s, flags, ps.readUserState(userId), userId);
5106            }
5107        }
5108        return null;
5109    }
5110
5111    @Override
5112    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5113        if (!sUserManager.exists(userId)) return null;
5114        final int callingUid = Binder.getCallingUid();
5115        flags = updateFlagsForComponent(flags, userId, component);
5116        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5117                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5118        synchronized (mPackages) {
5119            PackageParser.Provider p = mProviders.mProviders.get(component);
5120            if (DEBUG_PACKAGE_INFO) Log.v(
5121                TAG, "getProviderInfo " + component + ": " + p);
5122            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5123                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5124                if (ps == null) return null;
5125                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5126                    return null;
5127                }
5128                return PackageParser.generateProviderInfo(
5129                        p, flags, ps.readUserState(userId), userId);
5130            }
5131        }
5132        return null;
5133    }
5134
5135    @Override
5136    public String[] getSystemSharedLibraryNames() {
5137        // allow instant applications
5138        synchronized (mPackages) {
5139            Set<String> libs = null;
5140            final int libCount = mSharedLibraries.size();
5141            for (int i = 0; i < libCount; i++) {
5142                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5143                if (versionedLib == null) {
5144                    continue;
5145                }
5146                final int versionCount = versionedLib.size();
5147                for (int j = 0; j < versionCount; j++) {
5148                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5149                    if (!libEntry.info.isStatic()) {
5150                        if (libs == null) {
5151                            libs = new ArraySet<>();
5152                        }
5153                        libs.add(libEntry.info.getName());
5154                        break;
5155                    }
5156                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5157                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5158                            UserHandle.getUserId(Binder.getCallingUid()),
5159                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5160                        if (libs == null) {
5161                            libs = new ArraySet<>();
5162                        }
5163                        libs.add(libEntry.info.getName());
5164                        break;
5165                    }
5166                }
5167            }
5168
5169            if (libs != null) {
5170                String[] libsArray = new String[libs.size()];
5171                libs.toArray(libsArray);
5172                return libsArray;
5173            }
5174
5175            return null;
5176        }
5177    }
5178
5179    @Override
5180    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5181        // allow instant applications
5182        synchronized (mPackages) {
5183            return mServicesSystemSharedLibraryPackageName;
5184        }
5185    }
5186
5187    @Override
5188    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5189        // allow instant applications
5190        synchronized (mPackages) {
5191            return mSharedSystemSharedLibraryPackageName;
5192        }
5193    }
5194
5195    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5196        for (int i = userList.length - 1; i >= 0; --i) {
5197            final int userId = userList[i];
5198            // don't add instant app to the list of updates
5199            if (pkgSetting.getInstantApp(userId)) {
5200                continue;
5201            }
5202            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5203            if (changedPackages == null) {
5204                changedPackages = new SparseArray<>();
5205                mChangedPackages.put(userId, changedPackages);
5206            }
5207            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5208            if (sequenceNumbers == null) {
5209                sequenceNumbers = new HashMap<>();
5210                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5211            }
5212            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5213            if (sequenceNumber != null) {
5214                changedPackages.remove(sequenceNumber);
5215            }
5216            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5217            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5218        }
5219        mChangedPackagesSequenceNumber++;
5220    }
5221
5222    @Override
5223    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5224        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5225            return null;
5226        }
5227        synchronized (mPackages) {
5228            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5229                return null;
5230            }
5231            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5232            if (changedPackages == null) {
5233                return null;
5234            }
5235            final List<String> packageNames =
5236                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5237            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5238                final String packageName = changedPackages.get(i);
5239                if (packageName != null) {
5240                    packageNames.add(packageName);
5241                }
5242            }
5243            return packageNames.isEmpty()
5244                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5245        }
5246    }
5247
5248    @Override
5249    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5250        // allow instant applications
5251        ArrayList<FeatureInfo> res;
5252        synchronized (mAvailableFeatures) {
5253            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5254            res.addAll(mAvailableFeatures.values());
5255        }
5256        final FeatureInfo fi = new FeatureInfo();
5257        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5258                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5259        res.add(fi);
5260
5261        return new ParceledListSlice<>(res);
5262    }
5263
5264    @Override
5265    public boolean hasSystemFeature(String name, int version) {
5266        // allow instant applications
5267        synchronized (mAvailableFeatures) {
5268            final FeatureInfo feat = mAvailableFeatures.get(name);
5269            if (feat == null) {
5270                return false;
5271            } else {
5272                return feat.version >= version;
5273            }
5274        }
5275    }
5276
5277    @Override
5278    public int checkPermission(String permName, String pkgName, int userId) {
5279        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5280    }
5281
5282    @Override
5283    public int checkUidPermission(String permName, int uid) {
5284        synchronized (mPackages) {
5285            final String[] packageNames = getPackagesForUid(uid);
5286            final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
5287                    ? mPackages.get(packageNames[0])
5288                    : null;
5289            return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5290        }
5291    }
5292
5293    @Override
5294    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5295        if (UserHandle.getCallingUserId() != userId) {
5296            mContext.enforceCallingPermission(
5297                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5298                    "isPermissionRevokedByPolicy for user " + userId);
5299        }
5300
5301        if (checkPermission(permission, packageName, userId)
5302                == PackageManager.PERMISSION_GRANTED) {
5303            return false;
5304        }
5305
5306        final int callingUid = Binder.getCallingUid();
5307        if (getInstantAppPackageName(callingUid) != null) {
5308            if (!isCallerSameApp(packageName, callingUid)) {
5309                return false;
5310            }
5311        } else {
5312            if (isInstantApp(packageName, userId)) {
5313                return false;
5314            }
5315        }
5316
5317        final long identity = Binder.clearCallingIdentity();
5318        try {
5319            final int flags = getPermissionFlags(permission, packageName, userId);
5320            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5321        } finally {
5322            Binder.restoreCallingIdentity(identity);
5323        }
5324    }
5325
5326    @Override
5327    public String getPermissionControllerPackageName() {
5328        synchronized (mPackages) {
5329            return mRequiredInstallerPackage;
5330        }
5331    }
5332
5333    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5334        return mPermissionManager.addDynamicPermission(
5335                info, async, getCallingUid(), new PermissionCallback() {
5336                    @Override
5337                    public void onPermissionChanged() {
5338                        if (!async) {
5339                            mSettings.writeLPr();
5340                        } else {
5341                            scheduleWriteSettingsLocked();
5342                        }
5343                    }
5344                });
5345    }
5346
5347    @Override
5348    public boolean addPermission(PermissionInfo info) {
5349        synchronized (mPackages) {
5350            return addDynamicPermission(info, false);
5351        }
5352    }
5353
5354    @Override
5355    public boolean addPermissionAsync(PermissionInfo info) {
5356        synchronized (mPackages) {
5357            return addDynamicPermission(info, true);
5358        }
5359    }
5360
5361    @Override
5362    public void removePermission(String permName) {
5363        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5364    }
5365
5366    @Override
5367    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5368        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5369                getCallingUid(), userId, mPermissionCallback);
5370    }
5371
5372    @Override
5373    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5374        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5375                getCallingUid(), userId, mPermissionCallback);
5376    }
5377
5378    @Override
5379    public void resetRuntimePermissions() {
5380        mContext.enforceCallingOrSelfPermission(
5381                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5382                "revokeRuntimePermission");
5383
5384        int callingUid = Binder.getCallingUid();
5385        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5386            mContext.enforceCallingOrSelfPermission(
5387                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5388                    "resetRuntimePermissions");
5389        }
5390
5391        synchronized (mPackages) {
5392            mPermissionManager.updateAllPermissions(
5393                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5394                    mPermissionCallback);
5395            for (int userId : UserManagerService.getInstance().getUserIds()) {
5396                final int packageCount = mPackages.size();
5397                for (int i = 0; i < packageCount; i++) {
5398                    PackageParser.Package pkg = mPackages.valueAt(i);
5399                    if (!(pkg.mExtras instanceof PackageSetting)) {
5400                        continue;
5401                    }
5402                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5403                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5404                }
5405            }
5406        }
5407    }
5408
5409    @Override
5410    public int getPermissionFlags(String permName, String packageName, int userId) {
5411        return mPermissionManager.getPermissionFlags(
5412                permName, packageName, getCallingUid(), userId);
5413    }
5414
5415    @Override
5416    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5417            int flagValues, int userId) {
5418        mPermissionManager.updatePermissionFlags(
5419                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5420                mPermissionCallback);
5421    }
5422
5423    /**
5424     * Update the permission flags for all packages and runtime permissions of a user in order
5425     * to allow device or profile owner to remove POLICY_FIXED.
5426     */
5427    @Override
5428    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5429        synchronized (mPackages) {
5430            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5431                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5432                    mPermissionCallback);
5433            if (changed) {
5434                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5435            }
5436        }
5437    }
5438
5439    @Override
5440    public boolean shouldShowRequestPermissionRationale(String permissionName,
5441            String packageName, int userId) {
5442        if (UserHandle.getCallingUserId() != userId) {
5443            mContext.enforceCallingPermission(
5444                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5445                    "canShowRequestPermissionRationale for user " + userId);
5446        }
5447
5448        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5449        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5450            return false;
5451        }
5452
5453        if (checkPermission(permissionName, packageName, userId)
5454                == PackageManager.PERMISSION_GRANTED) {
5455            return false;
5456        }
5457
5458        final int flags;
5459
5460        final long identity = Binder.clearCallingIdentity();
5461        try {
5462            flags = getPermissionFlags(permissionName,
5463                    packageName, userId);
5464        } finally {
5465            Binder.restoreCallingIdentity(identity);
5466        }
5467
5468        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5469                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5470                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5471
5472        if ((flags & fixedFlags) != 0) {
5473            return false;
5474        }
5475
5476        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5477    }
5478
5479    @Override
5480    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5481        mContext.enforceCallingOrSelfPermission(
5482                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5483                "addOnPermissionsChangeListener");
5484
5485        synchronized (mPackages) {
5486            mOnPermissionChangeListeners.addListenerLocked(listener);
5487        }
5488    }
5489
5490    @Override
5491    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5492        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5493            throw new SecurityException("Instant applications don't have access to this method");
5494        }
5495        synchronized (mPackages) {
5496            mOnPermissionChangeListeners.removeListenerLocked(listener);
5497        }
5498    }
5499
5500    @Override
5501    public boolean isProtectedBroadcast(String actionName) {
5502        // allow instant applications
5503        synchronized (mProtectedBroadcasts) {
5504            if (mProtectedBroadcasts.contains(actionName)) {
5505                return true;
5506            } else if (actionName != null) {
5507                // TODO: remove these terrible hacks
5508                if (actionName.startsWith("android.net.netmon.lingerExpired")
5509                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5510                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5511                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5512                    return true;
5513                }
5514            }
5515        }
5516        return false;
5517    }
5518
5519    @Override
5520    public int checkSignatures(String pkg1, String pkg2) {
5521        synchronized (mPackages) {
5522            final PackageParser.Package p1 = mPackages.get(pkg1);
5523            final PackageParser.Package p2 = mPackages.get(pkg2);
5524            if (p1 == null || p1.mExtras == null
5525                    || p2 == null || p2.mExtras == null) {
5526                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5527            }
5528            final int callingUid = Binder.getCallingUid();
5529            final int callingUserId = UserHandle.getUserId(callingUid);
5530            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5531            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5532            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5533                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5534                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5535            }
5536            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5537        }
5538    }
5539
5540    @Override
5541    public int checkUidSignatures(int uid1, int uid2) {
5542        final int callingUid = Binder.getCallingUid();
5543        final int callingUserId = UserHandle.getUserId(callingUid);
5544        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5545        // Map to base uids.
5546        uid1 = UserHandle.getAppId(uid1);
5547        uid2 = UserHandle.getAppId(uid2);
5548        // reader
5549        synchronized (mPackages) {
5550            Signature[] s1;
5551            Signature[] s2;
5552            Object obj = mSettings.getUserIdLPr(uid1);
5553            if (obj != null) {
5554                if (obj instanceof SharedUserSetting) {
5555                    if (isCallerInstantApp) {
5556                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5557                    }
5558                    s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5559                } else if (obj instanceof PackageSetting) {
5560                    final PackageSetting ps = (PackageSetting) obj;
5561                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5562                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5563                    }
5564                    s1 = ps.signatures.mSigningDetails.signatures;
5565                } else {
5566                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5567                }
5568            } else {
5569                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5570            }
5571            obj = mSettings.getUserIdLPr(uid2);
5572            if (obj != null) {
5573                if (obj instanceof SharedUserSetting) {
5574                    if (isCallerInstantApp) {
5575                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5576                    }
5577                    s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5578                } else if (obj instanceof PackageSetting) {
5579                    final PackageSetting ps = (PackageSetting) obj;
5580                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5581                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5582                    }
5583                    s2 = ps.signatures.mSigningDetails.signatures;
5584                } else {
5585                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5586                }
5587            } else {
5588                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5589            }
5590            return compareSignatures(s1, s2);
5591        }
5592    }
5593
5594    @Override
5595    public boolean hasSigningCertificate(
5596            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5597
5598        synchronized (mPackages) {
5599            final PackageParser.Package p = mPackages.get(packageName);
5600            if (p == null || p.mExtras == null) {
5601                return false;
5602            }
5603            final int callingUid = Binder.getCallingUid();
5604            final int callingUserId = UserHandle.getUserId(callingUid);
5605            final PackageSetting ps = (PackageSetting) p.mExtras;
5606            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5607                return false;
5608            }
5609            switch (type) {
5610                case CERT_INPUT_RAW_X509:
5611                    return p.mSigningDetails.hasCertificate(certificate);
5612                case CERT_INPUT_SHA256:
5613                    return p.mSigningDetails.hasSha256Certificate(certificate);
5614                default:
5615                    return false;
5616            }
5617        }
5618    }
5619
5620    @Override
5621    public boolean hasUidSigningCertificate(
5622            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5623        final int callingUid = Binder.getCallingUid();
5624        final int callingUserId = UserHandle.getUserId(callingUid);
5625        // Map to base uids.
5626        uid = UserHandle.getAppId(uid);
5627        // reader
5628        synchronized (mPackages) {
5629            final PackageParser.SigningDetails signingDetails;
5630            final Object obj = mSettings.getUserIdLPr(uid);
5631            if (obj != null) {
5632                if (obj instanceof SharedUserSetting) {
5633                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5634                    if (isCallerInstantApp) {
5635                        return false;
5636                    }
5637                    signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5638                } else if (obj instanceof PackageSetting) {
5639                    final PackageSetting ps = (PackageSetting) obj;
5640                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5641                        return false;
5642                    }
5643                    signingDetails = ps.signatures.mSigningDetails;
5644                } else {
5645                    return false;
5646                }
5647            } else {
5648                return false;
5649            }
5650            switch (type) {
5651                case CERT_INPUT_RAW_X509:
5652                    return signingDetails.hasCertificate(certificate);
5653                case CERT_INPUT_SHA256:
5654                    return signingDetails.hasSha256Certificate(certificate);
5655                default:
5656                    return false;
5657            }
5658        }
5659    }
5660
5661    /**
5662     * This method should typically only be used when granting or revoking
5663     * permissions, since the app may immediately restart after this call.
5664     * <p>
5665     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5666     * guard your work against the app being relaunched.
5667     */
5668    private void killUid(int appId, int userId, String reason) {
5669        final long identity = Binder.clearCallingIdentity();
5670        try {
5671            IActivityManager am = ActivityManager.getService();
5672            if (am != null) {
5673                try {
5674                    am.killUid(appId, userId, reason);
5675                } catch (RemoteException e) {
5676                    /* ignore - same process */
5677                }
5678            }
5679        } finally {
5680            Binder.restoreCallingIdentity(identity);
5681        }
5682    }
5683
5684    /**
5685     * If the database version for this type of package (internal storage or
5686     * external storage) is less than the version where package signatures
5687     * were updated, return true.
5688     */
5689    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5690        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5691        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5692    }
5693
5694    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5695        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5696        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5697    }
5698
5699    @Override
5700    public List<String> getAllPackages() {
5701        final int callingUid = Binder.getCallingUid();
5702        final int callingUserId = UserHandle.getUserId(callingUid);
5703        synchronized (mPackages) {
5704            if (canViewInstantApps(callingUid, callingUserId)) {
5705                return new ArrayList<String>(mPackages.keySet());
5706            }
5707            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5708            final List<String> result = new ArrayList<>();
5709            if (instantAppPkgName != null) {
5710                // caller is an instant application; filter unexposed applications
5711                for (PackageParser.Package pkg : mPackages.values()) {
5712                    if (!pkg.visibleToInstantApps) {
5713                        continue;
5714                    }
5715                    result.add(pkg.packageName);
5716                }
5717            } else {
5718                // caller is a normal application; filter instant applications
5719                for (PackageParser.Package pkg : mPackages.values()) {
5720                    final PackageSetting ps =
5721                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5722                    if (ps != null
5723                            && ps.getInstantApp(callingUserId)
5724                            && !mInstantAppRegistry.isInstantAccessGranted(
5725                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5726                        continue;
5727                    }
5728                    result.add(pkg.packageName);
5729                }
5730            }
5731            return result;
5732        }
5733    }
5734
5735    @Override
5736    public String[] getPackagesForUid(int uid) {
5737        final int callingUid = Binder.getCallingUid();
5738        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5739        final int userId = UserHandle.getUserId(uid);
5740        uid = UserHandle.getAppId(uid);
5741        // reader
5742        synchronized (mPackages) {
5743            Object obj = mSettings.getUserIdLPr(uid);
5744            if (obj instanceof SharedUserSetting) {
5745                if (isCallerInstantApp) {
5746                    return null;
5747                }
5748                final SharedUserSetting sus = (SharedUserSetting) obj;
5749                final int N = sus.packages.size();
5750                String[] res = new String[N];
5751                final Iterator<PackageSetting> it = sus.packages.iterator();
5752                int i = 0;
5753                while (it.hasNext()) {
5754                    PackageSetting ps = it.next();
5755                    if (ps.getInstalled(userId)) {
5756                        res[i++] = ps.name;
5757                    } else {
5758                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5759                    }
5760                }
5761                return res;
5762            } else if (obj instanceof PackageSetting) {
5763                final PackageSetting ps = (PackageSetting) obj;
5764                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5765                    return new String[]{ps.name};
5766                }
5767            }
5768        }
5769        return null;
5770    }
5771
5772    @Override
5773    public String getNameForUid(int uid) {
5774        final int callingUid = Binder.getCallingUid();
5775        if (getInstantAppPackageName(callingUid) != null) {
5776            return null;
5777        }
5778        synchronized (mPackages) {
5779            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5780            if (obj instanceof SharedUserSetting) {
5781                final SharedUserSetting sus = (SharedUserSetting) obj;
5782                return sus.name + ":" + sus.userId;
5783            } else if (obj instanceof PackageSetting) {
5784                final PackageSetting ps = (PackageSetting) obj;
5785                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5786                    return null;
5787                }
5788                return ps.name;
5789            }
5790            return null;
5791        }
5792    }
5793
5794    @Override
5795    public String[] getNamesForUids(int[] uids) {
5796        if (uids == null || uids.length == 0) {
5797            return null;
5798        }
5799        final int callingUid = Binder.getCallingUid();
5800        if (getInstantAppPackageName(callingUid) != null) {
5801            return null;
5802        }
5803        final String[] names = new String[uids.length];
5804        synchronized (mPackages) {
5805            for (int i = uids.length - 1; i >= 0; i--) {
5806                final int uid = uids[i];
5807                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5808                if (obj instanceof SharedUserSetting) {
5809                    final SharedUserSetting sus = (SharedUserSetting) obj;
5810                    names[i] = "shared:" + sus.name;
5811                } else if (obj instanceof PackageSetting) {
5812                    final PackageSetting ps = (PackageSetting) obj;
5813                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5814                        names[i] = null;
5815                    } else {
5816                        names[i] = ps.name;
5817                    }
5818                } else {
5819                    names[i] = null;
5820                }
5821            }
5822        }
5823        return names;
5824    }
5825
5826    @Override
5827    public int getUidForSharedUser(String sharedUserName) {
5828        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5829            return -1;
5830        }
5831        if (sharedUserName == null) {
5832            return -1;
5833        }
5834        // reader
5835        synchronized (mPackages) {
5836            SharedUserSetting suid;
5837            try {
5838                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5839                if (suid != null) {
5840                    return suid.userId;
5841                }
5842            } catch (PackageManagerException ignore) {
5843                // can't happen, but, still need to catch it
5844            }
5845            return -1;
5846        }
5847    }
5848
5849    @Override
5850    public int getFlagsForUid(int uid) {
5851        final int callingUid = Binder.getCallingUid();
5852        if (getInstantAppPackageName(callingUid) != null) {
5853            return 0;
5854        }
5855        synchronized (mPackages) {
5856            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5857            if (obj instanceof SharedUserSetting) {
5858                final SharedUserSetting sus = (SharedUserSetting) obj;
5859                return sus.pkgFlags;
5860            } else if (obj instanceof PackageSetting) {
5861                final PackageSetting ps = (PackageSetting) obj;
5862                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5863                    return 0;
5864                }
5865                return ps.pkgFlags;
5866            }
5867        }
5868        return 0;
5869    }
5870
5871    @Override
5872    public int getPrivateFlagsForUid(int uid) {
5873        final int callingUid = Binder.getCallingUid();
5874        if (getInstantAppPackageName(callingUid) != null) {
5875            return 0;
5876        }
5877        synchronized (mPackages) {
5878            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5879            if (obj instanceof SharedUserSetting) {
5880                final SharedUserSetting sus = (SharedUserSetting) obj;
5881                return sus.pkgPrivateFlags;
5882            } else if (obj instanceof PackageSetting) {
5883                final PackageSetting ps = (PackageSetting) obj;
5884                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5885                    return 0;
5886                }
5887                return ps.pkgPrivateFlags;
5888            }
5889        }
5890        return 0;
5891    }
5892
5893    @Override
5894    public boolean isUidPrivileged(int uid) {
5895        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5896            return false;
5897        }
5898        uid = UserHandle.getAppId(uid);
5899        // reader
5900        synchronized (mPackages) {
5901            Object obj = mSettings.getUserIdLPr(uid);
5902            if (obj instanceof SharedUserSetting) {
5903                final SharedUserSetting sus = (SharedUserSetting) obj;
5904                final Iterator<PackageSetting> it = sus.packages.iterator();
5905                while (it.hasNext()) {
5906                    if (it.next().isPrivileged()) {
5907                        return true;
5908                    }
5909                }
5910            } else if (obj instanceof PackageSetting) {
5911                final PackageSetting ps = (PackageSetting) obj;
5912                return ps.isPrivileged();
5913            }
5914        }
5915        return false;
5916    }
5917
5918    @Override
5919    public String[] getAppOpPermissionPackages(String permName) {
5920        return mPermissionManager.getAppOpPermissionPackages(permName);
5921    }
5922
5923    @Override
5924    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5925            int flags, int userId) {
5926        return resolveIntentInternal(
5927                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5928    }
5929
5930    /**
5931     * Normally instant apps can only be resolved when they're visible to the caller.
5932     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5933     * since we need to allow the system to start any installed application.
5934     */
5935    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5936            int flags, int userId, boolean resolveForStart) {
5937        try {
5938            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5939
5940            if (!sUserManager.exists(userId)) return null;
5941            final int callingUid = Binder.getCallingUid();
5942            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5943            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5944                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5945
5946            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5947            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5948                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5949            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5950
5951            final ResolveInfo bestChoice =
5952                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5953            return bestChoice;
5954        } finally {
5955            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5956        }
5957    }
5958
5959    @Override
5960    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5961        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5962            throw new SecurityException(
5963                    "findPersistentPreferredActivity can only be run by the system");
5964        }
5965        if (!sUserManager.exists(userId)) {
5966            return null;
5967        }
5968        final int callingUid = Binder.getCallingUid();
5969        intent = updateIntentForResolve(intent);
5970        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5971        final int flags = updateFlagsForResolve(
5972                0, userId, intent, callingUid, false /*includeInstantApps*/);
5973        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5974                userId);
5975        synchronized (mPackages) {
5976            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5977                    userId);
5978        }
5979    }
5980
5981    @Override
5982    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5983            IntentFilter filter, int match, ComponentName activity) {
5984        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5985            return;
5986        }
5987        final int userId = UserHandle.getCallingUserId();
5988        if (DEBUG_PREFERRED) {
5989            Log.v(TAG, "setLastChosenActivity intent=" + intent
5990                + " resolvedType=" + resolvedType
5991                + " flags=" + flags
5992                + " filter=" + filter
5993                + " match=" + match
5994                + " activity=" + activity);
5995            filter.dump(new PrintStreamPrinter(System.out), "    ");
5996        }
5997        intent.setComponent(null);
5998        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5999                userId);
6000        // Find any earlier preferred or last chosen entries and nuke them
6001        findPreferredActivity(intent, resolvedType,
6002                flags, query, 0, false, true, false, userId);
6003        // Add the new activity as the last chosen for this filter
6004        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6005                "Setting last chosen");
6006    }
6007
6008    @Override
6009    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6010        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6011            return null;
6012        }
6013        final int userId = UserHandle.getCallingUserId();
6014        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6015        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6016                userId);
6017        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6018                false, false, false, userId);
6019    }
6020
6021    /**
6022     * Returns whether or not instant apps have been disabled remotely.
6023     */
6024    private boolean areWebInstantAppsDisabled() {
6025        return mWebInstantAppsDisabled;
6026    }
6027
6028    private boolean isInstantAppResolutionAllowed(
6029            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6030            boolean skipPackageCheck) {
6031        if (mInstantAppResolverConnection == null) {
6032            return false;
6033        }
6034        if (mInstantAppInstallerActivity == null) {
6035            return false;
6036        }
6037        if (intent.getComponent() != null) {
6038            return false;
6039        }
6040        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6041            return false;
6042        }
6043        if (!skipPackageCheck && intent.getPackage() != null) {
6044            return false;
6045        }
6046        if (!intent.isWebIntent()) {
6047            // for non web intents, we should not resolve externally if an app already exists to
6048            // handle it or if the caller didn't explicitly request it.
6049            if ((resolvedActivities != null && resolvedActivities.size() != 0)
6050                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6051                return false;
6052            }
6053        } else {
6054            if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6055                return false;
6056            } else if (areWebInstantAppsDisabled()) {
6057                return false;
6058            }
6059        }
6060        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6061        // Or if there's already an ephemeral app installed that handles the action
6062        synchronized (mPackages) {
6063            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6064            for (int n = 0; n < count; n++) {
6065                final ResolveInfo info = resolvedActivities.get(n);
6066                final String packageName = info.activityInfo.packageName;
6067                final PackageSetting ps = mSettings.mPackages.get(packageName);
6068                if (ps != null) {
6069                    // only check domain verification status if the app is not a browser
6070                    if (!info.handleAllWebDataURI) {
6071                        // Try to get the status from User settings first
6072                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6073                        final int status = (int) (packedStatus >> 32);
6074                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6075                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6076                            if (DEBUG_INSTANT) {
6077                                Slog.v(TAG, "DENY instant app;"
6078                                    + " pkg: " + packageName + ", status: " + status);
6079                            }
6080                            return false;
6081                        }
6082                    }
6083                    if (ps.getInstantApp(userId)) {
6084                        if (DEBUG_INSTANT) {
6085                            Slog.v(TAG, "DENY instant app installed;"
6086                                    + " pkg: " + packageName);
6087                        }
6088                        return false;
6089                    }
6090                }
6091            }
6092        }
6093        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6094        return true;
6095    }
6096
6097    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6098            Intent origIntent, String resolvedType, String callingPackage,
6099            Bundle verificationBundle, int userId) {
6100        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6101                new InstantAppRequest(responseObj, origIntent, resolvedType,
6102                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6103        mHandler.sendMessage(msg);
6104    }
6105
6106    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6107            int flags, List<ResolveInfo> query, int userId) {
6108        if (query != null) {
6109            final int N = query.size();
6110            if (N == 1) {
6111                return query.get(0);
6112            } else if (N > 1) {
6113                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6114                // If there is more than one activity with the same priority,
6115                // then let the user decide between them.
6116                ResolveInfo r0 = query.get(0);
6117                ResolveInfo r1 = query.get(1);
6118                if (DEBUG_INTENT_MATCHING || debug) {
6119                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6120                            + r1.activityInfo.name + "=" + r1.priority);
6121                }
6122                // If the first activity has a higher priority, or a different
6123                // default, then it is always desirable to pick it.
6124                if (r0.priority != r1.priority
6125                        || r0.preferredOrder != r1.preferredOrder
6126                        || r0.isDefault != r1.isDefault) {
6127                    return query.get(0);
6128                }
6129                // If we have saved a preference for a preferred activity for
6130                // this Intent, use that.
6131                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6132                        flags, query, r0.priority, true, false, debug, userId);
6133                if (ri != null) {
6134                    return ri;
6135                }
6136                // If we have an ephemeral app, use it
6137                for (int i = 0; i < N; i++) {
6138                    ri = query.get(i);
6139                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6140                        final String packageName = ri.activityInfo.packageName;
6141                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6142                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6143                        final int status = (int)(packedStatus >> 32);
6144                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6145                            return ri;
6146                        }
6147                    }
6148                }
6149                ri = new ResolveInfo(mResolveInfo);
6150                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6151                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6152                // If all of the options come from the same package, show the application's
6153                // label and icon instead of the generic resolver's.
6154                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6155                // and then throw away the ResolveInfo itself, meaning that the caller loses
6156                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6157                // a fallback for this case; we only set the target package's resources on
6158                // the ResolveInfo, not the ActivityInfo.
6159                final String intentPackage = intent.getPackage();
6160                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6161                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6162                    ri.resolvePackageName = intentPackage;
6163                    if (userNeedsBadging(userId)) {
6164                        ri.noResourceId = true;
6165                    } else {
6166                        ri.icon = appi.icon;
6167                    }
6168                    ri.iconResourceId = appi.icon;
6169                    ri.labelRes = appi.labelRes;
6170                }
6171                ri.activityInfo.applicationInfo = new ApplicationInfo(
6172                        ri.activityInfo.applicationInfo);
6173                if (userId != 0) {
6174                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6175                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6176                }
6177                // Make sure that the resolver is displayable in car mode
6178                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6179                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6180                return ri;
6181            }
6182        }
6183        return null;
6184    }
6185
6186    /**
6187     * Return true if the given list is not empty and all of its contents have
6188     * an activityInfo with the given package name.
6189     */
6190    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6191        if (ArrayUtils.isEmpty(list)) {
6192            return false;
6193        }
6194        for (int i = 0, N = list.size(); i < N; i++) {
6195            final ResolveInfo ri = list.get(i);
6196            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6197            if (ai == null || !packageName.equals(ai.packageName)) {
6198                return false;
6199            }
6200        }
6201        return true;
6202    }
6203
6204    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6205            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6206        final int N = query.size();
6207        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6208                .get(userId);
6209        // Get the list of persistent preferred activities that handle the intent
6210        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6211        List<PersistentPreferredActivity> pprefs = ppir != null
6212                ? ppir.queryIntent(intent, resolvedType,
6213                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6214                        userId)
6215                : null;
6216        if (pprefs != null && pprefs.size() > 0) {
6217            final int M = pprefs.size();
6218            for (int i=0; i<M; i++) {
6219                final PersistentPreferredActivity ppa = pprefs.get(i);
6220                if (DEBUG_PREFERRED || debug) {
6221                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6222                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6223                            + "\n  component=" + ppa.mComponent);
6224                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6225                }
6226                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6227                        flags | MATCH_DISABLED_COMPONENTS, userId);
6228                if (DEBUG_PREFERRED || debug) {
6229                    Slog.v(TAG, "Found persistent preferred activity:");
6230                    if (ai != null) {
6231                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6232                    } else {
6233                        Slog.v(TAG, "  null");
6234                    }
6235                }
6236                if (ai == null) {
6237                    // This previously registered persistent preferred activity
6238                    // component is no longer known. Ignore it and do NOT remove it.
6239                    continue;
6240                }
6241                for (int j=0; j<N; j++) {
6242                    final ResolveInfo ri = query.get(j);
6243                    if (!ri.activityInfo.applicationInfo.packageName
6244                            .equals(ai.applicationInfo.packageName)) {
6245                        continue;
6246                    }
6247                    if (!ri.activityInfo.name.equals(ai.name)) {
6248                        continue;
6249                    }
6250                    //  Found a persistent preference that can handle the intent.
6251                    if (DEBUG_PREFERRED || debug) {
6252                        Slog.v(TAG, "Returning persistent preferred activity: " +
6253                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6254                    }
6255                    return ri;
6256                }
6257            }
6258        }
6259        return null;
6260    }
6261
6262    // TODO: handle preferred activities missing while user has amnesia
6263    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6264            List<ResolveInfo> query, int priority, boolean always,
6265            boolean removeMatches, boolean debug, int userId) {
6266        if (!sUserManager.exists(userId)) return null;
6267        final int callingUid = Binder.getCallingUid();
6268        flags = updateFlagsForResolve(
6269                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6270        intent = updateIntentForResolve(intent);
6271        // writer
6272        synchronized (mPackages) {
6273            // Try to find a matching persistent preferred activity.
6274            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6275                    debug, userId);
6276
6277            // If a persistent preferred activity matched, use it.
6278            if (pri != null) {
6279                return pri;
6280            }
6281
6282            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6283            // Get the list of preferred activities that handle the intent
6284            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6285            List<PreferredActivity> prefs = pir != null
6286                    ? pir.queryIntent(intent, resolvedType,
6287                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6288                            userId)
6289                    : null;
6290            if (prefs != null && prefs.size() > 0) {
6291                boolean changed = false;
6292                try {
6293                    // First figure out how good the original match set is.
6294                    // We will only allow preferred activities that came
6295                    // from the same match quality.
6296                    int match = 0;
6297
6298                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6299
6300                    final int N = query.size();
6301                    for (int j=0; j<N; j++) {
6302                        final ResolveInfo ri = query.get(j);
6303                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6304                                + ": 0x" + Integer.toHexString(match));
6305                        if (ri.match > match) {
6306                            match = ri.match;
6307                        }
6308                    }
6309
6310                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6311                            + Integer.toHexString(match));
6312
6313                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6314                    final int M = prefs.size();
6315                    for (int i=0; i<M; i++) {
6316                        final PreferredActivity pa = prefs.get(i);
6317                        if (DEBUG_PREFERRED || debug) {
6318                            Slog.v(TAG, "Checking PreferredActivity ds="
6319                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6320                                    + "\n  component=" + pa.mPref.mComponent);
6321                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6322                        }
6323                        if (pa.mPref.mMatch != match) {
6324                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6325                                    + Integer.toHexString(pa.mPref.mMatch));
6326                            continue;
6327                        }
6328                        // If it's not an "always" type preferred activity and that's what we're
6329                        // looking for, skip it.
6330                        if (always && !pa.mPref.mAlways) {
6331                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6332                            continue;
6333                        }
6334                        final ActivityInfo ai = getActivityInfo(
6335                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6336                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6337                                userId);
6338                        if (DEBUG_PREFERRED || debug) {
6339                            Slog.v(TAG, "Found preferred activity:");
6340                            if (ai != null) {
6341                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6342                            } else {
6343                                Slog.v(TAG, "  null");
6344                            }
6345                        }
6346                        if (ai == null) {
6347                            // This previously registered preferred activity
6348                            // component is no longer known.  Most likely an update
6349                            // to the app was installed and in the new version this
6350                            // component no longer exists.  Clean it up by removing
6351                            // it from the preferred activities list, and skip it.
6352                            Slog.w(TAG, "Removing dangling preferred activity: "
6353                                    + pa.mPref.mComponent);
6354                            pir.removeFilter(pa);
6355                            changed = true;
6356                            continue;
6357                        }
6358                        for (int j=0; j<N; j++) {
6359                            final ResolveInfo ri = query.get(j);
6360                            if (!ri.activityInfo.applicationInfo.packageName
6361                                    .equals(ai.applicationInfo.packageName)) {
6362                                continue;
6363                            }
6364                            if (!ri.activityInfo.name.equals(ai.name)) {
6365                                continue;
6366                            }
6367
6368                            if (removeMatches) {
6369                                pir.removeFilter(pa);
6370                                changed = true;
6371                                if (DEBUG_PREFERRED) {
6372                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6373                                }
6374                                break;
6375                            }
6376
6377                            // Okay we found a previously set preferred or last chosen app.
6378                            // If the result set is different from when this
6379                            // was created, and is not a subset of the preferred set, we need to
6380                            // clear it and re-ask the user their preference, if we're looking for
6381                            // an "always" type entry.
6382                            if (always && !pa.mPref.sameSet(query)) {
6383                                if (pa.mPref.isSuperset(query)) {
6384                                    // some components of the set are no longer present in
6385                                    // the query, but the preferred activity can still be reused
6386                                    if (DEBUG_PREFERRED) {
6387                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6388                                                + " still valid as only non-preferred components"
6389                                                + " were removed for " + intent + " type "
6390                                                + resolvedType);
6391                                    }
6392                                    // remove obsolete components and re-add the up-to-date filter
6393                                    PreferredActivity freshPa = new PreferredActivity(pa,
6394                                            pa.mPref.mMatch,
6395                                            pa.mPref.discardObsoleteComponents(query),
6396                                            pa.mPref.mComponent,
6397                                            pa.mPref.mAlways);
6398                                    pir.removeFilter(pa);
6399                                    pir.addFilter(freshPa);
6400                                    changed = true;
6401                                } else {
6402                                    Slog.i(TAG,
6403                                            "Result set changed, dropping preferred activity for "
6404                                                    + intent + " type " + resolvedType);
6405                                    if (DEBUG_PREFERRED) {
6406                                        Slog.v(TAG, "Removing preferred activity since set changed "
6407                                                + pa.mPref.mComponent);
6408                                    }
6409                                    pir.removeFilter(pa);
6410                                    // Re-add the filter as a "last chosen" entry (!always)
6411                                    PreferredActivity lastChosen = new PreferredActivity(
6412                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6413                                    pir.addFilter(lastChosen);
6414                                    changed = true;
6415                                    return null;
6416                                }
6417                            }
6418
6419                            // Yay! Either the set matched or we're looking for the last chosen
6420                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6421                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6422                            return ri;
6423                        }
6424                    }
6425                } finally {
6426                    if (changed) {
6427                        if (DEBUG_PREFERRED) {
6428                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6429                        }
6430                        scheduleWritePackageRestrictionsLocked(userId);
6431                    }
6432                }
6433            }
6434        }
6435        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6436        return null;
6437    }
6438
6439    /*
6440     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6441     */
6442    @Override
6443    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6444            int targetUserId) {
6445        mContext.enforceCallingOrSelfPermission(
6446                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6447        List<CrossProfileIntentFilter> matches =
6448                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6449        if (matches != null) {
6450            int size = matches.size();
6451            for (int i = 0; i < size; i++) {
6452                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6453            }
6454        }
6455        if (intent.hasWebURI()) {
6456            // cross-profile app linking works only towards the parent.
6457            final int callingUid = Binder.getCallingUid();
6458            final UserInfo parent = getProfileParent(sourceUserId);
6459            synchronized(mPackages) {
6460                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6461                        false /*includeInstantApps*/);
6462                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6463                        intent, resolvedType, flags, sourceUserId, parent.id);
6464                return xpDomainInfo != null;
6465            }
6466        }
6467        return false;
6468    }
6469
6470    private UserInfo getProfileParent(int userId) {
6471        final long identity = Binder.clearCallingIdentity();
6472        try {
6473            return sUserManager.getProfileParent(userId);
6474        } finally {
6475            Binder.restoreCallingIdentity(identity);
6476        }
6477    }
6478
6479    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6480            String resolvedType, int userId) {
6481        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6482        if (resolver != null) {
6483            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6484        }
6485        return null;
6486    }
6487
6488    @Override
6489    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6490            String resolvedType, int flags, int userId) {
6491        try {
6492            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6493
6494            return new ParceledListSlice<>(
6495                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6496        } finally {
6497            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6498        }
6499    }
6500
6501    /**
6502     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6503     * instant, returns {@code null}.
6504     */
6505    private String getInstantAppPackageName(int callingUid) {
6506        synchronized (mPackages) {
6507            // If the caller is an isolated app use the owner's uid for the lookup.
6508            if (Process.isIsolated(callingUid)) {
6509                callingUid = mIsolatedOwners.get(callingUid);
6510            }
6511            final int appId = UserHandle.getAppId(callingUid);
6512            final Object obj = mSettings.getUserIdLPr(appId);
6513            if (obj instanceof PackageSetting) {
6514                final PackageSetting ps = (PackageSetting) obj;
6515                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6516                return isInstantApp ? ps.pkg.packageName : null;
6517            }
6518        }
6519        return null;
6520    }
6521
6522    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6523            String resolvedType, int flags, int userId) {
6524        return queryIntentActivitiesInternal(
6525                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6526                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6527    }
6528
6529    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6530            String resolvedType, int flags, int filterCallingUid, int userId,
6531            boolean resolveForStart, boolean allowDynamicSplits) {
6532        if (!sUserManager.exists(userId)) return Collections.emptyList();
6533        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6534        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6535                false /* requireFullPermission */, false /* checkShell */,
6536                "query intent activities");
6537        final String pkgName = intent.getPackage();
6538        ComponentName comp = intent.getComponent();
6539        if (comp == null) {
6540            if (intent.getSelector() != null) {
6541                intent = intent.getSelector();
6542                comp = intent.getComponent();
6543            }
6544        }
6545
6546        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6547                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6548        if (comp != null) {
6549            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6550            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6551            if (ai != null) {
6552                // When specifying an explicit component, we prevent the activity from being
6553                // used when either 1) the calling package is normal and the activity is within
6554                // an ephemeral application or 2) the calling package is ephemeral and the
6555                // activity is not visible to ephemeral applications.
6556                final boolean matchInstantApp =
6557                        (flags & PackageManager.MATCH_INSTANT) != 0;
6558                final boolean matchVisibleToInstantAppOnly =
6559                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6560                final boolean matchExplicitlyVisibleOnly =
6561                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6562                final boolean isCallerInstantApp =
6563                        instantAppPkgName != null;
6564                final boolean isTargetSameInstantApp =
6565                        comp.getPackageName().equals(instantAppPkgName);
6566                final boolean isTargetInstantApp =
6567                        (ai.applicationInfo.privateFlags
6568                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6569                final boolean isTargetVisibleToInstantApp =
6570                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6571                final boolean isTargetExplicitlyVisibleToInstantApp =
6572                        isTargetVisibleToInstantApp
6573                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6574                final boolean isTargetHiddenFromInstantApp =
6575                        !isTargetVisibleToInstantApp
6576                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6577                final boolean blockResolution =
6578                        !isTargetSameInstantApp
6579                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6580                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6581                                        && isTargetHiddenFromInstantApp));
6582                if (!blockResolution) {
6583                    final ResolveInfo ri = new ResolveInfo();
6584                    ri.activityInfo = ai;
6585                    list.add(ri);
6586                }
6587            }
6588            return applyPostResolutionFilter(
6589                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6590        }
6591
6592        // reader
6593        boolean sortResult = false;
6594        boolean addInstant = false;
6595        List<ResolveInfo> result;
6596        synchronized (mPackages) {
6597            if (pkgName == null) {
6598                List<CrossProfileIntentFilter> matchingFilters =
6599                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6600                // Check for results that need to skip the current profile.
6601                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6602                        resolvedType, flags, userId);
6603                if (xpResolveInfo != null) {
6604                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6605                    xpResult.add(xpResolveInfo);
6606                    return applyPostResolutionFilter(
6607                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6608                            allowDynamicSplits, filterCallingUid, userId, intent);
6609                }
6610
6611                // Check for results in the current profile.
6612                result = filterIfNotSystemUser(mActivities.queryIntent(
6613                        intent, resolvedType, flags, userId), userId);
6614                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6615                        false /*skipPackageCheck*/);
6616                // Check for cross profile results.
6617                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6618                xpResolveInfo = queryCrossProfileIntents(
6619                        matchingFilters, intent, resolvedType, flags, userId,
6620                        hasNonNegativePriorityResult);
6621                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6622                    boolean isVisibleToUser = filterIfNotSystemUser(
6623                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6624                    if (isVisibleToUser) {
6625                        result.add(xpResolveInfo);
6626                        sortResult = true;
6627                    }
6628                }
6629                if (intent.hasWebURI()) {
6630                    CrossProfileDomainInfo xpDomainInfo = null;
6631                    final UserInfo parent = getProfileParent(userId);
6632                    if (parent != null) {
6633                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6634                                flags, userId, parent.id);
6635                    }
6636                    if (xpDomainInfo != null) {
6637                        if (xpResolveInfo != null) {
6638                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6639                            // in the result.
6640                            result.remove(xpResolveInfo);
6641                        }
6642                        if (result.size() == 0 && !addInstant) {
6643                            // No result in current profile, but found candidate in parent user.
6644                            // And we are not going to add emphemeral app, so we can return the
6645                            // result straight away.
6646                            result.add(xpDomainInfo.resolveInfo);
6647                            return applyPostResolutionFilter(result, instantAppPkgName,
6648                                    allowDynamicSplits, filterCallingUid, userId, intent);
6649                        }
6650                    } else if (result.size() <= 1 && !addInstant) {
6651                        // No result in parent user and <= 1 result in current profile, and we
6652                        // are not going to add emphemeral app, so we can return the result without
6653                        // further processing.
6654                        return applyPostResolutionFilter(result, instantAppPkgName,
6655                                allowDynamicSplits, filterCallingUid, userId, intent);
6656                    }
6657                    // We have more than one candidate (combining results from current and parent
6658                    // profile), so we need filtering and sorting.
6659                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6660                            intent, flags, result, xpDomainInfo, userId);
6661                    sortResult = true;
6662                }
6663            } else {
6664                final PackageParser.Package pkg = mPackages.get(pkgName);
6665                result = null;
6666                if (pkg != null) {
6667                    result = filterIfNotSystemUser(
6668                            mActivities.queryIntentForPackage(
6669                                    intent, resolvedType, flags, pkg.activities, userId),
6670                            userId);
6671                }
6672                if (result == null || result.size() == 0) {
6673                    // the caller wants to resolve for a particular package; however, there
6674                    // were no installed results, so, try to find an ephemeral result
6675                    addInstant = isInstantAppResolutionAllowed(
6676                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6677                    if (result == null) {
6678                        result = new ArrayList<>();
6679                    }
6680                }
6681            }
6682        }
6683        if (addInstant) {
6684            result = maybeAddInstantAppInstaller(
6685                    result, intent, resolvedType, flags, userId, resolveForStart);
6686        }
6687        if (sortResult) {
6688            Collections.sort(result, mResolvePrioritySorter);
6689        }
6690        return applyPostResolutionFilter(
6691                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6692    }
6693
6694    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6695            String resolvedType, int flags, int userId, boolean resolveForStart) {
6696        // first, check to see if we've got an instant app already installed
6697        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6698        ResolveInfo localInstantApp = null;
6699        boolean blockResolution = false;
6700        if (!alreadyResolvedLocally) {
6701            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6702                    flags
6703                        | PackageManager.GET_RESOLVED_FILTER
6704                        | PackageManager.MATCH_INSTANT
6705                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6706                    userId);
6707            for (int i = instantApps.size() - 1; i >= 0; --i) {
6708                final ResolveInfo info = instantApps.get(i);
6709                final String packageName = info.activityInfo.packageName;
6710                final PackageSetting ps = mSettings.mPackages.get(packageName);
6711                if (ps.getInstantApp(userId)) {
6712                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6713                    final int status = (int)(packedStatus >> 32);
6714                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6715                        // there's a local instant application installed, but, the user has
6716                        // chosen to never use it; skip resolution and don't acknowledge
6717                        // an instant application is even available
6718                        if (DEBUG_INSTANT) {
6719                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6720                        }
6721                        blockResolution = true;
6722                        break;
6723                    } else {
6724                        // we have a locally installed instant application; skip resolution
6725                        // but acknowledge there's an instant application available
6726                        if (DEBUG_INSTANT) {
6727                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6728                        }
6729                        localInstantApp = info;
6730                        break;
6731                    }
6732                }
6733            }
6734        }
6735        // no app installed, let's see if one's available
6736        AuxiliaryResolveInfo auxiliaryResponse = null;
6737        if (!blockResolution) {
6738            if (localInstantApp == null) {
6739                // we don't have an instant app locally, resolve externally
6740                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6741                final InstantAppRequest requestObject = new InstantAppRequest(
6742                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6743                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6744                        resolveForStart);
6745                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
6746                        mInstantAppResolverConnection, requestObject);
6747                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6748            } else {
6749                // we have an instant application locally, but, we can't admit that since
6750                // callers shouldn't be able to determine prior browsing. create a dummy
6751                // auxiliary response so the downstream code behaves as if there's an
6752                // instant application available externally. when it comes time to start
6753                // the instant application, we'll do the right thing.
6754                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6755                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
6756                                        ai.packageName, ai.versionCode, null /* splitName */);
6757            }
6758        }
6759        if (intent.isWebIntent() && auxiliaryResponse == null) {
6760            return result;
6761        }
6762        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6763        if (ps == null
6764                || ps.getUserState().get(userId) == null
6765                || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
6766            return result;
6767        }
6768        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6769        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6770                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6771        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6772                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6773        // add a non-generic filter
6774        ephemeralInstaller.filter = new IntentFilter();
6775        if (intent.getAction() != null) {
6776            ephemeralInstaller.filter.addAction(intent.getAction());
6777        }
6778        if (intent.getData() != null && intent.getData().getPath() != null) {
6779            ephemeralInstaller.filter.addDataPath(
6780                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6781        }
6782        ephemeralInstaller.isInstantAppAvailable = true;
6783        // make sure this resolver is the default
6784        ephemeralInstaller.isDefault = true;
6785        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6786        if (DEBUG_INSTANT) {
6787            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6788        }
6789
6790        result.add(ephemeralInstaller);
6791        return result;
6792    }
6793
6794    private static class CrossProfileDomainInfo {
6795        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6796        ResolveInfo resolveInfo;
6797        /* Best domain verification status of the activities found in the other profile */
6798        int bestDomainVerificationStatus;
6799    }
6800
6801    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6802            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6803        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6804                sourceUserId)) {
6805            return null;
6806        }
6807        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6808                resolvedType, flags, parentUserId);
6809
6810        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6811            return null;
6812        }
6813        CrossProfileDomainInfo result = null;
6814        int size = resultTargetUser.size();
6815        for (int i = 0; i < size; i++) {
6816            ResolveInfo riTargetUser = resultTargetUser.get(i);
6817            // Intent filter verification is only for filters that specify a host. So don't return
6818            // those that handle all web uris.
6819            if (riTargetUser.handleAllWebDataURI) {
6820                continue;
6821            }
6822            String packageName = riTargetUser.activityInfo.packageName;
6823            PackageSetting ps = mSettings.mPackages.get(packageName);
6824            if (ps == null) {
6825                continue;
6826            }
6827            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6828            int status = (int)(verificationState >> 32);
6829            if (result == null) {
6830                result = new CrossProfileDomainInfo();
6831                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6832                        sourceUserId, parentUserId);
6833                result.bestDomainVerificationStatus = status;
6834            } else {
6835                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6836                        result.bestDomainVerificationStatus);
6837            }
6838        }
6839        // Don't consider matches with status NEVER across profiles.
6840        if (result != null && result.bestDomainVerificationStatus
6841                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6842            return null;
6843        }
6844        return result;
6845    }
6846
6847    /**
6848     * Verification statuses are ordered from the worse to the best, except for
6849     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6850     */
6851    private int bestDomainVerificationStatus(int status1, int status2) {
6852        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6853            return status2;
6854        }
6855        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6856            return status1;
6857        }
6858        return (int) MathUtils.max(status1, status2);
6859    }
6860
6861    private boolean isUserEnabled(int userId) {
6862        long callingId = Binder.clearCallingIdentity();
6863        try {
6864            UserInfo userInfo = sUserManager.getUserInfo(userId);
6865            return userInfo != null && userInfo.isEnabled();
6866        } finally {
6867            Binder.restoreCallingIdentity(callingId);
6868        }
6869    }
6870
6871    /**
6872     * Filter out activities with systemUserOnly flag set, when current user is not System.
6873     *
6874     * @return filtered list
6875     */
6876    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6877        if (userId == UserHandle.USER_SYSTEM) {
6878            return resolveInfos;
6879        }
6880        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6881            ResolveInfo info = resolveInfos.get(i);
6882            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6883                resolveInfos.remove(i);
6884            }
6885        }
6886        return resolveInfos;
6887    }
6888
6889    /**
6890     * Filters out ephemeral activities.
6891     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6892     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6893     *
6894     * @param resolveInfos The pre-filtered list of resolved activities
6895     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6896     *          is performed.
6897     * @param intent
6898     * @return A filtered list of resolved activities.
6899     */
6900    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6901            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId,
6902            Intent intent) {
6903        final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled();
6904        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6905            final ResolveInfo info = resolveInfos.get(i);
6906            // remove locally resolved instant app web results when disabled
6907            if (info.isInstantAppAvailable && blockInstant) {
6908                resolveInfos.remove(i);
6909                continue;
6910            }
6911            // allow activities that are defined in the provided package
6912            if (allowDynamicSplits
6913                    && info.activityInfo != null
6914                    && info.activityInfo.splitName != null
6915                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6916                            info.activityInfo.splitName)) {
6917                if (mInstantAppInstallerActivity == null) {
6918                    if (DEBUG_INSTALL) {
6919                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6920                    }
6921                    resolveInfos.remove(i);
6922                    continue;
6923                }
6924                if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
6925                    resolveInfos.remove(i);
6926                    continue;
6927                }
6928                // requested activity is defined in a split that hasn't been installed yet.
6929                // add the installer to the resolve list
6930                if (DEBUG_INSTALL) {
6931                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6932                }
6933                final ResolveInfo installerInfo = new ResolveInfo(
6934                        mInstantAppInstallerInfo);
6935                final ComponentName installFailureActivity = findInstallFailureActivity(
6936                        info.activityInfo.packageName,  filterCallingUid, userId);
6937                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6938                        installFailureActivity,
6939                        info.activityInfo.packageName,
6940                        info.activityInfo.applicationInfo.versionCode,
6941                        info.activityInfo.splitName);
6942                // add a non-generic filter
6943                installerInfo.filter = new IntentFilter();
6944
6945                // This resolve info may appear in the chooser UI, so let us make it
6946                // look as the one it replaces as far as the user is concerned which
6947                // requires loading the correct label and icon for the resolve info.
6948                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6949                installerInfo.labelRes = info.resolveLabelResId();
6950                installerInfo.icon = info.resolveIconResId();
6951                installerInfo.isInstantAppAvailable = true;
6952                resolveInfos.set(i, installerInfo);
6953                continue;
6954            }
6955            // caller is a full app, don't need to apply any other filtering
6956            if (ephemeralPkgName == null) {
6957                continue;
6958            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6959                // caller is same app; don't need to apply any other filtering
6960                continue;
6961            }
6962            // allow activities that have been explicitly exposed to ephemeral apps
6963            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6964            if (!isEphemeralApp
6965                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6966                continue;
6967            }
6968            resolveInfos.remove(i);
6969        }
6970        return resolveInfos;
6971    }
6972
6973    /**
6974     * Returns the activity component that can handle install failures.
6975     * <p>By default, the instant application installer handles failures. However, an
6976     * application may want to handle failures on its own. Applications do this by
6977     * creating an activity with an intent filter that handles the action
6978     * {@link Intent#ACTION_INSTALL_FAILURE}.
6979     */
6980    private @Nullable ComponentName findInstallFailureActivity(
6981            String packageName, int filterCallingUid, int userId) {
6982        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6983        failureActivityIntent.setPackage(packageName);
6984        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6985        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6986                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6987                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6988        final int NR = result.size();
6989        if (NR > 0) {
6990            for (int i = 0; i < NR; i++) {
6991                final ResolveInfo info = result.get(i);
6992                if (info.activityInfo.splitName != null) {
6993                    continue;
6994                }
6995                return new ComponentName(packageName, info.activityInfo.name);
6996            }
6997        }
6998        return null;
6999    }
7000
7001    /**
7002     * @param resolveInfos list of resolve infos in descending priority order
7003     * @return if the list contains a resolve info with non-negative priority
7004     */
7005    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7006        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7007    }
7008
7009    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7010            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7011            int userId) {
7012        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7013
7014        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7015            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7016                    candidates.size());
7017        }
7018
7019        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7020        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7021        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7022        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7023        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7024        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7025
7026        synchronized (mPackages) {
7027            final int count = candidates.size();
7028            // First, try to use linked apps. Partition the candidates into four lists:
7029            // one for the final results, one for the "do not use ever", one for "undefined status"
7030            // and finally one for "browser app type".
7031            for (int n=0; n<count; n++) {
7032                ResolveInfo info = candidates.get(n);
7033                String packageName = info.activityInfo.packageName;
7034                PackageSetting ps = mSettings.mPackages.get(packageName);
7035                if (ps != null) {
7036                    // Add to the special match all list (Browser use case)
7037                    if (info.handleAllWebDataURI) {
7038                        matchAllList.add(info);
7039                        continue;
7040                    }
7041                    // Try to get the status from User settings first
7042                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7043                    int status = (int)(packedStatus >> 32);
7044                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7045                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7046                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7047                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7048                                    + " : linkgen=" + linkGeneration);
7049                        }
7050                        // Use link-enabled generation as preferredOrder, i.e.
7051                        // prefer newly-enabled over earlier-enabled.
7052                        info.preferredOrder = linkGeneration;
7053                        alwaysList.add(info);
7054                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7055                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7056                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7057                        }
7058                        neverList.add(info);
7059                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7060                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7061                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7062                        }
7063                        alwaysAskList.add(info);
7064                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7065                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7066                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7067                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7068                        }
7069                        undefinedList.add(info);
7070                    }
7071                }
7072            }
7073
7074            // We'll want to include browser possibilities in a few cases
7075            boolean includeBrowser = false;
7076
7077            // First try to add the "always" resolution(s) for the current user, if any
7078            if (alwaysList.size() > 0) {
7079                result.addAll(alwaysList);
7080            } else {
7081                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7082                result.addAll(undefinedList);
7083                // Maybe add one for the other profile.
7084                if (xpDomainInfo != null && (
7085                        xpDomainInfo.bestDomainVerificationStatus
7086                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7087                    result.add(xpDomainInfo.resolveInfo);
7088                }
7089                includeBrowser = true;
7090            }
7091
7092            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7093            // If there were 'always' entries their preferred order has been set, so we also
7094            // back that off to make the alternatives equivalent
7095            if (alwaysAskList.size() > 0) {
7096                for (ResolveInfo i : result) {
7097                    i.preferredOrder = 0;
7098                }
7099                result.addAll(alwaysAskList);
7100                includeBrowser = true;
7101            }
7102
7103            if (includeBrowser) {
7104                // Also add browsers (all of them or only the default one)
7105                if (DEBUG_DOMAIN_VERIFICATION) {
7106                    Slog.v(TAG, "   ...including browsers in candidate set");
7107                }
7108                if ((matchFlags & MATCH_ALL) != 0) {
7109                    result.addAll(matchAllList);
7110                } else {
7111                    // Browser/generic handling case.  If there's a default browser, go straight
7112                    // to that (but only if there is no other higher-priority match).
7113                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7114                    int maxMatchPrio = 0;
7115                    ResolveInfo defaultBrowserMatch = null;
7116                    final int numCandidates = matchAllList.size();
7117                    for (int n = 0; n < numCandidates; n++) {
7118                        ResolveInfo info = matchAllList.get(n);
7119                        // track the highest overall match priority...
7120                        if (info.priority > maxMatchPrio) {
7121                            maxMatchPrio = info.priority;
7122                        }
7123                        // ...and the highest-priority default browser match
7124                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7125                            if (defaultBrowserMatch == null
7126                                    || (defaultBrowserMatch.priority < info.priority)) {
7127                                if (debug) {
7128                                    Slog.v(TAG, "Considering default browser match " + info);
7129                                }
7130                                defaultBrowserMatch = info;
7131                            }
7132                        }
7133                    }
7134                    if (defaultBrowserMatch != null
7135                            && defaultBrowserMatch.priority >= maxMatchPrio
7136                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7137                    {
7138                        if (debug) {
7139                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7140                        }
7141                        result.add(defaultBrowserMatch);
7142                    } else {
7143                        result.addAll(matchAllList);
7144                    }
7145                }
7146
7147                // If there is nothing selected, add all candidates and remove the ones that the user
7148                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7149                if (result.size() == 0) {
7150                    result.addAll(candidates);
7151                    result.removeAll(neverList);
7152                }
7153            }
7154        }
7155        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7156            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7157                    result.size());
7158            for (ResolveInfo info : result) {
7159                Slog.v(TAG, "  + " + info.activityInfo);
7160            }
7161        }
7162        return result;
7163    }
7164
7165    // Returns a packed value as a long:
7166    //
7167    // high 'int'-sized word: link status: undefined/ask/never/always.
7168    // low 'int'-sized word: relative priority among 'always' results.
7169    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7170        long result = ps.getDomainVerificationStatusForUser(userId);
7171        // if none available, get the master status
7172        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7173            if (ps.getIntentFilterVerificationInfo() != null) {
7174                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7175            }
7176        }
7177        return result;
7178    }
7179
7180    private ResolveInfo querySkipCurrentProfileIntents(
7181            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7182            int flags, int sourceUserId) {
7183        if (matchingFilters != null) {
7184            int size = matchingFilters.size();
7185            for (int i = 0; i < size; i ++) {
7186                CrossProfileIntentFilter filter = matchingFilters.get(i);
7187                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7188                    // Checking if there are activities in the target user that can handle the
7189                    // intent.
7190                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7191                            resolvedType, flags, sourceUserId);
7192                    if (resolveInfo != null) {
7193                        return resolveInfo;
7194                    }
7195                }
7196            }
7197        }
7198        return null;
7199    }
7200
7201    // Return matching ResolveInfo in target user if any.
7202    private ResolveInfo queryCrossProfileIntents(
7203            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7204            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7205        if (matchingFilters != null) {
7206            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7207            // match the same intent. For performance reasons, it is better not to
7208            // run queryIntent twice for the same userId
7209            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7210            int size = matchingFilters.size();
7211            for (int i = 0; i < size; i++) {
7212                CrossProfileIntentFilter filter = matchingFilters.get(i);
7213                int targetUserId = filter.getTargetUserId();
7214                boolean skipCurrentProfile =
7215                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7216                boolean skipCurrentProfileIfNoMatchFound =
7217                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7218                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7219                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7220                    // Checking if there are activities in the target user that can handle the
7221                    // intent.
7222                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7223                            resolvedType, flags, sourceUserId);
7224                    if (resolveInfo != null) return resolveInfo;
7225                    alreadyTriedUserIds.put(targetUserId, true);
7226                }
7227            }
7228        }
7229        return null;
7230    }
7231
7232    /**
7233     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7234     * will forward the intent to the filter's target user.
7235     * Otherwise, returns null.
7236     */
7237    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7238            String resolvedType, int flags, int sourceUserId) {
7239        int targetUserId = filter.getTargetUserId();
7240        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7241                resolvedType, flags, targetUserId);
7242        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7243            // If all the matches in the target profile are suspended, return null.
7244            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7245                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7246                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7247                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7248                            targetUserId);
7249                }
7250            }
7251        }
7252        return null;
7253    }
7254
7255    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7256            int sourceUserId, int targetUserId) {
7257        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7258        long ident = Binder.clearCallingIdentity();
7259        boolean targetIsProfile;
7260        try {
7261            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7262        } finally {
7263            Binder.restoreCallingIdentity(ident);
7264        }
7265        String className;
7266        if (targetIsProfile) {
7267            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7268        } else {
7269            className = FORWARD_INTENT_TO_PARENT;
7270        }
7271        ComponentName forwardingActivityComponentName = new ComponentName(
7272                mAndroidApplication.packageName, className);
7273        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7274                sourceUserId);
7275        if (!targetIsProfile) {
7276            forwardingActivityInfo.showUserIcon = targetUserId;
7277            forwardingResolveInfo.noResourceId = true;
7278        }
7279        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7280        forwardingResolveInfo.priority = 0;
7281        forwardingResolveInfo.preferredOrder = 0;
7282        forwardingResolveInfo.match = 0;
7283        forwardingResolveInfo.isDefault = true;
7284        forwardingResolveInfo.filter = filter;
7285        forwardingResolveInfo.targetUserId = targetUserId;
7286        return forwardingResolveInfo;
7287    }
7288
7289    @Override
7290    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7291            Intent[] specifics, String[] specificTypes, Intent intent,
7292            String resolvedType, int flags, int userId) {
7293        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7294                specificTypes, intent, resolvedType, flags, userId));
7295    }
7296
7297    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7298            Intent[] specifics, String[] specificTypes, Intent intent,
7299            String resolvedType, int flags, int userId) {
7300        if (!sUserManager.exists(userId)) return Collections.emptyList();
7301        final int callingUid = Binder.getCallingUid();
7302        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7303                false /*includeInstantApps*/);
7304        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7305                false /*requireFullPermission*/, false /*checkShell*/,
7306                "query intent activity options");
7307        final String resultsAction = intent.getAction();
7308
7309        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7310                | PackageManager.GET_RESOLVED_FILTER, userId);
7311
7312        if (DEBUG_INTENT_MATCHING) {
7313            Log.v(TAG, "Query " + intent + ": " + results);
7314        }
7315
7316        int specificsPos = 0;
7317        int N;
7318
7319        // todo: note that the algorithm used here is O(N^2).  This
7320        // isn't a problem in our current environment, but if we start running
7321        // into situations where we have more than 5 or 10 matches then this
7322        // should probably be changed to something smarter...
7323
7324        // First we go through and resolve each of the specific items
7325        // that were supplied, taking care of removing any corresponding
7326        // duplicate items in the generic resolve list.
7327        if (specifics != null) {
7328            for (int i=0; i<specifics.length; i++) {
7329                final Intent sintent = specifics[i];
7330                if (sintent == null) {
7331                    continue;
7332                }
7333
7334                if (DEBUG_INTENT_MATCHING) {
7335                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7336                }
7337
7338                String action = sintent.getAction();
7339                if (resultsAction != null && resultsAction.equals(action)) {
7340                    // If this action was explicitly requested, then don't
7341                    // remove things that have it.
7342                    action = null;
7343                }
7344
7345                ResolveInfo ri = null;
7346                ActivityInfo ai = null;
7347
7348                ComponentName comp = sintent.getComponent();
7349                if (comp == null) {
7350                    ri = resolveIntent(
7351                        sintent,
7352                        specificTypes != null ? specificTypes[i] : null,
7353                            flags, userId);
7354                    if (ri == null) {
7355                        continue;
7356                    }
7357                    if (ri == mResolveInfo) {
7358                        // ACK!  Must do something better with this.
7359                    }
7360                    ai = ri.activityInfo;
7361                    comp = new ComponentName(ai.applicationInfo.packageName,
7362                            ai.name);
7363                } else {
7364                    ai = getActivityInfo(comp, flags, userId);
7365                    if (ai == null) {
7366                        continue;
7367                    }
7368                }
7369
7370                // Look for any generic query activities that are duplicates
7371                // of this specific one, and remove them from the results.
7372                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7373                N = results.size();
7374                int j;
7375                for (j=specificsPos; j<N; j++) {
7376                    ResolveInfo sri = results.get(j);
7377                    if ((sri.activityInfo.name.equals(comp.getClassName())
7378                            && sri.activityInfo.applicationInfo.packageName.equals(
7379                                    comp.getPackageName()))
7380                        || (action != null && sri.filter.matchAction(action))) {
7381                        results.remove(j);
7382                        if (DEBUG_INTENT_MATCHING) Log.v(
7383                            TAG, "Removing duplicate item from " + j
7384                            + " due to specific " + specificsPos);
7385                        if (ri == null) {
7386                            ri = sri;
7387                        }
7388                        j--;
7389                        N--;
7390                    }
7391                }
7392
7393                // Add this specific item to its proper place.
7394                if (ri == null) {
7395                    ri = new ResolveInfo();
7396                    ri.activityInfo = ai;
7397                }
7398                results.add(specificsPos, ri);
7399                ri.specificIndex = i;
7400                specificsPos++;
7401            }
7402        }
7403
7404        // Now we go through the remaining generic results and remove any
7405        // duplicate actions that are found here.
7406        N = results.size();
7407        for (int i=specificsPos; i<N-1; i++) {
7408            final ResolveInfo rii = results.get(i);
7409            if (rii.filter == null) {
7410                continue;
7411            }
7412
7413            // Iterate over all of the actions of this result's intent
7414            // filter...  typically this should be just one.
7415            final Iterator<String> it = rii.filter.actionsIterator();
7416            if (it == null) {
7417                continue;
7418            }
7419            while (it.hasNext()) {
7420                final String action = it.next();
7421                if (resultsAction != null && resultsAction.equals(action)) {
7422                    // If this action was explicitly requested, then don't
7423                    // remove things that have it.
7424                    continue;
7425                }
7426                for (int j=i+1; j<N; j++) {
7427                    final ResolveInfo rij = results.get(j);
7428                    if (rij.filter != null && rij.filter.hasAction(action)) {
7429                        results.remove(j);
7430                        if (DEBUG_INTENT_MATCHING) Log.v(
7431                            TAG, "Removing duplicate item from " + j
7432                            + " due to action " + action + " at " + i);
7433                        j--;
7434                        N--;
7435                    }
7436                }
7437            }
7438
7439            // If the caller didn't request filter information, drop it now
7440            // so we don't have to marshall/unmarshall it.
7441            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7442                rii.filter = null;
7443            }
7444        }
7445
7446        // Filter out the caller activity if so requested.
7447        if (caller != null) {
7448            N = results.size();
7449            for (int i=0; i<N; i++) {
7450                ActivityInfo ainfo = results.get(i).activityInfo;
7451                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7452                        && caller.getClassName().equals(ainfo.name)) {
7453                    results.remove(i);
7454                    break;
7455                }
7456            }
7457        }
7458
7459        // If the caller didn't request filter information,
7460        // drop them now so we don't have to
7461        // marshall/unmarshall it.
7462        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7463            N = results.size();
7464            for (int i=0; i<N; i++) {
7465                results.get(i).filter = null;
7466            }
7467        }
7468
7469        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7470        return results;
7471    }
7472
7473    @Override
7474    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7475            String resolvedType, int flags, int userId) {
7476        return new ParceledListSlice<>(
7477                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7478                        false /*allowDynamicSplits*/));
7479    }
7480
7481    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7482            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7483        if (!sUserManager.exists(userId)) return Collections.emptyList();
7484        final int callingUid = Binder.getCallingUid();
7485        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7486                false /*requireFullPermission*/, false /*checkShell*/,
7487                "query intent receivers");
7488        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7489        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7490                false /*includeInstantApps*/);
7491        ComponentName comp = intent.getComponent();
7492        if (comp == null) {
7493            if (intent.getSelector() != null) {
7494                intent = intent.getSelector();
7495                comp = intent.getComponent();
7496            }
7497        }
7498        if (comp != null) {
7499            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7500            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7501            if (ai != null) {
7502                // When specifying an explicit component, we prevent the activity from being
7503                // used when either 1) the calling package is normal and the activity is within
7504                // an instant application or 2) the calling package is ephemeral and the
7505                // activity is not visible to instant applications.
7506                final boolean matchInstantApp =
7507                        (flags & PackageManager.MATCH_INSTANT) != 0;
7508                final boolean matchVisibleToInstantAppOnly =
7509                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7510                final boolean matchExplicitlyVisibleOnly =
7511                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7512                final boolean isCallerInstantApp =
7513                        instantAppPkgName != null;
7514                final boolean isTargetSameInstantApp =
7515                        comp.getPackageName().equals(instantAppPkgName);
7516                final boolean isTargetInstantApp =
7517                        (ai.applicationInfo.privateFlags
7518                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7519                final boolean isTargetVisibleToInstantApp =
7520                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7521                final boolean isTargetExplicitlyVisibleToInstantApp =
7522                        isTargetVisibleToInstantApp
7523                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7524                final boolean isTargetHiddenFromInstantApp =
7525                        !isTargetVisibleToInstantApp
7526                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7527                final boolean blockResolution =
7528                        !isTargetSameInstantApp
7529                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7530                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7531                                        && isTargetHiddenFromInstantApp));
7532                if (!blockResolution) {
7533                    ResolveInfo ri = new ResolveInfo();
7534                    ri.activityInfo = ai;
7535                    list.add(ri);
7536                }
7537            }
7538            return applyPostResolutionFilter(
7539                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7540        }
7541
7542        // reader
7543        synchronized (mPackages) {
7544            String pkgName = intent.getPackage();
7545            if (pkgName == null) {
7546                final List<ResolveInfo> result =
7547                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7548                return applyPostResolutionFilter(
7549                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7550            }
7551            final PackageParser.Package pkg = mPackages.get(pkgName);
7552            if (pkg != null) {
7553                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7554                        intent, resolvedType, flags, pkg.receivers, userId);
7555                return applyPostResolutionFilter(
7556                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7557            }
7558            return Collections.emptyList();
7559        }
7560    }
7561
7562    @Override
7563    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7564        final int callingUid = Binder.getCallingUid();
7565        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7566    }
7567
7568    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7569            int userId, int callingUid) {
7570        if (!sUserManager.exists(userId)) return null;
7571        flags = updateFlagsForResolve(
7572                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7573        List<ResolveInfo> query = queryIntentServicesInternal(
7574                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7575        if (query != null) {
7576            if (query.size() >= 1) {
7577                // If there is more than one service with the same priority,
7578                // just arbitrarily pick the first one.
7579                return query.get(0);
7580            }
7581        }
7582        return null;
7583    }
7584
7585    @Override
7586    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7587            String resolvedType, int flags, int userId) {
7588        final int callingUid = Binder.getCallingUid();
7589        return new ParceledListSlice<>(queryIntentServicesInternal(
7590                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7591    }
7592
7593    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7594            String resolvedType, int flags, int userId, int callingUid,
7595            boolean includeInstantApps) {
7596        if (!sUserManager.exists(userId)) return Collections.emptyList();
7597        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7598                false /*requireFullPermission*/, false /*checkShell*/,
7599                "query intent receivers");
7600        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7601        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7602        ComponentName comp = intent.getComponent();
7603        if (comp == null) {
7604            if (intent.getSelector() != null) {
7605                intent = intent.getSelector();
7606                comp = intent.getComponent();
7607            }
7608        }
7609        if (comp != null) {
7610            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7611            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7612            if (si != null) {
7613                // When specifying an explicit component, we prevent the service from being
7614                // used when either 1) the service is in an instant application and the
7615                // caller is not the same instant application or 2) the calling package is
7616                // ephemeral and the activity is not visible to ephemeral applications.
7617                final boolean matchInstantApp =
7618                        (flags & PackageManager.MATCH_INSTANT) != 0;
7619                final boolean matchVisibleToInstantAppOnly =
7620                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7621                final boolean isCallerInstantApp =
7622                        instantAppPkgName != null;
7623                final boolean isTargetSameInstantApp =
7624                        comp.getPackageName().equals(instantAppPkgName);
7625                final boolean isTargetInstantApp =
7626                        (si.applicationInfo.privateFlags
7627                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7628                final boolean isTargetHiddenFromInstantApp =
7629                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7630                final boolean blockResolution =
7631                        !isTargetSameInstantApp
7632                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7633                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7634                                        && isTargetHiddenFromInstantApp));
7635                if (!blockResolution) {
7636                    final ResolveInfo ri = new ResolveInfo();
7637                    ri.serviceInfo = si;
7638                    list.add(ri);
7639                }
7640            }
7641            return list;
7642        }
7643
7644        // reader
7645        synchronized (mPackages) {
7646            String pkgName = intent.getPackage();
7647            if (pkgName == null) {
7648                return applyPostServiceResolutionFilter(
7649                        mServices.queryIntent(intent, resolvedType, flags, userId),
7650                        instantAppPkgName);
7651            }
7652            final PackageParser.Package pkg = mPackages.get(pkgName);
7653            if (pkg != null) {
7654                return applyPostServiceResolutionFilter(
7655                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7656                                userId),
7657                        instantAppPkgName);
7658            }
7659            return Collections.emptyList();
7660        }
7661    }
7662
7663    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7664            String instantAppPkgName) {
7665        if (instantAppPkgName == null) {
7666            return resolveInfos;
7667        }
7668        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7669            final ResolveInfo info = resolveInfos.get(i);
7670            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7671            // allow services that are defined in the provided package
7672            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7673                if (info.serviceInfo.splitName != null
7674                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7675                                info.serviceInfo.splitName)) {
7676                    // requested service is defined in a split that hasn't been installed yet.
7677                    // add the installer to the resolve list
7678                    if (DEBUG_INSTANT) {
7679                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7680                    }
7681                    final ResolveInfo installerInfo = new ResolveInfo(
7682                            mInstantAppInstallerInfo);
7683                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7684                            null /* installFailureActivity */,
7685                            info.serviceInfo.packageName,
7686                            info.serviceInfo.applicationInfo.versionCode,
7687                            info.serviceInfo.splitName);
7688                    // add a non-generic filter
7689                    installerInfo.filter = new IntentFilter();
7690                    // load resources from the correct package
7691                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7692                    resolveInfos.set(i, installerInfo);
7693                }
7694                continue;
7695            }
7696            // allow services that have been explicitly exposed to ephemeral apps
7697            if (!isEphemeralApp
7698                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7699                continue;
7700            }
7701            resolveInfos.remove(i);
7702        }
7703        return resolveInfos;
7704    }
7705
7706    @Override
7707    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7708            String resolvedType, int flags, int userId) {
7709        return new ParceledListSlice<>(
7710                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7711    }
7712
7713    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7714            Intent intent, String resolvedType, int flags, int userId) {
7715        if (!sUserManager.exists(userId)) return Collections.emptyList();
7716        final int callingUid = Binder.getCallingUid();
7717        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7718        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7719                false /*includeInstantApps*/);
7720        ComponentName comp = intent.getComponent();
7721        if (comp == null) {
7722            if (intent.getSelector() != null) {
7723                intent = intent.getSelector();
7724                comp = intent.getComponent();
7725            }
7726        }
7727        if (comp != null) {
7728            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7729            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7730            if (pi != null) {
7731                // When specifying an explicit component, we prevent the provider from being
7732                // used when either 1) the provider is in an instant application and the
7733                // caller is not the same instant application or 2) the calling package is an
7734                // instant application and the provider is not visible to instant applications.
7735                final boolean matchInstantApp =
7736                        (flags & PackageManager.MATCH_INSTANT) != 0;
7737                final boolean matchVisibleToInstantAppOnly =
7738                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7739                final boolean isCallerInstantApp =
7740                        instantAppPkgName != null;
7741                final boolean isTargetSameInstantApp =
7742                        comp.getPackageName().equals(instantAppPkgName);
7743                final boolean isTargetInstantApp =
7744                        (pi.applicationInfo.privateFlags
7745                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7746                final boolean isTargetHiddenFromInstantApp =
7747                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7748                final boolean blockResolution =
7749                        !isTargetSameInstantApp
7750                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7751                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7752                                        && isTargetHiddenFromInstantApp));
7753                if (!blockResolution) {
7754                    final ResolveInfo ri = new ResolveInfo();
7755                    ri.providerInfo = pi;
7756                    list.add(ri);
7757                }
7758            }
7759            return list;
7760        }
7761
7762        // reader
7763        synchronized (mPackages) {
7764            String pkgName = intent.getPackage();
7765            if (pkgName == null) {
7766                return applyPostContentProviderResolutionFilter(
7767                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7768                        instantAppPkgName);
7769            }
7770            final PackageParser.Package pkg = mPackages.get(pkgName);
7771            if (pkg != null) {
7772                return applyPostContentProviderResolutionFilter(
7773                        mProviders.queryIntentForPackage(
7774                        intent, resolvedType, flags, pkg.providers, userId),
7775                        instantAppPkgName);
7776            }
7777            return Collections.emptyList();
7778        }
7779    }
7780
7781    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7782            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7783        if (instantAppPkgName == null) {
7784            return resolveInfos;
7785        }
7786        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7787            final ResolveInfo info = resolveInfos.get(i);
7788            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7789            // allow providers that are defined in the provided package
7790            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7791                if (info.providerInfo.splitName != null
7792                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7793                                info.providerInfo.splitName)) {
7794                    // requested provider is defined in a split that hasn't been installed yet.
7795                    // add the installer to the resolve list
7796                    if (DEBUG_INSTANT) {
7797                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7798                    }
7799                    final ResolveInfo installerInfo = new ResolveInfo(
7800                            mInstantAppInstallerInfo);
7801                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7802                            null /*failureActivity*/,
7803                            info.providerInfo.packageName,
7804                            info.providerInfo.applicationInfo.versionCode,
7805                            info.providerInfo.splitName);
7806                    // add a non-generic filter
7807                    installerInfo.filter = new IntentFilter();
7808                    // load resources from the correct package
7809                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7810                    resolveInfos.set(i, installerInfo);
7811                }
7812                continue;
7813            }
7814            // allow providers that have been explicitly exposed to instant applications
7815            if (!isEphemeralApp
7816                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7817                continue;
7818            }
7819            resolveInfos.remove(i);
7820        }
7821        return resolveInfos;
7822    }
7823
7824    @Override
7825    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7826        final int callingUid = Binder.getCallingUid();
7827        if (getInstantAppPackageName(callingUid) != null) {
7828            return ParceledListSlice.emptyList();
7829        }
7830        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7831        flags = updateFlagsForPackage(flags, userId, null);
7832        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7833        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7834                true /* requireFullPermission */, false /* checkShell */,
7835                "get installed packages");
7836
7837        // writer
7838        synchronized (mPackages) {
7839            ArrayList<PackageInfo> list;
7840            if (listUninstalled) {
7841                list = new ArrayList<>(mSettings.mPackages.size());
7842                for (PackageSetting ps : mSettings.mPackages.values()) {
7843                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7844                        continue;
7845                    }
7846                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7847                        continue;
7848                    }
7849                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7850                    if (pi != null) {
7851                        list.add(pi);
7852                    }
7853                }
7854            } else {
7855                list = new ArrayList<>(mPackages.size());
7856                for (PackageParser.Package p : mPackages.values()) {
7857                    final PackageSetting ps = (PackageSetting) p.mExtras;
7858                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7859                        continue;
7860                    }
7861                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7862                        continue;
7863                    }
7864                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7865                            p.mExtras, flags, userId);
7866                    if (pi != null) {
7867                        list.add(pi);
7868                    }
7869                }
7870            }
7871
7872            return new ParceledListSlice<>(list);
7873        }
7874    }
7875
7876    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7877            String[] permissions, boolean[] tmp, int flags, int userId) {
7878        int numMatch = 0;
7879        final PermissionsState permissionsState = ps.getPermissionsState();
7880        for (int i=0; i<permissions.length; i++) {
7881            final String permission = permissions[i];
7882            if (permissionsState.hasPermission(permission, userId)) {
7883                tmp[i] = true;
7884                numMatch++;
7885            } else {
7886                tmp[i] = false;
7887            }
7888        }
7889        if (numMatch == 0) {
7890            return;
7891        }
7892        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7893
7894        // The above might return null in cases of uninstalled apps or install-state
7895        // skew across users/profiles.
7896        if (pi != null) {
7897            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7898                if (numMatch == permissions.length) {
7899                    pi.requestedPermissions = permissions;
7900                } else {
7901                    pi.requestedPermissions = new String[numMatch];
7902                    numMatch = 0;
7903                    for (int i=0; i<permissions.length; i++) {
7904                        if (tmp[i]) {
7905                            pi.requestedPermissions[numMatch] = permissions[i];
7906                            numMatch++;
7907                        }
7908                    }
7909                }
7910            }
7911            list.add(pi);
7912        }
7913    }
7914
7915    @Override
7916    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7917            String[] permissions, int flags, int userId) {
7918        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7919        flags = updateFlagsForPackage(flags, userId, permissions);
7920        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7921                true /* requireFullPermission */, false /* checkShell */,
7922                "get packages holding permissions");
7923        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7924
7925        // writer
7926        synchronized (mPackages) {
7927            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7928            boolean[] tmpBools = new boolean[permissions.length];
7929            if (listUninstalled) {
7930                for (PackageSetting ps : mSettings.mPackages.values()) {
7931                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7932                            userId);
7933                }
7934            } else {
7935                for (PackageParser.Package pkg : mPackages.values()) {
7936                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7937                    if (ps != null) {
7938                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7939                                userId);
7940                    }
7941                }
7942            }
7943
7944            return new ParceledListSlice<PackageInfo>(list);
7945        }
7946    }
7947
7948    @Override
7949    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7950        final int callingUid = Binder.getCallingUid();
7951        if (getInstantAppPackageName(callingUid) != null) {
7952            return ParceledListSlice.emptyList();
7953        }
7954        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7955        flags = updateFlagsForApplication(flags, userId, null);
7956        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7957
7958        // writer
7959        synchronized (mPackages) {
7960            ArrayList<ApplicationInfo> list;
7961            if (listUninstalled) {
7962                list = new ArrayList<>(mSettings.mPackages.size());
7963                for (PackageSetting ps : mSettings.mPackages.values()) {
7964                    ApplicationInfo ai;
7965                    int effectiveFlags = flags;
7966                    if (ps.isSystem()) {
7967                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7968                    }
7969                    if (ps.pkg != null) {
7970                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7971                            continue;
7972                        }
7973                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7974                            continue;
7975                        }
7976                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7977                                ps.readUserState(userId), userId);
7978                        if (ai != null) {
7979                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7980                        }
7981                    } else {
7982                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7983                        // and already converts to externally visible package name
7984                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7985                                callingUid, effectiveFlags, userId);
7986                    }
7987                    if (ai != null) {
7988                        list.add(ai);
7989                    }
7990                }
7991            } else {
7992                list = new ArrayList<>(mPackages.size());
7993                for (PackageParser.Package p : mPackages.values()) {
7994                    if (p.mExtras != null) {
7995                        PackageSetting ps = (PackageSetting) p.mExtras;
7996                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7997                            continue;
7998                        }
7999                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8000                            continue;
8001                        }
8002                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8003                                ps.readUserState(userId), userId);
8004                        if (ai != null) {
8005                            ai.packageName = resolveExternalPackageNameLPr(p);
8006                            list.add(ai);
8007                        }
8008                    }
8009                }
8010            }
8011
8012            return new ParceledListSlice<>(list);
8013        }
8014    }
8015
8016    @Override
8017    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8018        if (HIDE_EPHEMERAL_APIS) {
8019            return null;
8020        }
8021        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8022            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8023                    "getEphemeralApplications");
8024        }
8025        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8026                true /* requireFullPermission */, false /* checkShell */,
8027                "getEphemeralApplications");
8028        synchronized (mPackages) {
8029            List<InstantAppInfo> instantApps = mInstantAppRegistry
8030                    .getInstantAppsLPr(userId);
8031            if (instantApps != null) {
8032                return new ParceledListSlice<>(instantApps);
8033            }
8034        }
8035        return null;
8036    }
8037
8038    @Override
8039    public boolean isInstantApp(String packageName, int userId) {
8040        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8041                true /* requireFullPermission */, false /* checkShell */,
8042                "isInstantApp");
8043        if (HIDE_EPHEMERAL_APIS) {
8044            return false;
8045        }
8046
8047        synchronized (mPackages) {
8048            int callingUid = Binder.getCallingUid();
8049            if (Process.isIsolated(callingUid)) {
8050                callingUid = mIsolatedOwners.get(callingUid);
8051            }
8052            final PackageSetting ps = mSettings.mPackages.get(packageName);
8053            PackageParser.Package pkg = mPackages.get(packageName);
8054            final boolean returnAllowed =
8055                    ps != null
8056                    && (isCallerSameApp(packageName, callingUid)
8057                            || canViewInstantApps(callingUid, userId)
8058                            || mInstantAppRegistry.isInstantAccessGranted(
8059                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8060            if (returnAllowed) {
8061                return ps.getInstantApp(userId);
8062            }
8063        }
8064        return false;
8065    }
8066
8067    @Override
8068    public byte[] getInstantAppCookie(String packageName, int userId) {
8069        if (HIDE_EPHEMERAL_APIS) {
8070            return null;
8071        }
8072
8073        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8074                true /* requireFullPermission */, false /* checkShell */,
8075                "getInstantAppCookie");
8076        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8077            return null;
8078        }
8079        synchronized (mPackages) {
8080            return mInstantAppRegistry.getInstantAppCookieLPw(
8081                    packageName, userId);
8082        }
8083    }
8084
8085    @Override
8086    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8087        if (HIDE_EPHEMERAL_APIS) {
8088            return true;
8089        }
8090
8091        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8092                true /* requireFullPermission */, true /* checkShell */,
8093                "setInstantAppCookie");
8094        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8095            return false;
8096        }
8097        synchronized (mPackages) {
8098            return mInstantAppRegistry.setInstantAppCookieLPw(
8099                    packageName, cookie, userId);
8100        }
8101    }
8102
8103    @Override
8104    public Bitmap getInstantAppIcon(String packageName, int userId) {
8105        if (HIDE_EPHEMERAL_APIS) {
8106            return null;
8107        }
8108
8109        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8110            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8111                    "getInstantAppIcon");
8112        }
8113        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8114                true /* requireFullPermission */, false /* checkShell */,
8115                "getInstantAppIcon");
8116
8117        synchronized (mPackages) {
8118            return mInstantAppRegistry.getInstantAppIconLPw(
8119                    packageName, userId);
8120        }
8121    }
8122
8123    private boolean isCallerSameApp(String packageName, int uid) {
8124        PackageParser.Package pkg = mPackages.get(packageName);
8125        return pkg != null
8126                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8127    }
8128
8129    @Override
8130    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8131        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8132            return ParceledListSlice.emptyList();
8133        }
8134        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8135    }
8136
8137    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8138        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8139
8140        // reader
8141        synchronized (mPackages) {
8142            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8143            final int userId = UserHandle.getCallingUserId();
8144            while (i.hasNext()) {
8145                final PackageParser.Package p = i.next();
8146                if (p.applicationInfo == null) continue;
8147
8148                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8149                        && !p.applicationInfo.isDirectBootAware();
8150                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8151                        && p.applicationInfo.isDirectBootAware();
8152
8153                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8154                        && (!mSafeMode || isSystemApp(p))
8155                        && (matchesUnaware || matchesAware)) {
8156                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8157                    if (ps != null) {
8158                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8159                                ps.readUserState(userId), userId);
8160                        if (ai != null) {
8161                            finalList.add(ai);
8162                        }
8163                    }
8164                }
8165            }
8166        }
8167
8168        return finalList;
8169    }
8170
8171    @Override
8172    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8173        return resolveContentProviderInternal(name, flags, userId);
8174    }
8175
8176    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8177        if (!sUserManager.exists(userId)) return null;
8178        flags = updateFlagsForComponent(flags, userId, name);
8179        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8180        // reader
8181        synchronized (mPackages) {
8182            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8183            PackageSetting ps = provider != null
8184                    ? mSettings.mPackages.get(provider.owner.packageName)
8185                    : null;
8186            if (ps != null) {
8187                final boolean isInstantApp = ps.getInstantApp(userId);
8188                // normal application; filter out instant application provider
8189                if (instantAppPkgName == null && isInstantApp) {
8190                    return null;
8191                }
8192                // instant application; filter out other instant applications
8193                if (instantAppPkgName != null
8194                        && isInstantApp
8195                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8196                    return null;
8197                }
8198                // instant application; filter out non-exposed provider
8199                if (instantAppPkgName != null
8200                        && !isInstantApp
8201                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8202                    return null;
8203                }
8204                // provider not enabled
8205                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8206                    return null;
8207                }
8208                return PackageParser.generateProviderInfo(
8209                        provider, flags, ps.readUserState(userId), userId);
8210            }
8211            return null;
8212        }
8213    }
8214
8215    /**
8216     * @deprecated
8217     */
8218    @Deprecated
8219    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8220        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8221            return;
8222        }
8223        // reader
8224        synchronized (mPackages) {
8225            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8226                    .entrySet().iterator();
8227            final int userId = UserHandle.getCallingUserId();
8228            while (i.hasNext()) {
8229                Map.Entry<String, PackageParser.Provider> entry = i.next();
8230                PackageParser.Provider p = entry.getValue();
8231                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8232
8233                if (ps != null && p.syncable
8234                        && (!mSafeMode || (p.info.applicationInfo.flags
8235                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8236                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8237                            ps.readUserState(userId), userId);
8238                    if (info != null) {
8239                        outNames.add(entry.getKey());
8240                        outInfo.add(info);
8241                    }
8242                }
8243            }
8244        }
8245    }
8246
8247    @Override
8248    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8249            int uid, int flags, String metaDataKey) {
8250        final int callingUid = Binder.getCallingUid();
8251        final int userId = processName != null ? UserHandle.getUserId(uid)
8252                : UserHandle.getCallingUserId();
8253        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8254        flags = updateFlagsForComponent(flags, userId, processName);
8255        ArrayList<ProviderInfo> finalList = null;
8256        // reader
8257        synchronized (mPackages) {
8258            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8259            while (i.hasNext()) {
8260                final PackageParser.Provider p = i.next();
8261                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8262                if (ps != null && p.info.authority != null
8263                        && (processName == null
8264                                || (p.info.processName.equals(processName)
8265                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8266                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8267
8268                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8269                    // parameter.
8270                    if (metaDataKey != null
8271                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8272                        continue;
8273                    }
8274                    final ComponentName component =
8275                            new ComponentName(p.info.packageName, p.info.name);
8276                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8277                        continue;
8278                    }
8279                    if (finalList == null) {
8280                        finalList = new ArrayList<ProviderInfo>(3);
8281                    }
8282                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8283                            ps.readUserState(userId), userId);
8284                    if (info != null) {
8285                        finalList.add(info);
8286                    }
8287                }
8288            }
8289        }
8290
8291        if (finalList != null) {
8292            Collections.sort(finalList, mProviderInitOrderSorter);
8293            return new ParceledListSlice<ProviderInfo>(finalList);
8294        }
8295
8296        return ParceledListSlice.emptyList();
8297    }
8298
8299    @Override
8300    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8301        // reader
8302        synchronized (mPackages) {
8303            final int callingUid = Binder.getCallingUid();
8304            final int callingUserId = UserHandle.getUserId(callingUid);
8305            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8306            if (ps == null) return null;
8307            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8308                return null;
8309            }
8310            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8311            return PackageParser.generateInstrumentationInfo(i, flags);
8312        }
8313    }
8314
8315    @Override
8316    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8317            String targetPackage, int flags) {
8318        final int callingUid = Binder.getCallingUid();
8319        final int callingUserId = UserHandle.getUserId(callingUid);
8320        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8321        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8322            return ParceledListSlice.emptyList();
8323        }
8324        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8325    }
8326
8327    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8328            int flags) {
8329        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8330
8331        // reader
8332        synchronized (mPackages) {
8333            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8334            while (i.hasNext()) {
8335                final PackageParser.Instrumentation p = i.next();
8336                if (targetPackage == null
8337                        || targetPackage.equals(p.info.targetPackage)) {
8338                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8339                            flags);
8340                    if (ii != null) {
8341                        finalList.add(ii);
8342                    }
8343                }
8344            }
8345        }
8346
8347        return finalList;
8348    }
8349
8350    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8351        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8352        try {
8353            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8354        } finally {
8355            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8356        }
8357    }
8358
8359    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8360        final File[] files = scanDir.listFiles();
8361        if (ArrayUtils.isEmpty(files)) {
8362            Log.d(TAG, "No files in app dir " + scanDir);
8363            return;
8364        }
8365
8366        if (DEBUG_PACKAGE_SCANNING) {
8367            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8368                    + " flags=0x" + Integer.toHexString(parseFlags));
8369        }
8370        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8371                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8372                mParallelPackageParserCallback)) {
8373            // Submit files for parsing in parallel
8374            int fileCount = 0;
8375            for (File file : files) {
8376                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8377                        && !PackageInstallerService.isStageName(file.getName());
8378                if (!isPackage) {
8379                    // Ignore entries which are not packages
8380                    continue;
8381                }
8382                parallelPackageParser.submit(file, parseFlags);
8383                fileCount++;
8384            }
8385
8386            // Process results one by one
8387            for (; fileCount > 0; fileCount--) {
8388                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8389                Throwable throwable = parseResult.throwable;
8390                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8391
8392                if (throwable == null) {
8393                    // TODO(toddke): move lower in the scan chain
8394                    // Static shared libraries have synthetic package names
8395                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8396                        renameStaticSharedLibraryPackage(parseResult.pkg);
8397                    }
8398                    try {
8399                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8400                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8401                                    currentTime, null);
8402                        }
8403                    } catch (PackageManagerException e) {
8404                        errorCode = e.error;
8405                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8406                    }
8407                } else if (throwable instanceof PackageParser.PackageParserException) {
8408                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8409                            throwable;
8410                    errorCode = e.error;
8411                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8412                } else {
8413                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8414                            + parseResult.scanFile, throwable);
8415                }
8416
8417                // Delete invalid userdata apps
8418                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8419                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8420                    logCriticalInfo(Log.WARN,
8421                            "Deleting invalid package at " + parseResult.scanFile);
8422                    removeCodePathLI(parseResult.scanFile);
8423                }
8424            }
8425        }
8426    }
8427
8428    public static void reportSettingsProblem(int priority, String msg) {
8429        logCriticalInfo(priority, msg);
8430    }
8431
8432    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8433            boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8434        // When upgrading from pre-N MR1, verify the package time stamp using the package
8435        // directory and not the APK file.
8436        final long lastModifiedTime = mIsPreNMR1Upgrade
8437                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8438        if (ps != null && !forceCollect
8439                && ps.codePathString.equals(pkg.codePath)
8440                && ps.timeStamp == lastModifiedTime
8441                && !isCompatSignatureUpdateNeeded(pkg)
8442                && !isRecoverSignatureUpdateNeeded(pkg)) {
8443            if (ps.signatures.mSigningDetails.signatures != null
8444                    && ps.signatures.mSigningDetails.signatures.length != 0
8445                    && ps.signatures.mSigningDetails.signatureSchemeVersion
8446                            != SignatureSchemeVersion.UNKNOWN) {
8447                // Optimization: reuse the existing cached signing data
8448                // if the package appears to be unchanged.
8449                pkg.mSigningDetails =
8450                        new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
8451                return;
8452            }
8453
8454            Slog.w(TAG, "PackageSetting for " + ps.name
8455                    + " is missing signatures.  Collecting certs again to recover them.");
8456        } else {
8457            Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8458                    (forceCollect ? " (forced)" : ""));
8459        }
8460
8461        try {
8462            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8463            PackageParser.collectCertificates(pkg, skipVerify);
8464        } catch (PackageParserException e) {
8465            throw PackageManagerException.from(e);
8466        } finally {
8467            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8468        }
8469    }
8470
8471    /**
8472     *  Traces a package scan.
8473     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8474     */
8475    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8476            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8477        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8478        try {
8479            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8480        } finally {
8481            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8482        }
8483    }
8484
8485    /**
8486     *  Scans a package and returns the newly parsed package.
8487     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8488     */
8489    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8490            long currentTime, UserHandle user) throws PackageManagerException {
8491        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8492        PackageParser pp = new PackageParser();
8493        pp.setSeparateProcesses(mSeparateProcesses);
8494        pp.setOnlyCoreApps(mOnlyCore);
8495        pp.setDisplayMetrics(mMetrics);
8496        pp.setCallback(mPackageParserCallback);
8497
8498        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8499        final PackageParser.Package pkg;
8500        try {
8501            pkg = pp.parsePackage(scanFile, parseFlags);
8502        } catch (PackageParserException e) {
8503            throw PackageManagerException.from(e);
8504        } finally {
8505            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8506        }
8507
8508        // Static shared libraries have synthetic package names
8509        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8510            renameStaticSharedLibraryPackage(pkg);
8511        }
8512
8513        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8514    }
8515
8516    /**
8517     *  Scans a package and returns the newly parsed package.
8518     *  @throws PackageManagerException on a parse error.
8519     */
8520    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8521            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8522            @Nullable UserHandle user)
8523                    throws PackageManagerException {
8524        // If the package has children and this is the first dive in the function
8525        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8526        // packages (parent and children) would be successfully scanned before the
8527        // actual scan since scanning mutates internal state and we want to atomically
8528        // install the package and its children.
8529        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8530            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8531                scanFlags |= SCAN_CHECK_ONLY;
8532            }
8533        } else {
8534            scanFlags &= ~SCAN_CHECK_ONLY;
8535        }
8536
8537        // Scan the parent
8538        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8539                scanFlags, currentTime, user);
8540
8541        // Scan the children
8542        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8543        for (int i = 0; i < childCount; i++) {
8544            PackageParser.Package childPackage = pkg.childPackages.get(i);
8545            addForInitLI(childPackage, parseFlags, scanFlags,
8546                    currentTime, user);
8547        }
8548
8549
8550        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8551            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8552        }
8553
8554        return scannedPkg;
8555    }
8556
8557    /**
8558     * Returns if full apk verification can be skipped for the whole package, including the splits.
8559     */
8560    private boolean canSkipFullPackageVerification(PackageParser.Package pkg) {
8561        if (!canSkipFullApkVerification(pkg.baseCodePath)) {
8562            return false;
8563        }
8564        // TODO: Allow base and splits to be verified individually.
8565        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8566            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8567                if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) {
8568                    return false;
8569                }
8570            }
8571        }
8572        return true;
8573    }
8574
8575    /**
8576     * Returns if full apk verification can be skipped, depending on current FSVerity setup and
8577     * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
8578     * match one in a trusted source, and should be done separately.
8579     */
8580    private boolean canSkipFullApkVerification(String apkPath) {
8581        byte[] rootHashObserved = null;
8582        try {
8583            rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
8584            if (rootHashObserved == null) {
8585                return false;  // APK does not contain Merkle tree root hash.
8586            }
8587            synchronized (mInstallLock) {
8588                // Returns whether the observed root hash matches what kernel has.
8589                mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8590                return true;
8591            }
8592        } catch (InstallerException | IOException | DigestException |
8593                NoSuchAlgorithmException e) {
8594            Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8595        }
8596        return false;
8597    }
8598
8599    /**
8600     * Adds a new package to the internal data structures during platform initialization.
8601     * <p>After adding, the package is known to the system and available for querying.
8602     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8603     * etc...], additional checks are performed. Basic verification [such as ensuring
8604     * matching signatures, checking version codes, etc...] occurs if the package is
8605     * identical to a previously known package. If the package fails a signature check,
8606     * the version installed on /data will be removed. If the version of the new package
8607     * is less than or equal than the version on /data, it will be ignored.
8608     * <p>Regardless of the package location, the results are applied to the internal
8609     * structures and the package is made available to the rest of the system.
8610     * <p>NOTE: The return value should be removed. It's the passed in package object.
8611     */
8612    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8613            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8614            @Nullable UserHandle user)
8615                    throws PackageManagerException {
8616        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8617        final String renamedPkgName;
8618        final PackageSetting disabledPkgSetting;
8619        final boolean isSystemPkgUpdated;
8620        final boolean pkgAlreadyExists;
8621        PackageSetting pkgSetting;
8622
8623        // NOTE: installPackageLI() has the same code to setup the package's
8624        // application info. This probably should be done lower in the call
8625        // stack [such as scanPackageOnly()]. However, we verify the application
8626        // info prior to that [in scanPackageNew()] and thus have to setup
8627        // the application info early.
8628        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8629        pkg.setApplicationInfoCodePath(pkg.codePath);
8630        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8631        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8632        pkg.setApplicationInfoResourcePath(pkg.codePath);
8633        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8634        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8635
8636        synchronized (mPackages) {
8637            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8638            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8639            if (realPkgName != null) {
8640                ensurePackageRenamed(pkg, renamedPkgName);
8641            }
8642            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8643            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8644            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8645            pkgAlreadyExists = pkgSetting != null;
8646            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8647            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8648            isSystemPkgUpdated = disabledPkgSetting != null;
8649
8650            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8651                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8652            }
8653
8654            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8655                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8656                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8657                    : null;
8658            if (DEBUG_PACKAGE_SCANNING
8659                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8660                    && sharedUserSetting != null) {
8661                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8662                        + " (uid=" + sharedUserSetting.userId + "):"
8663                        + " packages=" + sharedUserSetting.packages);
8664            }
8665
8666            if (scanSystemPartition) {
8667                // Potentially prune child packages. If the application on the /system
8668                // partition has been updated via OTA, but, is still disabled by a
8669                // version on /data, cycle through all of its children packages and
8670                // remove children that are no longer defined.
8671                if (isSystemPkgUpdated) {
8672                    final int scannedChildCount = (pkg.childPackages != null)
8673                            ? pkg.childPackages.size() : 0;
8674                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8675                            ? disabledPkgSetting.childPackageNames.size() : 0;
8676                    for (int i = 0; i < disabledChildCount; i++) {
8677                        String disabledChildPackageName =
8678                                disabledPkgSetting.childPackageNames.get(i);
8679                        boolean disabledPackageAvailable = false;
8680                        for (int j = 0; j < scannedChildCount; j++) {
8681                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8682                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8683                                disabledPackageAvailable = true;
8684                                break;
8685                            }
8686                        }
8687                        if (!disabledPackageAvailable) {
8688                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8689                        }
8690                    }
8691                    // we're updating the disabled package, so, scan it as the package setting
8692                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
8693                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8694                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8695                            (pkg == mPlatformPackage), user);
8696                    applyPolicy(pkg, parseFlags, scanFlags);
8697                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8698                }
8699            }
8700        }
8701
8702        final boolean newPkgChangedPaths =
8703                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8704        final boolean newPkgVersionGreater =
8705                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8706        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8707                && newPkgChangedPaths && newPkgVersionGreater;
8708        if (isSystemPkgBetter) {
8709            // The version of the application on /system is greater than the version on
8710            // /data. Switch back to the application on /system.
8711            // It's safe to assume the application on /system will correctly scan. If not,
8712            // there won't be a working copy of the application.
8713            synchronized (mPackages) {
8714                // just remove the loaded entries from package lists
8715                mPackages.remove(pkgSetting.name);
8716            }
8717
8718            logCriticalInfo(Log.WARN,
8719                    "System package updated;"
8720                    + " name: " + pkgSetting.name
8721                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8722                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8723
8724            final InstallArgs args = createInstallArgsForExisting(
8725                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8726                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8727            args.cleanUpResourcesLI();
8728            synchronized (mPackages) {
8729                mSettings.enableSystemPackageLPw(pkgSetting.name);
8730            }
8731        }
8732
8733        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8734            // The version of the application on the /system partition is less than or
8735            // equal to the version on the /data partition. Throw an exception and use
8736            // the application already installed on the /data partition.
8737            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8738                    + pkg.codePath + " ignored: updated version " + disabledPkgSetting.versionCode
8739                    + " better than this " + pkg.getLongVersionCode());
8740        }
8741
8742        // Verify certificates against what was last scanned. If it is an updated priv app, we will
8743        // force re-collecting certificate.
8744        final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
8745                disabledPkgSetting);
8746        // Full APK verification can be skipped during certificate collection, only if the file is
8747        // in verified partition, or can be verified on access (when apk verity is enabled). In both
8748        // cases, only data in Signing Block is verified instead of the whole file.
8749        final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
8750                (forceCollect && canSkipFullPackageVerification(pkg));
8751        collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
8752
8753        boolean shouldHideSystemApp = false;
8754        // A new application appeared on /system, but, we already have a copy of
8755        // the application installed on /data.
8756        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8757                && !pkgSetting.isSystem()) {
8758
8759            if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
8760                    PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
8761                logCriticalInfo(Log.WARN,
8762                        "System package signature mismatch;"
8763                        + " name: " + pkgSetting.name);
8764                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8765                        "scanPackageInternalLI")) {
8766                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8767                }
8768                pkgSetting = null;
8769            } else if (newPkgVersionGreater) {
8770                // The application on /system is newer than the application on /data.
8771                // Simply remove the application on /data [keeping application data]
8772                // and replace it with the version on /system.
8773                logCriticalInfo(Log.WARN,
8774                        "System package enabled;"
8775                        + " name: " + pkgSetting.name
8776                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8777                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8778                InstallArgs args = createInstallArgsForExisting(
8779                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8780                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8781                synchronized (mInstallLock) {
8782                    args.cleanUpResourcesLI();
8783                }
8784            } else {
8785                // The application on /system is older than the application on /data. Hide
8786                // the application on /system and the version on /data will be scanned later
8787                // and re-added like an update.
8788                shouldHideSystemApp = true;
8789                logCriticalInfo(Log.INFO,
8790                        "System package disabled;"
8791                        + " name: " + pkgSetting.name
8792                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8793                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8794            }
8795        }
8796
8797        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8798                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8799
8800        if (shouldHideSystemApp) {
8801            synchronized (mPackages) {
8802                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8803            }
8804        }
8805        return scannedPkg;
8806    }
8807
8808    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8809        // Derive the new package synthetic package name
8810        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8811                + pkg.staticSharedLibVersion);
8812    }
8813
8814    private static String fixProcessName(String defProcessName,
8815            String processName) {
8816        if (processName == null) {
8817            return defProcessName;
8818        }
8819        return processName;
8820    }
8821
8822    /**
8823     * Enforces that only the system UID or root's UID can call a method exposed
8824     * via Binder.
8825     *
8826     * @param message used as message if SecurityException is thrown
8827     * @throws SecurityException if the caller is not system or root
8828     */
8829    private static final void enforceSystemOrRoot(String message) {
8830        final int uid = Binder.getCallingUid();
8831        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8832            throw new SecurityException(message);
8833        }
8834    }
8835
8836    @Override
8837    public void performFstrimIfNeeded() {
8838        enforceSystemOrRoot("Only the system can request fstrim");
8839
8840        // Before everything else, see whether we need to fstrim.
8841        try {
8842            IStorageManager sm = PackageHelper.getStorageManager();
8843            if (sm != null) {
8844                boolean doTrim = false;
8845                final long interval = android.provider.Settings.Global.getLong(
8846                        mContext.getContentResolver(),
8847                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8848                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8849                if (interval > 0) {
8850                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8851                    if (timeSinceLast > interval) {
8852                        doTrim = true;
8853                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8854                                + "; running immediately");
8855                    }
8856                }
8857                if (doTrim) {
8858                    final boolean dexOptDialogShown;
8859                    synchronized (mPackages) {
8860                        dexOptDialogShown = mDexOptDialogShown;
8861                    }
8862                    if (!isFirstBoot() && dexOptDialogShown) {
8863                        try {
8864                            ActivityManager.getService().showBootMessage(
8865                                    mContext.getResources().getString(
8866                                            R.string.android_upgrading_fstrim), true);
8867                        } catch (RemoteException e) {
8868                        }
8869                    }
8870                    sm.runMaintenance();
8871                }
8872            } else {
8873                Slog.e(TAG, "storageManager service unavailable!");
8874            }
8875        } catch (RemoteException e) {
8876            // Can't happen; StorageManagerService is local
8877        }
8878    }
8879
8880    @Override
8881    public void updatePackagesIfNeeded() {
8882        enforceSystemOrRoot("Only the system can request package update");
8883
8884        // We need to re-extract after an OTA.
8885        boolean causeUpgrade = isUpgrade();
8886
8887        // First boot or factory reset.
8888        // Note: we also handle devices that are upgrading to N right now as if it is their
8889        //       first boot, as they do not have profile data.
8890        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8891
8892        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8893        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8894
8895        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8896            return;
8897        }
8898
8899        List<PackageParser.Package> pkgs;
8900        synchronized (mPackages) {
8901            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8902        }
8903
8904        final long startTime = System.nanoTime();
8905        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8906                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
8907                    false /* bootComplete */);
8908
8909        final int elapsedTimeSeconds =
8910                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8911
8912        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8913        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8914        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8915        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8916        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8917    }
8918
8919    /*
8920     * Return the prebuilt profile path given a package base code path.
8921     */
8922    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8923        return pkg.baseCodePath + ".prof";
8924    }
8925
8926    /**
8927     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8928     * containing statistics about the invocation. The array consists of three elements,
8929     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8930     * and {@code numberOfPackagesFailed}.
8931     */
8932    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8933            final int compilationReason, boolean bootComplete) {
8934
8935        int numberOfPackagesVisited = 0;
8936        int numberOfPackagesOptimized = 0;
8937        int numberOfPackagesSkipped = 0;
8938        int numberOfPackagesFailed = 0;
8939        final int numberOfPackagesToDexopt = pkgs.size();
8940
8941        for (PackageParser.Package pkg : pkgs) {
8942            numberOfPackagesVisited++;
8943
8944            boolean useProfileForDexopt = false;
8945
8946            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8947                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8948                // that are already compiled.
8949                File profileFile = new File(getPrebuildProfilePath(pkg));
8950                // Copy profile if it exists.
8951                if (profileFile.exists()) {
8952                    try {
8953                        // We could also do this lazily before calling dexopt in
8954                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8955                        // is that we don't have a good way to say "do this only once".
8956                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8957                                pkg.applicationInfo.uid, pkg.packageName,
8958                                ArtManager.getProfileName(null))) {
8959                            Log.e(TAG, "Installer failed to copy system profile!");
8960                        } else {
8961                            // Disabled as this causes speed-profile compilation during first boot
8962                            // even if things are already compiled.
8963                            // useProfileForDexopt = true;
8964                        }
8965                    } catch (Exception e) {
8966                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8967                                e);
8968                    }
8969                } else {
8970                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8971                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8972                    // minimize the number off apps being speed-profile compiled during first boot.
8973                    // The other paths will not change the filter.
8974                    if (disabledPs != null && disabledPs.pkg.isStub) {
8975                        // The package is the stub one, remove the stub suffix to get the normal
8976                        // package and APK names.
8977                        String systemProfilePath =
8978                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8979                        profileFile = new File(systemProfilePath);
8980                        // If we have a profile for a compressed APK, copy it to the reference
8981                        // location.
8982                        // Note that copying the profile here will cause it to override the
8983                        // reference profile every OTA even though the existing reference profile
8984                        // may have more data. We can't copy during decompression since the
8985                        // directories are not set up at that point.
8986                        if (profileFile.exists()) {
8987                            try {
8988                                // We could also do this lazily before calling dexopt in
8989                                // PackageDexOptimizer to prevent this happening on first boot. The
8990                                // issue is that we don't have a good way to say "do this only
8991                                // once".
8992                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8993                                        pkg.applicationInfo.uid, pkg.packageName,
8994                                        ArtManager.getProfileName(null))) {
8995                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8996                                } else {
8997                                    useProfileForDexopt = true;
8998                                }
8999                            } catch (Exception e) {
9000                                Log.e(TAG, "Failed to copy profile " +
9001                                        profileFile.getAbsolutePath() + " ", e);
9002                            }
9003                        }
9004                    }
9005                }
9006            }
9007
9008            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9009                if (DEBUG_DEXOPT) {
9010                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9011                }
9012                numberOfPackagesSkipped++;
9013                continue;
9014            }
9015
9016            if (DEBUG_DEXOPT) {
9017                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9018                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9019            }
9020
9021            if (showDialog) {
9022                try {
9023                    ActivityManager.getService().showBootMessage(
9024                            mContext.getResources().getString(R.string.android_upgrading_apk,
9025                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9026                } catch (RemoteException e) {
9027                }
9028                synchronized (mPackages) {
9029                    mDexOptDialogShown = true;
9030                }
9031            }
9032
9033            int pkgCompilationReason = compilationReason;
9034            if (useProfileForDexopt) {
9035                // Use background dexopt mode to try and use the profile. Note that this does not
9036                // guarantee usage of the profile.
9037                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9038            }
9039
9040            // checkProfiles is false to avoid merging profiles during boot which
9041            // might interfere with background compilation (b/28612421).
9042            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9043            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9044            // trade-off worth doing to save boot time work.
9045            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9046            if (compilationReason == REASON_FIRST_BOOT) {
9047                // TODO: This doesn't cover the upgrade case, we should check for this too.
9048                dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9049            }
9050            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9051                    pkg.packageName,
9052                    pkgCompilationReason,
9053                    dexoptFlags));
9054
9055            switch (primaryDexOptStaus) {
9056                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9057                    numberOfPackagesOptimized++;
9058                    break;
9059                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9060                    numberOfPackagesSkipped++;
9061                    break;
9062                case PackageDexOptimizer.DEX_OPT_FAILED:
9063                    numberOfPackagesFailed++;
9064                    break;
9065                default:
9066                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9067                    break;
9068            }
9069        }
9070
9071        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9072                numberOfPackagesFailed };
9073    }
9074
9075    @Override
9076    public void notifyPackageUse(String packageName, int reason) {
9077        synchronized (mPackages) {
9078            final int callingUid = Binder.getCallingUid();
9079            final int callingUserId = UserHandle.getUserId(callingUid);
9080            if (getInstantAppPackageName(callingUid) != null) {
9081                if (!isCallerSameApp(packageName, callingUid)) {
9082                    return;
9083                }
9084            } else {
9085                if (isInstantApp(packageName, callingUserId)) {
9086                    return;
9087                }
9088            }
9089            notifyPackageUseLocked(packageName, reason);
9090        }
9091    }
9092
9093    @GuardedBy("mPackages")
9094    private void notifyPackageUseLocked(String packageName, int reason) {
9095        final PackageParser.Package p = mPackages.get(packageName);
9096        if (p == null) {
9097            return;
9098        }
9099        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9100    }
9101
9102    @Override
9103    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9104            List<String> classPaths, String loaderIsa) {
9105        int userId = UserHandle.getCallingUserId();
9106        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9107        if (ai == null) {
9108            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9109                + loadingPackageName + ", user=" + userId);
9110            return;
9111        }
9112        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9113    }
9114
9115    @Override
9116    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9117            IDexModuleRegisterCallback callback) {
9118        int userId = UserHandle.getCallingUserId();
9119        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9120        DexManager.RegisterDexModuleResult result;
9121        if (ai == null) {
9122            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9123                     " calling user. package=" + packageName + ", user=" + userId);
9124            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9125        } else {
9126            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9127        }
9128
9129        if (callback != null) {
9130            mHandler.post(() -> {
9131                try {
9132                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9133                } catch (RemoteException e) {
9134                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9135                }
9136            });
9137        }
9138    }
9139
9140    /**
9141     * Ask the package manager to perform a dex-opt with the given compiler filter.
9142     *
9143     * Note: exposed only for the shell command to allow moving packages explicitly to a
9144     *       definite state.
9145     */
9146    @Override
9147    public boolean performDexOptMode(String packageName,
9148            boolean checkProfiles, String targetCompilerFilter, boolean force,
9149            boolean bootComplete, String splitName) {
9150        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9151                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9152                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9153        return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9154                targetCompilerFilter, splitName, flags));
9155    }
9156
9157    /**
9158     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9159     * secondary dex files belonging to the given package.
9160     *
9161     * Note: exposed only for the shell command to allow moving packages explicitly to a
9162     *       definite state.
9163     */
9164    @Override
9165    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9166            boolean force) {
9167        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9168                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9169                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9170                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9171        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9172    }
9173
9174    /*package*/ boolean performDexOpt(DexoptOptions options) {
9175        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9176            return false;
9177        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9178            return false;
9179        }
9180
9181        if (options.isDexoptOnlySecondaryDex()) {
9182            return mDexManager.dexoptSecondaryDex(options);
9183        } else {
9184            int dexoptStatus = performDexOptWithStatus(options);
9185            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9186        }
9187    }
9188
9189    /**
9190     * Perform dexopt on the given package and return one of following result:
9191     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9192     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9193     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9194     */
9195    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9196        return performDexOptTraced(options);
9197    }
9198
9199    private int performDexOptTraced(DexoptOptions options) {
9200        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9201        try {
9202            return performDexOptInternal(options);
9203        } finally {
9204            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9205        }
9206    }
9207
9208    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9209    // if the package can now be considered up to date for the given filter.
9210    private int performDexOptInternal(DexoptOptions options) {
9211        PackageParser.Package p;
9212        synchronized (mPackages) {
9213            p = mPackages.get(options.getPackageName());
9214            if (p == null) {
9215                // Package could not be found. Report failure.
9216                return PackageDexOptimizer.DEX_OPT_FAILED;
9217            }
9218            mPackageUsage.maybeWriteAsync(mPackages);
9219            mCompilerStats.maybeWriteAsync();
9220        }
9221        long callingId = Binder.clearCallingIdentity();
9222        try {
9223            synchronized (mInstallLock) {
9224                return performDexOptInternalWithDependenciesLI(p, options);
9225            }
9226        } finally {
9227            Binder.restoreCallingIdentity(callingId);
9228        }
9229    }
9230
9231    public ArraySet<String> getOptimizablePackages() {
9232        ArraySet<String> pkgs = new ArraySet<String>();
9233        synchronized (mPackages) {
9234            for (PackageParser.Package p : mPackages.values()) {
9235                if (PackageDexOptimizer.canOptimizePackage(p)) {
9236                    pkgs.add(p.packageName);
9237                }
9238            }
9239        }
9240        return pkgs;
9241    }
9242
9243    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9244            DexoptOptions options) {
9245        // Select the dex optimizer based on the force parameter.
9246        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9247        //       allocate an object here.
9248        PackageDexOptimizer pdo = options.isForce()
9249                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9250                : mPackageDexOptimizer;
9251
9252        // Dexopt all dependencies first. Note: we ignore the return value and march on
9253        // on errors.
9254        // Note that we are going to call performDexOpt on those libraries as many times as
9255        // they are referenced in packages. When we do a batch of performDexOpt (for example
9256        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9257        // and the first package that uses the library will dexopt it. The
9258        // others will see that the compiled code for the library is up to date.
9259        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9260        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9261        if (!deps.isEmpty()) {
9262            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9263                    options.getCompilationReason(), options.getCompilerFilter(),
9264                    options.getSplitName(),
9265                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9266            for (PackageParser.Package depPackage : deps) {
9267                // TODO: Analyze and investigate if we (should) profile libraries.
9268                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9269                        getOrCreateCompilerPackageStats(depPackage),
9270                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9271            }
9272        }
9273        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9274                getOrCreateCompilerPackageStats(p),
9275                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9276    }
9277
9278    /**
9279     * Reconcile the information we have about the secondary dex files belonging to
9280     * {@code packagName} and the actual dex files. For all dex files that were
9281     * deleted, update the internal records and delete the generated oat files.
9282     */
9283    @Override
9284    public void reconcileSecondaryDexFiles(String packageName) {
9285        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9286            return;
9287        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9288            return;
9289        }
9290        mDexManager.reconcileSecondaryDexFiles(packageName);
9291    }
9292
9293    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9294    // a reference there.
9295    /*package*/ DexManager getDexManager() {
9296        return mDexManager;
9297    }
9298
9299    /**
9300     * Execute the background dexopt job immediately.
9301     */
9302    @Override
9303    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9304        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9305            return false;
9306        }
9307        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9308    }
9309
9310    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9311        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9312                || p.usesStaticLibraries != null) {
9313            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9314            Set<String> collectedNames = new HashSet<>();
9315            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9316
9317            retValue.remove(p);
9318
9319            return retValue;
9320        } else {
9321            return Collections.emptyList();
9322        }
9323    }
9324
9325    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9326            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9327        if (!collectedNames.contains(p.packageName)) {
9328            collectedNames.add(p.packageName);
9329            collected.add(p);
9330
9331            if (p.usesLibraries != null) {
9332                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9333                        null, collected, collectedNames);
9334            }
9335            if (p.usesOptionalLibraries != null) {
9336                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9337                        null, collected, collectedNames);
9338            }
9339            if (p.usesStaticLibraries != null) {
9340                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9341                        p.usesStaticLibrariesVersions, collected, collectedNames);
9342            }
9343        }
9344    }
9345
9346    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9347            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9348        final int libNameCount = libs.size();
9349        for (int i = 0; i < libNameCount; i++) {
9350            String libName = libs.get(i);
9351            long version = (versions != null && versions.length == libNameCount)
9352                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9353            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9354            if (libPkg != null) {
9355                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9356            }
9357        }
9358    }
9359
9360    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9361        synchronized (mPackages) {
9362            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9363            if (libEntry != null) {
9364                return mPackages.get(libEntry.apk);
9365            }
9366            return null;
9367        }
9368    }
9369
9370    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9371        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9372        if (versionedLib == null) {
9373            return null;
9374        }
9375        return versionedLib.get(version);
9376    }
9377
9378    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9379        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9380                pkg.staticSharedLibName);
9381        if (versionedLib == null) {
9382            return null;
9383        }
9384        long previousLibVersion = -1;
9385        final int versionCount = versionedLib.size();
9386        for (int i = 0; i < versionCount; i++) {
9387            final long libVersion = versionedLib.keyAt(i);
9388            if (libVersion < pkg.staticSharedLibVersion) {
9389                previousLibVersion = Math.max(previousLibVersion, libVersion);
9390            }
9391        }
9392        if (previousLibVersion >= 0) {
9393            return versionedLib.get(previousLibVersion);
9394        }
9395        return null;
9396    }
9397
9398    public void shutdown() {
9399        mPackageUsage.writeNow(mPackages);
9400        mCompilerStats.writeNow();
9401        mDexManager.writePackageDexUsageNow();
9402    }
9403
9404    @Override
9405    public void dumpProfiles(String packageName) {
9406        PackageParser.Package pkg;
9407        synchronized (mPackages) {
9408            pkg = mPackages.get(packageName);
9409            if (pkg == null) {
9410                throw new IllegalArgumentException("Unknown package: " + packageName);
9411            }
9412        }
9413        /* Only the shell, root, or the app user should be able to dump profiles. */
9414        int callingUid = Binder.getCallingUid();
9415        if (callingUid != Process.SHELL_UID &&
9416            callingUid != Process.ROOT_UID &&
9417            callingUid != pkg.applicationInfo.uid) {
9418            throw new SecurityException("dumpProfiles");
9419        }
9420
9421        synchronized (mInstallLock) {
9422            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9423            mArtManagerService.dumpProfiles(pkg);
9424            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9425        }
9426    }
9427
9428    @Override
9429    public void forceDexOpt(String packageName) {
9430        enforceSystemOrRoot("forceDexOpt");
9431
9432        PackageParser.Package pkg;
9433        synchronized (mPackages) {
9434            pkg = mPackages.get(packageName);
9435            if (pkg == null) {
9436                throw new IllegalArgumentException("Unknown package: " + packageName);
9437            }
9438        }
9439
9440        synchronized (mInstallLock) {
9441            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9442
9443            // Whoever is calling forceDexOpt wants a compiled package.
9444            // Don't use profiles since that may cause compilation to be skipped.
9445            final int res = performDexOptInternalWithDependenciesLI(
9446                    pkg,
9447                    new DexoptOptions(packageName,
9448                            getDefaultCompilerFilter(),
9449                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9450
9451            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9452            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9453                throw new IllegalStateException("Failed to dexopt: " + res);
9454            }
9455        }
9456    }
9457
9458    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9459        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9460            Slog.w(TAG, "Unable to update from " + oldPkg.name
9461                    + " to " + newPkg.packageName
9462                    + ": old package not in system partition");
9463            return false;
9464        } else if (mPackages.get(oldPkg.name) != null) {
9465            Slog.w(TAG, "Unable to update from " + oldPkg.name
9466                    + " to " + newPkg.packageName
9467                    + ": old package still exists");
9468            return false;
9469        }
9470        return true;
9471    }
9472
9473    void removeCodePathLI(File codePath) {
9474        if (codePath.isDirectory()) {
9475            try {
9476                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9477            } catch (InstallerException e) {
9478                Slog.w(TAG, "Failed to remove code path", e);
9479            }
9480        } else {
9481            codePath.delete();
9482        }
9483    }
9484
9485    private int[] resolveUserIds(int userId) {
9486        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9487    }
9488
9489    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9490        if (pkg == null) {
9491            Slog.wtf(TAG, "Package was null!", new Throwable());
9492            return;
9493        }
9494        clearAppDataLeafLIF(pkg, userId, flags);
9495        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9496        for (int i = 0; i < childCount; i++) {
9497            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9498        }
9499
9500        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9501    }
9502
9503    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9504        final PackageSetting ps;
9505        synchronized (mPackages) {
9506            ps = mSettings.mPackages.get(pkg.packageName);
9507        }
9508        for (int realUserId : resolveUserIds(userId)) {
9509            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9510            try {
9511                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9512                        ceDataInode);
9513            } catch (InstallerException e) {
9514                Slog.w(TAG, String.valueOf(e));
9515            }
9516        }
9517    }
9518
9519    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9520        if (pkg == null) {
9521            Slog.wtf(TAG, "Package was null!", new Throwable());
9522            return;
9523        }
9524        destroyAppDataLeafLIF(pkg, userId, flags);
9525        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9526        for (int i = 0; i < childCount; i++) {
9527            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9528        }
9529    }
9530
9531    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9532        final PackageSetting ps;
9533        synchronized (mPackages) {
9534            ps = mSettings.mPackages.get(pkg.packageName);
9535        }
9536        for (int realUserId : resolveUserIds(userId)) {
9537            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9538            try {
9539                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9540                        ceDataInode);
9541            } catch (InstallerException e) {
9542                Slog.w(TAG, String.valueOf(e));
9543            }
9544            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9545        }
9546    }
9547
9548    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9549        if (pkg == null) {
9550            Slog.wtf(TAG, "Package was null!", new Throwable());
9551            return;
9552        }
9553        destroyAppProfilesLeafLIF(pkg);
9554        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9555        for (int i = 0; i < childCount; i++) {
9556            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9557        }
9558    }
9559
9560    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9561        try {
9562            mInstaller.destroyAppProfiles(pkg.packageName);
9563        } catch (InstallerException e) {
9564            Slog.w(TAG, String.valueOf(e));
9565        }
9566    }
9567
9568    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9569        if (pkg == null) {
9570            Slog.wtf(TAG, "Package was null!", new Throwable());
9571            return;
9572        }
9573        mArtManagerService.clearAppProfiles(pkg);
9574        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9575        for (int i = 0; i < childCount; i++) {
9576            mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
9577        }
9578    }
9579
9580    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9581            long lastUpdateTime) {
9582        // Set parent install/update time
9583        PackageSetting ps = (PackageSetting) pkg.mExtras;
9584        if (ps != null) {
9585            ps.firstInstallTime = firstInstallTime;
9586            ps.lastUpdateTime = lastUpdateTime;
9587        }
9588        // Set children install/update time
9589        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9590        for (int i = 0; i < childCount; i++) {
9591            PackageParser.Package childPkg = pkg.childPackages.get(i);
9592            ps = (PackageSetting) childPkg.mExtras;
9593            if (ps != null) {
9594                ps.firstInstallTime = firstInstallTime;
9595                ps.lastUpdateTime = lastUpdateTime;
9596            }
9597        }
9598    }
9599
9600    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9601            SharedLibraryEntry file,
9602            PackageParser.Package changingLib) {
9603        if (file.path != null) {
9604            usesLibraryFiles.add(file.path);
9605            return;
9606        }
9607        PackageParser.Package p = mPackages.get(file.apk);
9608        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9609            // If we are doing this while in the middle of updating a library apk,
9610            // then we need to make sure to use that new apk for determining the
9611            // dependencies here.  (We haven't yet finished committing the new apk
9612            // to the package manager state.)
9613            if (p == null || p.packageName.equals(changingLib.packageName)) {
9614                p = changingLib;
9615            }
9616        }
9617        if (p != null) {
9618            usesLibraryFiles.addAll(p.getAllCodePaths());
9619            if (p.usesLibraryFiles != null) {
9620                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9621            }
9622        }
9623    }
9624
9625    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9626            PackageParser.Package changingLib) throws PackageManagerException {
9627        if (pkg == null) {
9628            return;
9629        }
9630        // The collection used here must maintain the order of addition (so
9631        // that libraries are searched in the correct order) and must have no
9632        // duplicates.
9633        Set<String> usesLibraryFiles = null;
9634        if (pkg.usesLibraries != null) {
9635            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9636                    null, null, pkg.packageName, changingLib, true,
9637                    pkg.applicationInfo.targetSdkVersion, null);
9638        }
9639        if (pkg.usesStaticLibraries != null) {
9640            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9641                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9642                    pkg.packageName, changingLib, true,
9643                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9644        }
9645        if (pkg.usesOptionalLibraries != null) {
9646            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9647                    null, null, pkg.packageName, changingLib, false,
9648                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9649        }
9650        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9651            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9652        } else {
9653            pkg.usesLibraryFiles = null;
9654        }
9655    }
9656
9657    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9658            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9659            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9660            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9661            throws PackageManagerException {
9662        final int libCount = requestedLibraries.size();
9663        for (int i = 0; i < libCount; i++) {
9664            final String libName = requestedLibraries.get(i);
9665            final long libVersion = requiredVersions != null ? requiredVersions[i]
9666                    : SharedLibraryInfo.VERSION_UNDEFINED;
9667            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9668            if (libEntry == null) {
9669                if (required) {
9670                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9671                            "Package " + packageName + " requires unavailable shared library "
9672                                    + libName + "; failing!");
9673                } else if (DEBUG_SHARED_LIBRARIES) {
9674                    Slog.i(TAG, "Package " + packageName
9675                            + " desires unavailable shared library "
9676                            + libName + "; ignoring!");
9677                }
9678            } else {
9679                if (requiredVersions != null && requiredCertDigests != null) {
9680                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9681                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9682                            "Package " + packageName + " requires unavailable static shared"
9683                                    + " library " + libName + " version "
9684                                    + libEntry.info.getLongVersion() + "; failing!");
9685                    }
9686
9687                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9688                    if (libPkg == null) {
9689                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9690                                "Package " + packageName + " requires unavailable static shared"
9691                                        + " library; failing!");
9692                    }
9693
9694                    final String[] expectedCertDigests = requiredCertDigests[i];
9695
9696
9697                    if (expectedCertDigests.length > 1) {
9698
9699                        // For apps targeting O MR1 we require explicit enumeration of all certs.
9700                        final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9701                                ? PackageUtils.computeSignaturesSha256Digests(
9702                                libPkg.mSigningDetails.signatures)
9703                                : PackageUtils.computeSignaturesSha256Digests(
9704                                        new Signature[]{libPkg.mSigningDetails.signatures[0]});
9705
9706                        // Take a shortcut if sizes don't match. Note that if an app doesn't
9707                        // target O we don't parse the "additional-certificate" tags similarly
9708                        // how we only consider all certs only for apps targeting O (see above).
9709                        // Therefore, the size check is safe to make.
9710                        if (expectedCertDigests.length != libCertDigests.length) {
9711                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9712                                    "Package " + packageName + " requires differently signed" +
9713                                            " static shared library; failing!");
9714                        }
9715
9716                        // Use a predictable order as signature order may vary
9717                        Arrays.sort(libCertDigests);
9718                        Arrays.sort(expectedCertDigests);
9719
9720                        final int certCount = libCertDigests.length;
9721                        for (int j = 0; j < certCount; j++) {
9722                            if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9723                                throw new PackageManagerException(
9724                                        INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9725                                        "Package " + packageName + " requires differently signed" +
9726                                                " static shared library; failing!");
9727                            }
9728                        }
9729                    } else {
9730
9731                        // lib signing cert could have rotated beyond the one expected, check to see
9732                        // if the new one has been blessed by the old
9733                        if (!libPkg.mSigningDetails.hasSha256Certificate(
9734                                ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
9735                            throw new PackageManagerException(
9736                                    INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9737                                    "Package " + packageName + " requires differently signed" +
9738                                            " static shared library; failing!");
9739                        }
9740                    }
9741                }
9742
9743                if (outUsedLibraries == null) {
9744                    // Use LinkedHashSet to preserve the order of files added to
9745                    // usesLibraryFiles while eliminating duplicates.
9746                    outUsedLibraries = new LinkedHashSet<>();
9747                }
9748                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9749            }
9750        }
9751        return outUsedLibraries;
9752    }
9753
9754    private static boolean hasString(List<String> list, List<String> which) {
9755        if (list == null) {
9756            return false;
9757        }
9758        for (int i=list.size()-1; i>=0; i--) {
9759            for (int j=which.size()-1; j>=0; j--) {
9760                if (which.get(j).equals(list.get(i))) {
9761                    return true;
9762                }
9763            }
9764        }
9765        return false;
9766    }
9767
9768    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9769            PackageParser.Package changingPkg) {
9770        ArrayList<PackageParser.Package> res = null;
9771        for (PackageParser.Package pkg : mPackages.values()) {
9772            if (changingPkg != null
9773                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9774                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9775                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9776                            changingPkg.staticSharedLibName)) {
9777                return null;
9778            }
9779            if (res == null) {
9780                res = new ArrayList<>();
9781            }
9782            res.add(pkg);
9783            try {
9784                updateSharedLibrariesLPr(pkg, changingPkg);
9785            } catch (PackageManagerException e) {
9786                // If a system app update or an app and a required lib missing we
9787                // delete the package and for updated system apps keep the data as
9788                // it is better for the user to reinstall than to be in an limbo
9789                // state. Also libs disappearing under an app should never happen
9790                // - just in case.
9791                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9792                    final int flags = pkg.isUpdatedSystemApp()
9793                            ? PackageManager.DELETE_KEEP_DATA : 0;
9794                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9795                            flags , null, true, null);
9796                }
9797                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9798            }
9799        }
9800        return res;
9801    }
9802
9803    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9804            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9805            @Nullable UserHandle user) throws PackageManagerException {
9806        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9807        // If the package has children and this is the first dive in the function
9808        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9809        // whether all packages (parent and children) would be successfully scanned
9810        // before the actual scan since scanning mutates internal state and we want
9811        // to atomically install the package and its children.
9812        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9813            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9814                scanFlags |= SCAN_CHECK_ONLY;
9815            }
9816        } else {
9817            scanFlags &= ~SCAN_CHECK_ONLY;
9818        }
9819
9820        final PackageParser.Package scannedPkg;
9821        try {
9822            // Scan the parent
9823            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9824            // Scan the children
9825            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9826            for (int i = 0; i < childCount; i++) {
9827                PackageParser.Package childPkg = pkg.childPackages.get(i);
9828                scanPackageNewLI(childPkg, parseFlags,
9829                        scanFlags, currentTime, user);
9830            }
9831        } finally {
9832            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9833        }
9834
9835        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9836            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9837        }
9838
9839        return scannedPkg;
9840    }
9841
9842    /** The result of a package scan. */
9843    private static class ScanResult {
9844        /** Whether or not the package scan was successful */
9845        public final boolean success;
9846        /**
9847         * The final package settings. This may be the same object passed in
9848         * the {@link ScanRequest}, but, with modified values.
9849         */
9850        @Nullable public final PackageSetting pkgSetting;
9851        /** ABI code paths that have changed in the package scan */
9852        @Nullable public final List<String> changedAbiCodePath;
9853        public ScanResult(
9854                boolean success,
9855                @Nullable PackageSetting pkgSetting,
9856                @Nullable List<String> changedAbiCodePath) {
9857            this.success = success;
9858            this.pkgSetting = pkgSetting;
9859            this.changedAbiCodePath = changedAbiCodePath;
9860        }
9861    }
9862
9863    /** A package to be scanned */
9864    private static class ScanRequest {
9865        /** The parsed package */
9866        @NonNull public final PackageParser.Package pkg;
9867        /** Shared user settings, if the package has a shared user */
9868        @Nullable public final SharedUserSetting sharedUserSetting;
9869        /**
9870         * Package settings of the currently installed version.
9871         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9872         * during scan.
9873         */
9874        @Nullable public final PackageSetting pkgSetting;
9875        /** A copy of the settings for the currently installed version */
9876        @Nullable public final PackageSetting oldPkgSetting;
9877        /** Package settings for the disabled version on the /system partition */
9878        @Nullable public final PackageSetting disabledPkgSetting;
9879        /** Package settings for the installed version under its original package name */
9880        @Nullable public final PackageSetting originalPkgSetting;
9881        /** The real package name of a renamed application */
9882        @Nullable public final String realPkgName;
9883        public final @ParseFlags int parseFlags;
9884        public final @ScanFlags int scanFlags;
9885        /** The user for which the package is being scanned */
9886        @Nullable public final UserHandle user;
9887        /** Whether or not the platform package is being scanned */
9888        public final boolean isPlatformPackage;
9889        public ScanRequest(
9890                @NonNull PackageParser.Package pkg,
9891                @Nullable SharedUserSetting sharedUserSetting,
9892                @Nullable PackageSetting pkgSetting,
9893                @Nullable PackageSetting disabledPkgSetting,
9894                @Nullable PackageSetting originalPkgSetting,
9895                @Nullable String realPkgName,
9896                @ParseFlags int parseFlags,
9897                @ScanFlags int scanFlags,
9898                boolean isPlatformPackage,
9899                @Nullable UserHandle user) {
9900            this.pkg = pkg;
9901            this.pkgSetting = pkgSetting;
9902            this.sharedUserSetting = sharedUserSetting;
9903            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9904            this.disabledPkgSetting = disabledPkgSetting;
9905            this.originalPkgSetting = originalPkgSetting;
9906            this.realPkgName = realPkgName;
9907            this.parseFlags = parseFlags;
9908            this.scanFlags = scanFlags;
9909            this.isPlatformPackage = isPlatformPackage;
9910            this.user = user;
9911        }
9912    }
9913
9914    /**
9915     * Returns the actual scan flags depending upon the state of the other settings.
9916     * <p>Updated system applications will not have the following flags set
9917     * by default and need to be adjusted after the fact:
9918     * <ul>
9919     * <li>{@link #SCAN_AS_SYSTEM}</li>
9920     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
9921     * <li>{@link #SCAN_AS_OEM}</li>
9922     * <li>{@link #SCAN_AS_VENDOR}</li>
9923     * <li>{@link #SCAN_AS_PRODUCT}</li>
9924     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
9925     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
9926     * </ul>
9927     */
9928    private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
9929            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
9930            PackageParser.Package pkg) {
9931        if (disabledPkgSetting != null) {
9932            // updated system application, must at least have SCAN_AS_SYSTEM
9933            scanFlags |= SCAN_AS_SYSTEM;
9934            if ((disabledPkgSetting.pkgPrivateFlags
9935                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9936                scanFlags |= SCAN_AS_PRIVILEGED;
9937            }
9938            if ((disabledPkgSetting.pkgPrivateFlags
9939                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9940                scanFlags |= SCAN_AS_OEM;
9941            }
9942            if ((disabledPkgSetting.pkgPrivateFlags
9943                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
9944                scanFlags |= SCAN_AS_VENDOR;
9945            }
9946            if ((disabledPkgSetting.pkgPrivateFlags
9947                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
9948                scanFlags |= SCAN_AS_PRODUCT;
9949            }
9950        }
9951        if (pkgSetting != null) {
9952            final int userId = ((user == null) ? 0 : user.getIdentifier());
9953            if (pkgSetting.getInstantApp(userId)) {
9954                scanFlags |= SCAN_AS_INSTANT_APP;
9955            }
9956            if (pkgSetting.getVirtulalPreload(userId)) {
9957                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9958            }
9959        }
9960
9961        // Scan as privileged apps that share a user with a priv-app.
9962        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) && !pkg.isPrivileged()
9963                && (pkg.mSharedUserId != null)) {
9964            SharedUserSetting sharedUserSetting = null;
9965            try {
9966                sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
9967            } catch (PackageManagerException ignore) {}
9968            if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
9969                // Exempt SharedUsers signed with the platform key.
9970                // TODO(b/72378145) Fix this exemption. Force signature apps
9971                // to whitelist their privileged permissions just like other
9972                // priv-apps.
9973                synchronized (mPackages) {
9974                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
9975                    if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
9976                                pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
9977                        scanFlags |= SCAN_AS_PRIVILEGED;
9978                    }
9979                }
9980            }
9981        }
9982
9983        return scanFlags;
9984    }
9985
9986    // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
9987    // the results / removing app data needs to be moved up a level to the callers of this
9988    // method. Also, we need to solve the problem of potentially creating a new shared user
9989    // setting. That can probably be done later and patch things up after the fact.
9990    @GuardedBy("mInstallLock")
9991    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9992            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9993            @Nullable UserHandle user) throws PackageManagerException {
9994
9995        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9996        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9997        if (realPkgName != null) {
9998            ensurePackageRenamed(pkg, renamedPkgName);
9999        }
10000        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
10001        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10002        final PackageSetting disabledPkgSetting =
10003                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10004
10005        if (mTransferedPackages.contains(pkg.packageName)) {
10006            Slog.w(TAG, "Package " + pkg.packageName
10007                    + " was transferred to another, but its .apk remains");
10008        }
10009
10010        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
10011        synchronized (mPackages) {
10012            applyPolicy(pkg, parseFlags, scanFlags);
10013            assertPackageIsValid(pkg, parseFlags, scanFlags);
10014
10015            SharedUserSetting sharedUserSetting = null;
10016            if (pkg.mSharedUserId != null) {
10017                // SIDE EFFECTS; may potentially allocate a new shared user
10018                sharedUserSetting = mSettings.getSharedUserLPw(
10019                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10020                if (DEBUG_PACKAGE_SCANNING) {
10021                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10022                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
10023                                + " (uid=" + sharedUserSetting.userId + "):"
10024                                + " packages=" + sharedUserSetting.packages);
10025                }
10026            }
10027
10028            boolean scanSucceeded = false;
10029            try {
10030                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
10031                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
10032                        (pkg == mPlatformPackage), user);
10033                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
10034                if (result.success) {
10035                    commitScanResultsLocked(request, result);
10036                }
10037                scanSucceeded = true;
10038            } finally {
10039                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10040                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
10041                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10042                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10043                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10044                  }
10045            }
10046        }
10047        return pkg;
10048    }
10049
10050    /**
10051     * Commits the package scan and modifies system state.
10052     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10053     * of committing the package, leaving the system in an inconsistent state.
10054     * This needs to be fixed so, once we get to this point, no errors are
10055     * possible and the system is not left in an inconsistent state.
10056     */
10057    @GuardedBy("mPackages")
10058    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
10059            throws PackageManagerException {
10060        final PackageParser.Package pkg = request.pkg;
10061        final @ParseFlags int parseFlags = request.parseFlags;
10062        final @ScanFlags int scanFlags = request.scanFlags;
10063        final PackageSetting oldPkgSetting = request.oldPkgSetting;
10064        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10065        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10066        final UserHandle user = request.user;
10067        final String realPkgName = request.realPkgName;
10068        final PackageSetting pkgSetting = result.pkgSetting;
10069        final List<String> changedAbiCodePath = result.changedAbiCodePath;
10070        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
10071
10072        if (newPkgSettingCreated) {
10073            if (originalPkgSetting != null) {
10074                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
10075            }
10076            // THROWS: when we can't allocate a user id. add call to check if there's
10077            // enough space to ensure we won't throw; otherwise, don't modify state
10078            mSettings.addUserToSettingLPw(pkgSetting);
10079
10080            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
10081                mTransferedPackages.add(originalPkgSetting.name);
10082            }
10083        }
10084        // TODO(toddke): Consider a method specifically for modifying the Package object
10085        // post scan; or, moving this stuff out of the Package object since it has nothing
10086        // to do with the package on disk.
10087        // We need to have this here because addUserToSettingLPw() is sometimes responsible
10088        // for creating the application ID. If we did this earlier, we would be saving the
10089        // correct ID.
10090        pkg.applicationInfo.uid = pkgSetting.appId;
10091
10092        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10093
10094        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
10095            mTransferedPackages.add(pkg.packageName);
10096        }
10097
10098        // THROWS: when requested libraries that can't be found. it only changes
10099        // the state of the passed in pkg object, so, move to the top of the method
10100        // and allow it to abort
10101        if ((scanFlags & SCAN_BOOTING) == 0
10102                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10103            // Check all shared libraries and map to their actual file path.
10104            // We only do this here for apps not on a system dir, because those
10105            // are the only ones that can fail an install due to this.  We
10106            // will take care of the system apps by updating all of their
10107            // library paths after the scan is done. Also during the initial
10108            // scan don't update any libs as we do this wholesale after all
10109            // apps are scanned to avoid dependency based scanning.
10110            updateSharedLibrariesLPr(pkg, null);
10111        }
10112
10113        // All versions of a static shared library are referenced with the same
10114        // package name. Internally, we use a synthetic package name to allow
10115        // multiple versions of the same shared library to be installed. So,
10116        // we need to generate the synthetic package name of the latest shared
10117        // library in order to compare signatures.
10118        PackageSetting signatureCheckPs = pkgSetting;
10119        if (pkg.applicationInfo.isStaticSharedLibrary()) {
10120            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10121            if (libraryEntry != null) {
10122                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10123            }
10124        }
10125
10126        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10127        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
10128            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
10129                // We just determined the app is signed correctly, so bring
10130                // over the latest parsed certs.
10131                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10132            } else {
10133                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10134                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10135                            "Package " + pkg.packageName + " upgrade keys do not match the "
10136                                    + "previously installed version");
10137                } else {
10138                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10139                    String msg = "System package " + pkg.packageName
10140                            + " signature changed; retaining data.";
10141                    reportSettingsProblem(Log.WARN, msg);
10142                }
10143            }
10144        } else {
10145            try {
10146                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
10147                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
10148                final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
10149                        pkg.mSigningDetails, compareCompat, compareRecover);
10150                // The new KeySets will be re-added later in the scanning process.
10151                if (compatMatch) {
10152                    synchronized (mPackages) {
10153                        ksms.removeAppKeySetDataLPw(pkg.packageName);
10154                    }
10155                }
10156                // We just determined the app is signed correctly, so bring
10157                // over the latest parsed certs.
10158                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10159
10160
10161                // if this is is a sharedUser, check to see if the new package is signed by a newer
10162                // signing certificate than the existing one, and if so, copy over the new details
10163                if (signatureCheckPs.sharedUser != null
10164                        && pkg.mSigningDetails.hasAncestor(
10165                                signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
10166                    signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10167                }
10168            } catch (PackageManagerException e) {
10169                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10170                    throw e;
10171                }
10172                // The signature has changed, but this package is in the system
10173                // image...  let's recover!
10174                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10175                // However...  if this package is part of a shared user, but it
10176                // doesn't match the signature of the shared user, let's fail.
10177                // What this means is that you can't change the signatures
10178                // associated with an overall shared user, which doesn't seem all
10179                // that unreasonable.
10180                if (signatureCheckPs.sharedUser != null) {
10181                    if (compareSignatures(
10182                            signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
10183                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
10184                        throw new PackageManagerException(
10185                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10186                                "Signature mismatch for shared user: "
10187                                        + pkgSetting.sharedUser);
10188                    }
10189                }
10190                // File a report about this.
10191                String msg = "System package " + pkg.packageName
10192                        + " signature changed; retaining data.";
10193                reportSettingsProblem(Log.WARN, msg);
10194            } catch (IllegalArgumentException e) {
10195
10196                // should never happen: certs matched when checking, but not when comparing
10197                // old to new for sharedUser
10198                throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10199                        "Signing certificates comparison made on incomparable signing details"
10200                        + " but somehow passed verifySignatures!");
10201            }
10202        }
10203
10204        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10205            // This package wants to adopt ownership of permissions from
10206            // another package.
10207            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10208                final String origName = pkg.mAdoptPermissions.get(i);
10209                final PackageSetting orig = mSettings.getPackageLPr(origName);
10210                if (orig != null) {
10211                    if (verifyPackageUpdateLPr(orig, pkg)) {
10212                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
10213                                + pkg.packageName);
10214                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10215                    }
10216                }
10217            }
10218        }
10219
10220        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10221            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
10222                final String codePathString = changedAbiCodePath.get(i);
10223                try {
10224                    mInstaller.rmdex(codePathString,
10225                            getDexCodeInstructionSet(getPreferredInstructionSet()));
10226                } catch (InstallerException ignored) {
10227                }
10228            }
10229        }
10230
10231        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10232            if (oldPkgSetting != null) {
10233                synchronized (mPackages) {
10234                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10235                }
10236            }
10237        } else {
10238            final int userId = user == null ? 0 : user.getIdentifier();
10239            // Modify state for the given package setting
10240            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10241                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10242            if (pkgSetting.getInstantApp(userId)) {
10243                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10244            }
10245        }
10246    }
10247
10248    /**
10249     * Returns the "real" name of the package.
10250     * <p>This may differ from the package's actual name if the application has already
10251     * been installed under one of this package's original names.
10252     */
10253    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10254            @Nullable String renamedPkgName) {
10255        if (isPackageRenamed(pkg, renamedPkgName)) {
10256            return pkg.mRealPackage;
10257        }
10258        return null;
10259    }
10260
10261    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10262    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10263            @Nullable String renamedPkgName) {
10264        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10265    }
10266
10267    /**
10268     * Returns the original package setting.
10269     * <p>A package can migrate its name during an update. In this scenario, a package
10270     * designates a set of names that it considers as one of its original names.
10271     * <p>An original package must be signed identically and it must have the same
10272     * shared user [if any].
10273     */
10274    @GuardedBy("mPackages")
10275    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10276            @Nullable String renamedPkgName) {
10277        if (!isPackageRenamed(pkg, renamedPkgName)) {
10278            return null;
10279        }
10280        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10281            final PackageSetting originalPs =
10282                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10283            if (originalPs != null) {
10284                // the package is already installed under its original name...
10285                // but, should we use it?
10286                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10287                    // the new package is incompatible with the original
10288                    continue;
10289                } else if (originalPs.sharedUser != null) {
10290                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10291                        // the shared user id is incompatible with the original
10292                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10293                                + " to " + pkg.packageName + ": old uid "
10294                                + originalPs.sharedUser.name
10295                                + " differs from " + pkg.mSharedUserId);
10296                        continue;
10297                    }
10298                    // TODO: Add case when shared user id is added [b/28144775]
10299                } else {
10300                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10301                            + pkg.packageName + " to old name " + originalPs.name);
10302                }
10303                return originalPs;
10304            }
10305        }
10306        return null;
10307    }
10308
10309    /**
10310     * Renames the package if it was installed under a different name.
10311     * <p>When we've already installed the package under an original name, update
10312     * the new package so we can continue to have the old name.
10313     */
10314    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10315            @NonNull String renamedPackageName) {
10316        if (pkg.mOriginalPackages == null
10317                || !pkg.mOriginalPackages.contains(renamedPackageName)
10318                || pkg.packageName.equals(renamedPackageName)) {
10319            return;
10320        }
10321        pkg.setPackageName(renamedPackageName);
10322    }
10323
10324    /**
10325     * Just scans the package without any side effects.
10326     * <p>Not entirely true at the moment. There is still one side effect -- this
10327     * method potentially modifies a live {@link PackageSetting} object representing
10328     * the package being scanned. This will be resolved in the future.
10329     *
10330     * @param request Information about the package to be scanned
10331     * @param isUnderFactoryTest Whether or not the device is under factory test
10332     * @param currentTime The current time, in millis
10333     * @return The results of the scan
10334     */
10335    @GuardedBy("mInstallLock")
10336    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10337            boolean isUnderFactoryTest, long currentTime)
10338                    throws PackageManagerException {
10339        final PackageParser.Package pkg = request.pkg;
10340        PackageSetting pkgSetting = request.pkgSetting;
10341        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10342        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10343        final @ParseFlags int parseFlags = request.parseFlags;
10344        final @ScanFlags int scanFlags = request.scanFlags;
10345        final String realPkgName = request.realPkgName;
10346        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10347        final UserHandle user = request.user;
10348        final boolean isPlatformPackage = request.isPlatformPackage;
10349
10350        List<String> changedAbiCodePath = null;
10351
10352        if (DEBUG_PACKAGE_SCANNING) {
10353            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10354                Log.d(TAG, "Scanning package " + pkg.packageName);
10355        }
10356
10357        if (Build.IS_DEBUGGABLE &&
10358                pkg.isPrivileged() &&
10359                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10360            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10361        }
10362
10363        // Initialize package source and resource directories
10364        final File scanFile = new File(pkg.codePath);
10365        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10366        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10367
10368        // We keep references to the derived CPU Abis from settings in oder to reuse
10369        // them in the case where we're not upgrading or booting for the first time.
10370        String primaryCpuAbiFromSettings = null;
10371        String secondaryCpuAbiFromSettings = null;
10372        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10373
10374        if (!needToDeriveAbi) {
10375            if (pkgSetting != null) {
10376                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10377                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10378            } else {
10379                // Re-scanning a system package after uninstalling updates; need to derive ABI
10380                needToDeriveAbi = true;
10381            }
10382        }
10383
10384        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10385            PackageManagerService.reportSettingsProblem(Log.WARN,
10386                    "Package " + pkg.packageName + " shared user changed from "
10387                            + (pkgSetting.sharedUser != null
10388                            ? pkgSetting.sharedUser.name : "<nothing>")
10389                            + " to "
10390                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10391                            + "; replacing with new");
10392            pkgSetting = null;
10393        }
10394
10395        String[] usesStaticLibraries = null;
10396        if (pkg.usesStaticLibraries != null) {
10397            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10398            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10399        }
10400        final boolean createNewPackage = (pkgSetting == null);
10401        if (createNewPackage) {
10402            final String parentPackageName = (pkg.parentPackage != null)
10403                    ? pkg.parentPackage.packageName : null;
10404            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10405            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10406            // REMOVE SharedUserSetting from method; update in a separate call
10407            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10408                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10409                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10410                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10411                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10412                    user, true /*allowInstall*/, instantApp, virtualPreload,
10413                    parentPackageName, pkg.getChildPackageNames(),
10414                    UserManagerService.getInstance(), usesStaticLibraries,
10415                    pkg.usesStaticLibrariesVersions);
10416        } else {
10417            // REMOVE SharedUserSetting from method; update in a separate call.
10418            //
10419            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10420            // secondaryCpuAbi are not known at this point so we always update them
10421            // to null here, only to reset them at a later point.
10422            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10423                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10424                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10425                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10426                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10427                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10428        }
10429        if (createNewPackage && originalPkgSetting != null) {
10430            // This is the initial transition from the original package, so,
10431            // fix up the new package's name now. We must do this after looking
10432            // up the package under its new name, so getPackageLP takes care of
10433            // fiddling things correctly.
10434            pkg.setPackageName(originalPkgSetting.name);
10435
10436            // File a report about this.
10437            String msg = "New package " + pkgSetting.realName
10438                    + " renamed to replace old package " + pkgSetting.name;
10439            reportSettingsProblem(Log.WARN, msg);
10440        }
10441
10442        final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
10443        // for existing packages, change the install state; but, only if it's explicitly specified
10444        if (!createNewPackage) {
10445            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10446            final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
10447            setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
10448        }
10449
10450        if (disabledPkgSetting != null) {
10451            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10452        }
10453
10454        // Apps which share a sharedUserId must be placed in the same selinux domain. If this
10455        // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
10456        // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
10457        // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
10458        // least restrictive selinux domain.
10459        // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
10460        // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
10461        // ensures that all packages continue to run in the same selinux domain.
10462        final int targetSdkVersion =
10463            ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
10464            sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
10465        // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
10466        // They currently can be if the sharedUser apps are signed with the platform key.
10467        final boolean isPrivileged = (sharedUserSetting != null) ?
10468            sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
10469
10470        pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
10471                pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
10472        pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
10473                userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
10474
10475        pkg.mExtras = pkgSetting;
10476        pkg.applicationInfo.processName = fixProcessName(
10477                pkg.applicationInfo.packageName,
10478                pkg.applicationInfo.processName);
10479
10480        if (!isPlatformPackage) {
10481            // Get all of our default paths setup
10482            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10483        }
10484
10485        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10486
10487        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10488            if (needToDeriveAbi) {
10489                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10490                final boolean extractNativeLibs = !pkg.isLibrary();
10491                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10492                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10493
10494                // Some system apps still use directory structure for native libraries
10495                // in which case we might end up not detecting abi solely based on apk
10496                // structure. Try to detect abi based on directory structure.
10497                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10498                        pkg.applicationInfo.primaryCpuAbi == null) {
10499                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10500                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10501                }
10502            } else {
10503                // This is not a first boot or an upgrade, don't bother deriving the
10504                // ABI during the scan. Instead, trust the value that was stored in the
10505                // package setting.
10506                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10507                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10508
10509                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10510
10511                if (DEBUG_ABI_SELECTION) {
10512                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10513                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10514                            pkg.applicationInfo.secondaryCpuAbi);
10515                }
10516            }
10517        } else {
10518            if ((scanFlags & SCAN_MOVE) != 0) {
10519                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10520                // but we already have this packages package info in the PackageSetting. We just
10521                // use that and derive the native library path based on the new codepath.
10522                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10523                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10524            }
10525
10526            // Set native library paths again. For moves, the path will be updated based on the
10527            // ABIs we've determined above. For non-moves, the path will be updated based on the
10528            // ABIs we determined during compilation, but the path will depend on the final
10529            // package path (after the rename away from the stage path).
10530            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10531        }
10532
10533        // This is a special case for the "system" package, where the ABI is
10534        // dictated by the zygote configuration (and init.rc). We should keep track
10535        // of this ABI so that we can deal with "normal" applications that run under
10536        // the same UID correctly.
10537        if (isPlatformPackage) {
10538            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10539                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10540        }
10541
10542        // If there's a mismatch between the abi-override in the package setting
10543        // and the abiOverride specified for the install. Warn about this because we
10544        // would've already compiled the app without taking the package setting into
10545        // account.
10546        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10547            if (cpuAbiOverride == null && pkg.packageName != null) {
10548                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10549                        " for package " + pkg.packageName);
10550            }
10551        }
10552
10553        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10554        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10555        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10556
10557        // Copy the derived override back to the parsed package, so that we can
10558        // update the package settings accordingly.
10559        pkg.cpuAbiOverride = cpuAbiOverride;
10560
10561        if (DEBUG_ABI_SELECTION) {
10562            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10563                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10564                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10565        }
10566
10567        // Push the derived path down into PackageSettings so we know what to
10568        // clean up at uninstall time.
10569        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10570
10571        if (DEBUG_ABI_SELECTION) {
10572            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10573                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10574                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10575        }
10576
10577        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10578            // We don't do this here during boot because we can do it all
10579            // at once after scanning all existing packages.
10580            //
10581            // We also do this *before* we perform dexopt on this package, so that
10582            // we can avoid redundant dexopts, and also to make sure we've got the
10583            // code and package path correct.
10584            changedAbiCodePath =
10585                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10586        }
10587
10588        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10589                android.Manifest.permission.FACTORY_TEST)) {
10590            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10591        }
10592
10593        if (isSystemApp(pkg)) {
10594            pkgSetting.isOrphaned = true;
10595        }
10596
10597        // Take care of first install / last update times.
10598        final long scanFileTime = getLastModifiedTime(pkg);
10599        if (currentTime != 0) {
10600            if (pkgSetting.firstInstallTime == 0) {
10601                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10602            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10603                pkgSetting.lastUpdateTime = currentTime;
10604            }
10605        } else if (pkgSetting.firstInstallTime == 0) {
10606            // We need *something*.  Take time time stamp of the file.
10607            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10608        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10609            if (scanFileTime != pkgSetting.timeStamp) {
10610                // A package on the system image has changed; consider this
10611                // to be an update.
10612                pkgSetting.lastUpdateTime = scanFileTime;
10613            }
10614        }
10615        pkgSetting.setTimeStamp(scanFileTime);
10616
10617        pkgSetting.pkg = pkg;
10618        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10619        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10620            pkgSetting.versionCode = pkg.getLongVersionCode();
10621        }
10622        // Update volume if needed
10623        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10624        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10625            Slog.i(PackageManagerService.TAG,
10626                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10627                    + " package " + pkg.packageName
10628                    + " volume from " + pkgSetting.volumeUuid
10629                    + " to " + volumeUuid);
10630            pkgSetting.volumeUuid = volumeUuid;
10631        }
10632
10633        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10634    }
10635
10636    /**
10637     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10638     */
10639    private static boolean apkHasCode(String fileName) {
10640        StrictJarFile jarFile = null;
10641        try {
10642            jarFile = new StrictJarFile(fileName,
10643                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10644            return jarFile.findEntry("classes.dex") != null;
10645        } catch (IOException ignore) {
10646        } finally {
10647            try {
10648                if (jarFile != null) {
10649                    jarFile.close();
10650                }
10651            } catch (IOException ignore) {}
10652        }
10653        return false;
10654    }
10655
10656    /**
10657     * Enforces code policy for the package. This ensures that if an APK has
10658     * declared hasCode="true" in its manifest that the APK actually contains
10659     * code.
10660     *
10661     * @throws PackageManagerException If bytecode could not be found when it should exist
10662     */
10663    private static void assertCodePolicy(PackageParser.Package pkg)
10664            throws PackageManagerException {
10665        final boolean shouldHaveCode =
10666                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10667        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10668            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10669                    "Package " + pkg.baseCodePath + " code is missing");
10670        }
10671
10672        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10673            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10674                final boolean splitShouldHaveCode =
10675                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10676                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10677                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10678                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10679                }
10680            }
10681        }
10682    }
10683
10684    /**
10685     * Applies policy to the parsed package based upon the given policy flags.
10686     * Ensures the package is in a good state.
10687     * <p>
10688     * Implementation detail: This method must NOT have any side effect. It would
10689     * ideally be static, but, it requires locks to read system state.
10690     */
10691    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10692            final @ScanFlags int scanFlags) {
10693        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10694            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10695            if (pkg.applicationInfo.isDirectBootAware()) {
10696                // we're direct boot aware; set for all components
10697                for (PackageParser.Service s : pkg.services) {
10698                    s.info.encryptionAware = s.info.directBootAware = true;
10699                }
10700                for (PackageParser.Provider p : pkg.providers) {
10701                    p.info.encryptionAware = p.info.directBootAware = true;
10702                }
10703                for (PackageParser.Activity a : pkg.activities) {
10704                    a.info.encryptionAware = a.info.directBootAware = true;
10705                }
10706                for (PackageParser.Activity r : pkg.receivers) {
10707                    r.info.encryptionAware = r.info.directBootAware = true;
10708                }
10709            }
10710            if (compressedFileExists(pkg.codePath)) {
10711                pkg.isStub = true;
10712            }
10713        } else {
10714            // non system apps can't be flagged as core
10715            pkg.coreApp = false;
10716            // clear flags not applicable to regular apps
10717            pkg.applicationInfo.flags &=
10718                    ~ApplicationInfo.FLAG_PERSISTENT;
10719            pkg.applicationInfo.privateFlags &=
10720                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10721            pkg.applicationInfo.privateFlags &=
10722                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10723            // cap permission priorities
10724            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10725                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10726                    pkg.permissionGroups.get(i).info.priority = 0;
10727                }
10728            }
10729        }
10730        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10731            // clear protected broadcasts
10732            pkg.protectedBroadcasts = null;
10733            // ignore export request for single user receivers
10734            if (pkg.receivers != null) {
10735                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10736                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10737                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10738                        receiver.info.exported = false;
10739                    }
10740                }
10741            }
10742            // ignore export request for single user services
10743            if (pkg.services != null) {
10744                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10745                    final PackageParser.Service service = pkg.services.get(i);
10746                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10747                        service.info.exported = false;
10748                    }
10749                }
10750            }
10751            // ignore export request for single user providers
10752            if (pkg.providers != null) {
10753                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10754                    final PackageParser.Provider provider = pkg.providers.get(i);
10755                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10756                        provider.info.exported = false;
10757                    }
10758                }
10759            }
10760        }
10761
10762        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10763            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10764        }
10765
10766        if ((scanFlags & SCAN_AS_OEM) != 0) {
10767            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10768        }
10769
10770        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10771            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10772        }
10773
10774        if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
10775            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
10776        }
10777
10778        if (!isSystemApp(pkg)) {
10779            // Only system apps can use these features.
10780            pkg.mOriginalPackages = null;
10781            pkg.mRealPackage = null;
10782            pkg.mAdoptPermissions = null;
10783        }
10784    }
10785
10786    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
10787            throws PackageManagerException {
10788        if (object == null) {
10789            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
10790        }
10791        return object;
10792    }
10793
10794    /**
10795     * Asserts the parsed package is valid according to the given policy. If the
10796     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10797     * <p>
10798     * Implementation detail: This method must NOT have any side effects. It would
10799     * ideally be static, but, it requires locks to read system state.
10800     *
10801     * @throws PackageManagerException If the package fails any of the validation checks
10802     */
10803    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10804            final @ScanFlags int scanFlags)
10805                    throws PackageManagerException {
10806        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10807            assertCodePolicy(pkg);
10808        }
10809
10810        if (pkg.applicationInfo.getCodePath() == null ||
10811                pkg.applicationInfo.getResourcePath() == null) {
10812            // Bail out. The resource and code paths haven't been set.
10813            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10814                    "Code and resource paths haven't been set correctly");
10815        }
10816
10817        // Make sure we're not adding any bogus keyset info
10818        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10819        ksms.assertScannedPackageValid(pkg);
10820
10821        synchronized (mPackages) {
10822            // The special "android" package can only be defined once
10823            if (pkg.packageName.equals("android")) {
10824                if (mAndroidApplication != null) {
10825                    Slog.w(TAG, "*************************************************");
10826                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10827                    Slog.w(TAG, " codePath=" + pkg.codePath);
10828                    Slog.w(TAG, "*************************************************");
10829                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10830                            "Core android package being redefined.  Skipping.");
10831                }
10832            }
10833
10834            // A package name must be unique; don't allow duplicates
10835            if (mPackages.containsKey(pkg.packageName)) {
10836                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10837                        "Application package " + pkg.packageName
10838                        + " already installed.  Skipping duplicate.");
10839            }
10840
10841            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10842                // Static libs have a synthetic package name containing the version
10843                // but we still want the base name to be unique.
10844                if (mPackages.containsKey(pkg.manifestPackageName)) {
10845                    throw new PackageManagerException(
10846                            "Duplicate static shared lib provider package");
10847                }
10848
10849                // Static shared libraries should have at least O target SDK
10850                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10851                    throw new PackageManagerException(
10852                            "Packages declaring static-shared libs must target O SDK or higher");
10853                }
10854
10855                // Package declaring static a shared lib cannot be instant apps
10856                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10857                    throw new PackageManagerException(
10858                            "Packages declaring static-shared libs cannot be instant apps");
10859                }
10860
10861                // Package declaring static a shared lib cannot be renamed since the package
10862                // name is synthetic and apps can't code around package manager internals.
10863                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10864                    throw new PackageManagerException(
10865                            "Packages declaring static-shared libs cannot be renamed");
10866                }
10867
10868                // Package declaring static a shared lib cannot declare child packages
10869                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10870                    throw new PackageManagerException(
10871                            "Packages declaring static-shared libs cannot have child packages");
10872                }
10873
10874                // Package declaring static a shared lib cannot declare dynamic libs
10875                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10876                    throw new PackageManagerException(
10877                            "Packages declaring static-shared libs cannot declare dynamic libs");
10878                }
10879
10880                // Package declaring static a shared lib cannot declare shared users
10881                if (pkg.mSharedUserId != null) {
10882                    throw new PackageManagerException(
10883                            "Packages declaring static-shared libs cannot declare shared users");
10884                }
10885
10886                // Static shared libs cannot declare activities
10887                if (!pkg.activities.isEmpty()) {
10888                    throw new PackageManagerException(
10889                            "Static shared libs cannot declare activities");
10890                }
10891
10892                // Static shared libs cannot declare services
10893                if (!pkg.services.isEmpty()) {
10894                    throw new PackageManagerException(
10895                            "Static shared libs cannot declare services");
10896                }
10897
10898                // Static shared libs cannot declare providers
10899                if (!pkg.providers.isEmpty()) {
10900                    throw new PackageManagerException(
10901                            "Static shared libs cannot declare content providers");
10902                }
10903
10904                // Static shared libs cannot declare receivers
10905                if (!pkg.receivers.isEmpty()) {
10906                    throw new PackageManagerException(
10907                            "Static shared libs cannot declare broadcast receivers");
10908                }
10909
10910                // Static shared libs cannot declare permission groups
10911                if (!pkg.permissionGroups.isEmpty()) {
10912                    throw new PackageManagerException(
10913                            "Static shared libs cannot declare permission groups");
10914                }
10915
10916                // Static shared libs cannot declare permissions
10917                if (!pkg.permissions.isEmpty()) {
10918                    throw new PackageManagerException(
10919                            "Static shared libs cannot declare permissions");
10920                }
10921
10922                // Static shared libs cannot declare protected broadcasts
10923                if (pkg.protectedBroadcasts != null) {
10924                    throw new PackageManagerException(
10925                            "Static shared libs cannot declare protected broadcasts");
10926                }
10927
10928                // Static shared libs cannot be overlay targets
10929                if (pkg.mOverlayTarget != null) {
10930                    throw new PackageManagerException(
10931                            "Static shared libs cannot be overlay targets");
10932                }
10933
10934                // The version codes must be ordered as lib versions
10935                long minVersionCode = Long.MIN_VALUE;
10936                long maxVersionCode = Long.MAX_VALUE;
10937
10938                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10939                        pkg.staticSharedLibName);
10940                if (versionedLib != null) {
10941                    final int versionCount = versionedLib.size();
10942                    for (int i = 0; i < versionCount; i++) {
10943                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10944                        final long libVersionCode = libInfo.getDeclaringPackage()
10945                                .getLongVersionCode();
10946                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10947                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10948                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10949                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10950                        } else {
10951                            minVersionCode = maxVersionCode = libVersionCode;
10952                            break;
10953                        }
10954                    }
10955                }
10956                if (pkg.getLongVersionCode() < minVersionCode
10957                        || pkg.getLongVersionCode() > maxVersionCode) {
10958                    throw new PackageManagerException("Static shared"
10959                            + " lib version codes must be ordered as lib versions");
10960                }
10961            }
10962
10963            // Only privileged apps and updated privileged apps can add child packages.
10964            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10965                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10966                    throw new PackageManagerException("Only privileged apps can add child "
10967                            + "packages. Ignoring package " + pkg.packageName);
10968                }
10969                final int childCount = pkg.childPackages.size();
10970                for (int i = 0; i < childCount; i++) {
10971                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10972                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10973                            childPkg.packageName)) {
10974                        throw new PackageManagerException("Can't override child of "
10975                                + "another disabled app. Ignoring package " + pkg.packageName);
10976                    }
10977                }
10978            }
10979
10980            // If we're only installing presumed-existing packages, require that the
10981            // scanned APK is both already known and at the path previously established
10982            // for it.  Previously unknown packages we pick up normally, but if we have an
10983            // a priori expectation about this package's install presence, enforce it.
10984            // With a singular exception for new system packages. When an OTA contains
10985            // a new system package, we allow the codepath to change from a system location
10986            // to the user-installed location. If we don't allow this change, any newer,
10987            // user-installed version of the application will be ignored.
10988            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10989                if (mExpectingBetter.containsKey(pkg.packageName)) {
10990                    logCriticalInfo(Log.WARN,
10991                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10992                } else {
10993                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10994                    if (known != null) {
10995                        if (DEBUG_PACKAGE_SCANNING) {
10996                            Log.d(TAG, "Examining " + pkg.codePath
10997                                    + " and requiring known paths " + known.codePathString
10998                                    + " & " + known.resourcePathString);
10999                        }
11000                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11001                                || !pkg.applicationInfo.getResourcePath().equals(
11002                                        known.resourcePathString)) {
11003                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11004                                    "Application package " + pkg.packageName
11005                                    + " found at " + pkg.applicationInfo.getCodePath()
11006                                    + " but expected at " + known.codePathString
11007                                    + "; ignoring.");
11008                        }
11009                    } else {
11010                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11011                                "Application package " + pkg.packageName
11012                                + " not found; ignoring.");
11013                    }
11014                }
11015            }
11016
11017            // Verify that this new package doesn't have any content providers
11018            // that conflict with existing packages.  Only do this if the
11019            // package isn't already installed, since we don't want to break
11020            // things that are installed.
11021            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11022                final int N = pkg.providers.size();
11023                int i;
11024                for (i=0; i<N; i++) {
11025                    PackageParser.Provider p = pkg.providers.get(i);
11026                    if (p.info.authority != null) {
11027                        String names[] = p.info.authority.split(";");
11028                        for (int j = 0; j < names.length; j++) {
11029                            if (mProvidersByAuthority.containsKey(names[j])) {
11030                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11031                                final String otherPackageName =
11032                                        ((other != null && other.getComponentName() != null) ?
11033                                                other.getComponentName().getPackageName() : "?");
11034                                throw new PackageManagerException(
11035                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11036                                        "Can't install because provider name " + names[j]
11037                                                + " (in package " + pkg.applicationInfo.packageName
11038                                                + ") is already used by " + otherPackageName);
11039                            }
11040                        }
11041                    }
11042                }
11043            }
11044
11045            // Verify that packages sharing a user with a privileged app are marked as privileged.
11046            if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
11047                SharedUserSetting sharedUserSetting = null;
11048                try {
11049                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
11050                } catch (PackageManagerException ignore) {}
11051                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11052                    // Exempt SharedUsers signed with the platform key.
11053                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11054                    if ((platformPkgSetting.signatures.mSigningDetails
11055                            != PackageParser.SigningDetails.UNKNOWN)
11056                            && (compareSignatures(
11057                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11058                                    pkg.mSigningDetails.signatures)
11059                                            != PackageManager.SIGNATURE_MATCH)) {
11060                        throw new PackageManagerException("Apps that share a user with a " +
11061                                "privileged app must themselves be marked as privileged. " +
11062                                pkg.packageName + " shares privileged user " +
11063                                pkg.mSharedUserId + ".");
11064                    }
11065                }
11066            }
11067
11068            // Apply policies specific for runtime resource overlays (RROs).
11069            if (pkg.mOverlayTarget != null) {
11070                // System overlays have some restrictions on their use of the 'static' state.
11071                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11072                    // We are scanning a system overlay. This can be the first scan of the
11073                    // system/vendor/oem partition, or an update to the system overlay.
11074                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11075                        // This must be an update to a system overlay.
11076                        final PackageSetting previousPkg = assertNotNull(
11077                                mSettings.getPackageLPr(pkg.packageName),
11078                                "previous package state not present");
11079
11080                        // Static overlays cannot be updated.
11081                        if (previousPkg.pkg.mOverlayIsStatic) {
11082                            throw new PackageManagerException("Overlay " + pkg.packageName +
11083                                    " is static and cannot be upgraded.");
11084                        // Non-static overlays cannot be converted to static overlays.
11085                        } else if (pkg.mOverlayIsStatic) {
11086                            throw new PackageManagerException("Overlay " + pkg.packageName +
11087                                    " cannot be upgraded into a static overlay.");
11088                        }
11089                    }
11090                } else {
11091                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
11092                    if (pkg.mOverlayIsStatic) {
11093                        throw new PackageManagerException("Overlay " + pkg.packageName +
11094                                " is static but not pre-installed.");
11095                    }
11096
11097                    // The only case where we allow installation of a non-system overlay is when
11098                    // its signature is signed with the platform certificate.
11099                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
11100                    if ((platformPkgSetting.signatures.mSigningDetails
11101                            != PackageParser.SigningDetails.UNKNOWN)
11102                            && (compareSignatures(
11103                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11104                                    pkg.mSigningDetails.signatures)
11105                                            != PackageManager.SIGNATURE_MATCH)) {
11106                        throw new PackageManagerException("Overlay " + pkg.packageName +
11107                                " must be signed with the platform certificate.");
11108                    }
11109                }
11110            }
11111        }
11112    }
11113
11114    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
11115            int type, String declaringPackageName, long declaringVersionCode) {
11116        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11117        if (versionedLib == null) {
11118            versionedLib = new LongSparseArray<>();
11119            mSharedLibraries.put(name, versionedLib);
11120            if (type == SharedLibraryInfo.TYPE_STATIC) {
11121                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11122            }
11123        } else if (versionedLib.indexOfKey(version) >= 0) {
11124            return false;
11125        }
11126        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11127                version, type, declaringPackageName, declaringVersionCode);
11128        versionedLib.put(version, libEntry);
11129        return true;
11130    }
11131
11132    private boolean removeSharedLibraryLPw(String name, long version) {
11133        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11134        if (versionedLib == null) {
11135            return false;
11136        }
11137        final int libIdx = versionedLib.indexOfKey(version);
11138        if (libIdx < 0) {
11139            return false;
11140        }
11141        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11142        versionedLib.remove(version);
11143        if (versionedLib.size() <= 0) {
11144            mSharedLibraries.remove(name);
11145            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11146                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11147                        .getPackageName());
11148            }
11149        }
11150        return true;
11151    }
11152
11153    /**
11154     * Adds a scanned package to the system. When this method is finished, the package will
11155     * be available for query, resolution, etc...
11156     */
11157    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11158            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
11159        final String pkgName = pkg.packageName;
11160        if (mCustomResolverComponentName != null &&
11161                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11162            setUpCustomResolverActivity(pkg);
11163        }
11164
11165        if (pkg.packageName.equals("android")) {
11166            synchronized (mPackages) {
11167                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11168                    // Set up information for our fall-back user intent resolution activity.
11169                    mPlatformPackage = pkg;
11170                    pkg.mVersionCode = mSdkVersion;
11171                    pkg.mVersionCodeMajor = 0;
11172                    mAndroidApplication = pkg.applicationInfo;
11173                    if (!mResolverReplaced) {
11174                        mResolveActivity.applicationInfo = mAndroidApplication;
11175                        mResolveActivity.name = ResolverActivity.class.getName();
11176                        mResolveActivity.packageName = mAndroidApplication.packageName;
11177                        mResolveActivity.processName = "system:ui";
11178                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11179                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11180                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11181                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11182                        mResolveActivity.exported = true;
11183                        mResolveActivity.enabled = true;
11184                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11185                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11186                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11187                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11188                                | ActivityInfo.CONFIG_ORIENTATION
11189                                | ActivityInfo.CONFIG_KEYBOARD
11190                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11191                        mResolveInfo.activityInfo = mResolveActivity;
11192                        mResolveInfo.priority = 0;
11193                        mResolveInfo.preferredOrder = 0;
11194                        mResolveInfo.match = 0;
11195                        mResolveComponentName = new ComponentName(
11196                                mAndroidApplication.packageName, mResolveActivity.name);
11197                    }
11198                }
11199            }
11200        }
11201
11202        ArrayList<PackageParser.Package> clientLibPkgs = null;
11203        // writer
11204        synchronized (mPackages) {
11205            boolean hasStaticSharedLibs = false;
11206
11207            // Any app can add new static shared libraries
11208            if (pkg.staticSharedLibName != null) {
11209                // Static shared libs don't allow renaming as they have synthetic package
11210                // names to allow install of multiple versions, so use name from manifest.
11211                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11212                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11213                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
11214                    hasStaticSharedLibs = true;
11215                } else {
11216                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11217                                + pkg.staticSharedLibName + " already exists; skipping");
11218                }
11219                // Static shared libs cannot be updated once installed since they
11220                // use synthetic package name which includes the version code, so
11221                // not need to update other packages's shared lib dependencies.
11222            }
11223
11224            if (!hasStaticSharedLibs
11225                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11226                // Only system apps can add new dynamic shared libraries.
11227                if (pkg.libraryNames != null) {
11228                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11229                        String name = pkg.libraryNames.get(i);
11230                        boolean allowed = false;
11231                        if (pkg.isUpdatedSystemApp()) {
11232                            // New library entries can only be added through the
11233                            // system image.  This is important to get rid of a lot
11234                            // of nasty edge cases: for example if we allowed a non-
11235                            // system update of the app to add a library, then uninstalling
11236                            // the update would make the library go away, and assumptions
11237                            // we made such as through app install filtering would now
11238                            // have allowed apps on the device which aren't compatible
11239                            // with it.  Better to just have the restriction here, be
11240                            // conservative, and create many fewer cases that can negatively
11241                            // impact the user experience.
11242                            final PackageSetting sysPs = mSettings
11243                                    .getDisabledSystemPkgLPr(pkg.packageName);
11244                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11245                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11246                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11247                                        allowed = true;
11248                                        break;
11249                                    }
11250                                }
11251                            }
11252                        } else {
11253                            allowed = true;
11254                        }
11255                        if (allowed) {
11256                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11257                                    SharedLibraryInfo.VERSION_UNDEFINED,
11258                                    SharedLibraryInfo.TYPE_DYNAMIC,
11259                                    pkg.packageName, pkg.getLongVersionCode())) {
11260                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11261                                        + name + " already exists; skipping");
11262                            }
11263                        } else {
11264                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11265                                    + name + " that is not declared on system image; skipping");
11266                        }
11267                    }
11268
11269                    if ((scanFlags & SCAN_BOOTING) == 0) {
11270                        // If we are not booting, we need to update any applications
11271                        // that are clients of our shared library.  If we are booting,
11272                        // this will all be done once the scan is complete.
11273                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11274                    }
11275                }
11276            }
11277        }
11278
11279        if ((scanFlags & SCAN_BOOTING) != 0) {
11280            // No apps can run during boot scan, so they don't need to be frozen
11281        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11282            // Caller asked to not kill app, so it's probably not frozen
11283        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11284            // Caller asked us to ignore frozen check for some reason; they
11285            // probably didn't know the package name
11286        } else {
11287            // We're doing major surgery on this package, so it better be frozen
11288            // right now to keep it from launching
11289            checkPackageFrozen(pkgName);
11290        }
11291
11292        // Also need to kill any apps that are dependent on the library.
11293        if (clientLibPkgs != null) {
11294            for (int i=0; i<clientLibPkgs.size(); i++) {
11295                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11296                killApplication(clientPkg.applicationInfo.packageName,
11297                        clientPkg.applicationInfo.uid, "update lib");
11298            }
11299        }
11300
11301        // writer
11302        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11303
11304        synchronized (mPackages) {
11305            // We don't expect installation to fail beyond this point
11306
11307            // Add the new setting to mSettings
11308            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11309            // Add the new setting to mPackages
11310            mPackages.put(pkg.applicationInfo.packageName, pkg);
11311            // Make sure we don't accidentally delete its data.
11312            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11313            while (iter.hasNext()) {
11314                PackageCleanItem item = iter.next();
11315                if (pkgName.equals(item.packageName)) {
11316                    iter.remove();
11317                }
11318            }
11319
11320            // Add the package's KeySets to the global KeySetManagerService
11321            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11322            ksms.addScannedPackageLPw(pkg);
11323
11324            int N = pkg.providers.size();
11325            StringBuilder r = null;
11326            int i;
11327            for (i=0; i<N; i++) {
11328                PackageParser.Provider p = pkg.providers.get(i);
11329                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11330                        p.info.processName);
11331                mProviders.addProvider(p);
11332                p.syncable = p.info.isSyncable;
11333                if (p.info.authority != null) {
11334                    String names[] = p.info.authority.split(";");
11335                    p.info.authority = null;
11336                    for (int j = 0; j < names.length; j++) {
11337                        if (j == 1 && p.syncable) {
11338                            // We only want the first authority for a provider to possibly be
11339                            // syncable, so if we already added this provider using a different
11340                            // authority clear the syncable flag. We copy the provider before
11341                            // changing it because the mProviders object contains a reference
11342                            // to a provider that we don't want to change.
11343                            // Only do this for the second authority since the resulting provider
11344                            // object can be the same for all future authorities for this provider.
11345                            p = new PackageParser.Provider(p);
11346                            p.syncable = false;
11347                        }
11348                        if (!mProvidersByAuthority.containsKey(names[j])) {
11349                            mProvidersByAuthority.put(names[j], p);
11350                            if (p.info.authority == null) {
11351                                p.info.authority = names[j];
11352                            } else {
11353                                p.info.authority = p.info.authority + ";" + names[j];
11354                            }
11355                            if (DEBUG_PACKAGE_SCANNING) {
11356                                if (chatty)
11357                                    Log.d(TAG, "Registered content provider: " + names[j]
11358                                            + ", className = " + p.info.name + ", isSyncable = "
11359                                            + p.info.isSyncable);
11360                            }
11361                        } else {
11362                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11363                            Slog.w(TAG, "Skipping provider name " + names[j] +
11364                                    " (in package " + pkg.applicationInfo.packageName +
11365                                    "): name already used by "
11366                                    + ((other != null && other.getComponentName() != null)
11367                                            ? other.getComponentName().getPackageName() : "?"));
11368                        }
11369                    }
11370                }
11371                if (chatty) {
11372                    if (r == null) {
11373                        r = new StringBuilder(256);
11374                    } else {
11375                        r.append(' ');
11376                    }
11377                    r.append(p.info.name);
11378                }
11379            }
11380            if (r != null) {
11381                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11382            }
11383
11384            N = pkg.services.size();
11385            r = null;
11386            for (i=0; i<N; i++) {
11387                PackageParser.Service s = pkg.services.get(i);
11388                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11389                        s.info.processName);
11390                mServices.addService(s);
11391                if (chatty) {
11392                    if (r == null) {
11393                        r = new StringBuilder(256);
11394                    } else {
11395                        r.append(' ');
11396                    }
11397                    r.append(s.info.name);
11398                }
11399            }
11400            if (r != null) {
11401                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11402            }
11403
11404            N = pkg.receivers.size();
11405            r = null;
11406            for (i=0; i<N; i++) {
11407                PackageParser.Activity a = pkg.receivers.get(i);
11408                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11409                        a.info.processName);
11410                mReceivers.addActivity(a, "receiver");
11411                if (chatty) {
11412                    if (r == null) {
11413                        r = new StringBuilder(256);
11414                    } else {
11415                        r.append(' ');
11416                    }
11417                    r.append(a.info.name);
11418                }
11419            }
11420            if (r != null) {
11421                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11422            }
11423
11424            N = pkg.activities.size();
11425            r = null;
11426            for (i=0; i<N; i++) {
11427                PackageParser.Activity a = pkg.activities.get(i);
11428                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11429                        a.info.processName);
11430                mActivities.addActivity(a, "activity");
11431                if (chatty) {
11432                    if (r == null) {
11433                        r = new StringBuilder(256);
11434                    } else {
11435                        r.append(' ');
11436                    }
11437                    r.append(a.info.name);
11438                }
11439            }
11440            if (r != null) {
11441                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11442            }
11443
11444            // Don't allow ephemeral applications to define new permissions groups.
11445            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11446                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11447                        + " ignored: instant apps cannot define new permission groups.");
11448            } else {
11449                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11450            }
11451
11452            // Don't allow ephemeral applications to define new permissions.
11453            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11454                Slog.w(TAG, "Permissions from package " + pkg.packageName
11455                        + " ignored: instant apps cannot define new permissions.");
11456            } else {
11457                mPermissionManager.addAllPermissions(pkg, chatty);
11458            }
11459
11460            N = pkg.instrumentation.size();
11461            r = null;
11462            for (i=0; i<N; i++) {
11463                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11464                a.info.packageName = pkg.applicationInfo.packageName;
11465                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11466                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11467                a.info.splitNames = pkg.splitNames;
11468                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11469                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11470                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11471                a.info.dataDir = pkg.applicationInfo.dataDir;
11472                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11473                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11474                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11475                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11476                mInstrumentation.put(a.getComponentName(), a);
11477                if (chatty) {
11478                    if (r == null) {
11479                        r = new StringBuilder(256);
11480                    } else {
11481                        r.append(' ');
11482                    }
11483                    r.append(a.info.name);
11484                }
11485            }
11486            if (r != null) {
11487                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11488            }
11489
11490            if (pkg.protectedBroadcasts != null) {
11491                N = pkg.protectedBroadcasts.size();
11492                synchronized (mProtectedBroadcasts) {
11493                    for (i = 0; i < N; i++) {
11494                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11495                    }
11496                }
11497            }
11498        }
11499
11500        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11501    }
11502
11503    /**
11504     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11505     * is derived purely on the basis of the contents of {@code scanFile} and
11506     * {@code cpuAbiOverride}.
11507     *
11508     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11509     */
11510    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11511            boolean extractLibs)
11512                    throws PackageManagerException {
11513        // Give ourselves some initial paths; we'll come back for another
11514        // pass once we've determined ABI below.
11515        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11516
11517        // We would never need to extract libs for forward-locked and external packages,
11518        // since the container service will do it for us. We shouldn't attempt to
11519        // extract libs from system app when it was not updated.
11520        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11521                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11522            extractLibs = false;
11523        }
11524
11525        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11526        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11527
11528        NativeLibraryHelper.Handle handle = null;
11529        try {
11530            handle = NativeLibraryHelper.Handle.create(pkg);
11531            // TODO(multiArch): This can be null for apps that didn't go through the
11532            // usual installation process. We can calculate it again, like we
11533            // do during install time.
11534            //
11535            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11536            // unnecessary.
11537            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11538
11539            // Null out the abis so that they can be recalculated.
11540            pkg.applicationInfo.primaryCpuAbi = null;
11541            pkg.applicationInfo.secondaryCpuAbi = null;
11542            if (isMultiArch(pkg.applicationInfo)) {
11543                // Warn if we've set an abiOverride for multi-lib packages..
11544                // By definition, we need to copy both 32 and 64 bit libraries for
11545                // such packages.
11546                if (pkg.cpuAbiOverride != null
11547                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11548                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11549                }
11550
11551                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11552                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11553                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11554                    if (extractLibs) {
11555                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11556                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11557                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11558                                useIsaSpecificSubdirs);
11559                    } else {
11560                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11561                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11562                    }
11563                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11564                }
11565
11566                // Shared library native code should be in the APK zip aligned
11567                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11568                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11569                            "Shared library native lib extraction not supported");
11570                }
11571
11572                maybeThrowExceptionForMultiArchCopy(
11573                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11574
11575                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11576                    if (extractLibs) {
11577                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11578                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11579                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11580                                useIsaSpecificSubdirs);
11581                    } else {
11582                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11583                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11584                    }
11585                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11586                }
11587
11588                maybeThrowExceptionForMultiArchCopy(
11589                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11590
11591                if (abi64 >= 0) {
11592                    // Shared library native libs should be in the APK zip aligned
11593                    if (extractLibs && pkg.isLibrary()) {
11594                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11595                                "Shared library native lib extraction not supported");
11596                    }
11597                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11598                }
11599
11600                if (abi32 >= 0) {
11601                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11602                    if (abi64 >= 0) {
11603                        if (pkg.use32bitAbi) {
11604                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11605                            pkg.applicationInfo.primaryCpuAbi = abi;
11606                        } else {
11607                            pkg.applicationInfo.secondaryCpuAbi = abi;
11608                        }
11609                    } else {
11610                        pkg.applicationInfo.primaryCpuAbi = abi;
11611                    }
11612                }
11613            } else {
11614                String[] abiList = (cpuAbiOverride != null) ?
11615                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11616
11617                // Enable gross and lame hacks for apps that are built with old
11618                // SDK tools. We must scan their APKs for renderscript bitcode and
11619                // not launch them if it's present. Don't bother checking on devices
11620                // that don't have 64 bit support.
11621                boolean needsRenderScriptOverride = false;
11622                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11623                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11624                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11625                    needsRenderScriptOverride = true;
11626                }
11627
11628                final int copyRet;
11629                if (extractLibs) {
11630                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11631                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11632                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11633                } else {
11634                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11635                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11636                }
11637                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11638
11639                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11640                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11641                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11642                }
11643
11644                if (copyRet >= 0) {
11645                    // Shared libraries that have native libs must be multi-architecture
11646                    if (pkg.isLibrary()) {
11647                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11648                                "Shared library with native libs must be multiarch");
11649                    }
11650                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11651                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11652                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11653                } else if (needsRenderScriptOverride) {
11654                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11655                }
11656            }
11657        } catch (IOException ioe) {
11658            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11659        } finally {
11660            IoUtils.closeQuietly(handle);
11661        }
11662
11663        // Now that we've calculated the ABIs and determined if it's an internal app,
11664        // we will go ahead and populate the nativeLibraryPath.
11665        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11666    }
11667
11668    /**
11669     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11670     * i.e, so that all packages can be run inside a single process if required.
11671     *
11672     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11673     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11674     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11675     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11676     * updating a package that belongs to a shared user.
11677     *
11678     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11679     * adds unnecessary complexity.
11680     */
11681    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11682            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11683        List<String> changedAbiCodePath = null;
11684        String requiredInstructionSet = null;
11685        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11686            requiredInstructionSet = VMRuntime.getInstructionSet(
11687                     scannedPackage.applicationInfo.primaryCpuAbi);
11688        }
11689
11690        PackageSetting requirer = null;
11691        for (PackageSetting ps : packagesForUser) {
11692            // If packagesForUser contains scannedPackage, we skip it. This will happen
11693            // when scannedPackage is an update of an existing package. Without this check,
11694            // we will never be able to change the ABI of any package belonging to a shared
11695            // user, even if it's compatible with other packages.
11696            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11697                if (ps.primaryCpuAbiString == null) {
11698                    continue;
11699                }
11700
11701                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11702                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11703                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11704                    // this but there's not much we can do.
11705                    String errorMessage = "Instruction set mismatch, "
11706                            + ((requirer == null) ? "[caller]" : requirer)
11707                            + " requires " + requiredInstructionSet + " whereas " + ps
11708                            + " requires " + instructionSet;
11709                    Slog.w(TAG, errorMessage);
11710                }
11711
11712                if (requiredInstructionSet == null) {
11713                    requiredInstructionSet = instructionSet;
11714                    requirer = ps;
11715                }
11716            }
11717        }
11718
11719        if (requiredInstructionSet != null) {
11720            String adjustedAbi;
11721            if (requirer != null) {
11722                // requirer != null implies that either scannedPackage was null or that scannedPackage
11723                // did not require an ABI, in which case we have to adjust scannedPackage to match
11724                // the ABI of the set (which is the same as requirer's ABI)
11725                adjustedAbi = requirer.primaryCpuAbiString;
11726                if (scannedPackage != null) {
11727                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11728                }
11729            } else {
11730                // requirer == null implies that we're updating all ABIs in the set to
11731                // match scannedPackage.
11732                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11733            }
11734
11735            for (PackageSetting ps : packagesForUser) {
11736                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11737                    if (ps.primaryCpuAbiString != null) {
11738                        continue;
11739                    }
11740
11741                    ps.primaryCpuAbiString = adjustedAbi;
11742                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11743                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11744                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11745                        if (DEBUG_ABI_SELECTION) {
11746                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11747                                    + " (requirer="
11748                                    + (requirer != null ? requirer.pkg : "null")
11749                                    + ", scannedPackage="
11750                                    + (scannedPackage != null ? scannedPackage : "null")
11751                                    + ")");
11752                        }
11753                        if (changedAbiCodePath == null) {
11754                            changedAbiCodePath = new ArrayList<>();
11755                        }
11756                        changedAbiCodePath.add(ps.codePathString);
11757                    }
11758                }
11759            }
11760        }
11761        return changedAbiCodePath;
11762    }
11763
11764    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11765        synchronized (mPackages) {
11766            mResolverReplaced = true;
11767            // Set up information for custom user intent resolution activity.
11768            mResolveActivity.applicationInfo = pkg.applicationInfo;
11769            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11770            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11771            mResolveActivity.processName = pkg.applicationInfo.packageName;
11772            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11773            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11774                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11775            mResolveActivity.theme = 0;
11776            mResolveActivity.exported = true;
11777            mResolveActivity.enabled = true;
11778            mResolveInfo.activityInfo = mResolveActivity;
11779            mResolveInfo.priority = 0;
11780            mResolveInfo.preferredOrder = 0;
11781            mResolveInfo.match = 0;
11782            mResolveComponentName = mCustomResolverComponentName;
11783            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11784                    mResolveComponentName);
11785        }
11786    }
11787
11788    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11789        if (installerActivity == null) {
11790            if (DEBUG_INSTANT) {
11791                Slog.d(TAG, "Clear ephemeral installer activity");
11792            }
11793            mInstantAppInstallerActivity = null;
11794            return;
11795        }
11796
11797        if (DEBUG_INSTANT) {
11798            Slog.d(TAG, "Set ephemeral installer activity: "
11799                    + installerActivity.getComponentName());
11800        }
11801        // Set up information for ephemeral installer activity
11802        mInstantAppInstallerActivity = installerActivity;
11803        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11804                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11805        mInstantAppInstallerActivity.exported = true;
11806        mInstantAppInstallerActivity.enabled = true;
11807        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11808        mInstantAppInstallerInfo.priority = 1;
11809        mInstantAppInstallerInfo.preferredOrder = 1;
11810        mInstantAppInstallerInfo.isDefault = true;
11811        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11812                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11813    }
11814
11815    private static String calculateBundledApkRoot(final String codePathString) {
11816        final File codePath = new File(codePathString);
11817        final File codeRoot;
11818        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11819            codeRoot = Environment.getRootDirectory();
11820        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11821            codeRoot = Environment.getOemDirectory();
11822        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11823            codeRoot = Environment.getVendorDirectory();
11824        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
11825            codeRoot = Environment.getOdmDirectory();
11826        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
11827            codeRoot = Environment.getProductDirectory();
11828        } else {
11829            // Unrecognized code path; take its top real segment as the apk root:
11830            // e.g. /something/app/blah.apk => /something
11831            try {
11832                File f = codePath.getCanonicalFile();
11833                File parent = f.getParentFile();    // non-null because codePath is a file
11834                File tmp;
11835                while ((tmp = parent.getParentFile()) != null) {
11836                    f = parent;
11837                    parent = tmp;
11838                }
11839                codeRoot = f;
11840                Slog.w(TAG, "Unrecognized code path "
11841                        + codePath + " - using " + codeRoot);
11842            } catch (IOException e) {
11843                // Can't canonicalize the code path -- shenanigans?
11844                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11845                return Environment.getRootDirectory().getPath();
11846            }
11847        }
11848        return codeRoot.getPath();
11849    }
11850
11851    /**
11852     * Derive and set the location of native libraries for the given package,
11853     * which varies depending on where and how the package was installed.
11854     */
11855    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11856        final ApplicationInfo info = pkg.applicationInfo;
11857        final String codePath = pkg.codePath;
11858        final File codeFile = new File(codePath);
11859        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11860        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11861
11862        info.nativeLibraryRootDir = null;
11863        info.nativeLibraryRootRequiresIsa = false;
11864        info.nativeLibraryDir = null;
11865        info.secondaryNativeLibraryDir = null;
11866
11867        if (isApkFile(codeFile)) {
11868            // Monolithic install
11869            if (bundledApp) {
11870                // If "/system/lib64/apkname" exists, assume that is the per-package
11871                // native library directory to use; otherwise use "/system/lib/apkname".
11872                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11873                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11874                        getPrimaryInstructionSet(info));
11875
11876                // This is a bundled system app so choose the path based on the ABI.
11877                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11878                // is just the default path.
11879                final String apkName = deriveCodePathName(codePath);
11880                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11881                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11882                        apkName).getAbsolutePath();
11883
11884                if (info.secondaryCpuAbi != null) {
11885                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11886                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11887                            secondaryLibDir, apkName).getAbsolutePath();
11888                }
11889            } else if (asecApp) {
11890                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11891                        .getAbsolutePath();
11892            } else {
11893                final String apkName = deriveCodePathName(codePath);
11894                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11895                        .getAbsolutePath();
11896            }
11897
11898            info.nativeLibraryRootRequiresIsa = false;
11899            info.nativeLibraryDir = info.nativeLibraryRootDir;
11900        } else {
11901            // Cluster install
11902            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11903            info.nativeLibraryRootRequiresIsa = true;
11904
11905            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11906                    getPrimaryInstructionSet(info)).getAbsolutePath();
11907
11908            if (info.secondaryCpuAbi != null) {
11909                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11910                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11911            }
11912        }
11913    }
11914
11915    /**
11916     * Calculate the abis and roots for a bundled app. These can uniquely
11917     * be determined from the contents of the system partition, i.e whether
11918     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11919     * of this information, and instead assume that the system was built
11920     * sensibly.
11921     */
11922    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11923                                           PackageSetting pkgSetting) {
11924        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11925
11926        // If "/system/lib64/apkname" exists, assume that is the per-package
11927        // native library directory to use; otherwise use "/system/lib/apkname".
11928        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11929        setBundledAppAbi(pkg, apkRoot, apkName);
11930        // pkgSetting might be null during rescan following uninstall of updates
11931        // to a bundled app, so accommodate that possibility.  The settings in
11932        // that case will be established later from the parsed package.
11933        //
11934        // If the settings aren't null, sync them up with what we've just derived.
11935        // note that apkRoot isn't stored in the package settings.
11936        if (pkgSetting != null) {
11937            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11938            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11939        }
11940    }
11941
11942    /**
11943     * Deduces the ABI of a bundled app and sets the relevant fields on the
11944     * parsed pkg object.
11945     *
11946     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11947     *        under which system libraries are installed.
11948     * @param apkName the name of the installed package.
11949     */
11950    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11951        final File codeFile = new File(pkg.codePath);
11952
11953        final boolean has64BitLibs;
11954        final boolean has32BitLibs;
11955        if (isApkFile(codeFile)) {
11956            // Monolithic install
11957            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11958            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11959        } else {
11960            // Cluster install
11961            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11962            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11963                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11964                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11965                has64BitLibs = (new File(rootDir, isa)).exists();
11966            } else {
11967                has64BitLibs = false;
11968            }
11969            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11970                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11971                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11972                has32BitLibs = (new File(rootDir, isa)).exists();
11973            } else {
11974                has32BitLibs = false;
11975            }
11976        }
11977
11978        if (has64BitLibs && !has32BitLibs) {
11979            // The package has 64 bit libs, but not 32 bit libs. Its primary
11980            // ABI should be 64 bit. We can safely assume here that the bundled
11981            // native libraries correspond to the most preferred ABI in the list.
11982
11983            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11984            pkg.applicationInfo.secondaryCpuAbi = null;
11985        } else if (has32BitLibs && !has64BitLibs) {
11986            // The package has 32 bit libs but not 64 bit libs. Its primary
11987            // ABI should be 32 bit.
11988
11989            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11990            pkg.applicationInfo.secondaryCpuAbi = null;
11991        } else if (has32BitLibs && has64BitLibs) {
11992            // The application has both 64 and 32 bit bundled libraries. We check
11993            // here that the app declares multiArch support, and warn if it doesn't.
11994            //
11995            // We will be lenient here and record both ABIs. The primary will be the
11996            // ABI that's higher on the list, i.e, a device that's configured to prefer
11997            // 64 bit apps will see a 64 bit primary ABI,
11998
11999            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12000                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12001            }
12002
12003            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12004                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12005                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12006            } else {
12007                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12008                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12009            }
12010        } else {
12011            pkg.applicationInfo.primaryCpuAbi = null;
12012            pkg.applicationInfo.secondaryCpuAbi = null;
12013        }
12014    }
12015
12016    private void killApplication(String pkgName, int appId, String reason) {
12017        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12018    }
12019
12020    private void killApplication(String pkgName, int appId, int userId, String reason) {
12021        // Request the ActivityManager to kill the process(only for existing packages)
12022        // so that we do not end up in a confused state while the user is still using the older
12023        // version of the application while the new one gets installed.
12024        final long token = Binder.clearCallingIdentity();
12025        try {
12026            IActivityManager am = ActivityManager.getService();
12027            if (am != null) {
12028                try {
12029                    am.killApplication(pkgName, appId, userId, reason);
12030                } catch (RemoteException e) {
12031                }
12032            }
12033        } finally {
12034            Binder.restoreCallingIdentity(token);
12035        }
12036    }
12037
12038    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12039        // Remove the parent package setting
12040        PackageSetting ps = (PackageSetting) pkg.mExtras;
12041        if (ps != null) {
12042            removePackageLI(ps, chatty);
12043        }
12044        // Remove the child package setting
12045        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12046        for (int i = 0; i < childCount; i++) {
12047            PackageParser.Package childPkg = pkg.childPackages.get(i);
12048            ps = (PackageSetting) childPkg.mExtras;
12049            if (ps != null) {
12050                removePackageLI(ps, chatty);
12051            }
12052        }
12053    }
12054
12055    void removePackageLI(PackageSetting ps, boolean chatty) {
12056        if (DEBUG_INSTALL) {
12057            if (chatty)
12058                Log.d(TAG, "Removing package " + ps.name);
12059        }
12060
12061        // writer
12062        synchronized (mPackages) {
12063            mPackages.remove(ps.name);
12064            final PackageParser.Package pkg = ps.pkg;
12065            if (pkg != null) {
12066                cleanPackageDataStructuresLILPw(pkg, chatty);
12067            }
12068        }
12069    }
12070
12071    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12072        if (DEBUG_INSTALL) {
12073            if (chatty)
12074                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12075        }
12076
12077        // writer
12078        synchronized (mPackages) {
12079            // Remove the parent package
12080            mPackages.remove(pkg.applicationInfo.packageName);
12081            cleanPackageDataStructuresLILPw(pkg, chatty);
12082
12083            // Remove the child packages
12084            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12085            for (int i = 0; i < childCount; i++) {
12086                PackageParser.Package childPkg = pkg.childPackages.get(i);
12087                mPackages.remove(childPkg.applicationInfo.packageName);
12088                cleanPackageDataStructuresLILPw(childPkg, chatty);
12089            }
12090        }
12091    }
12092
12093    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12094        int N = pkg.providers.size();
12095        StringBuilder r = null;
12096        int i;
12097        for (i=0; i<N; i++) {
12098            PackageParser.Provider p = pkg.providers.get(i);
12099            mProviders.removeProvider(p);
12100            if (p.info.authority == null) {
12101
12102                /* There was another ContentProvider with this authority when
12103                 * this app was installed so this authority is null,
12104                 * Ignore it as we don't have to unregister the provider.
12105                 */
12106                continue;
12107            }
12108            String names[] = p.info.authority.split(";");
12109            for (int j = 0; j < names.length; j++) {
12110                if (mProvidersByAuthority.get(names[j]) == p) {
12111                    mProvidersByAuthority.remove(names[j]);
12112                    if (DEBUG_REMOVE) {
12113                        if (chatty)
12114                            Log.d(TAG, "Unregistered content provider: " + names[j]
12115                                    + ", className = " + p.info.name + ", isSyncable = "
12116                                    + p.info.isSyncable);
12117                    }
12118                }
12119            }
12120            if (DEBUG_REMOVE && chatty) {
12121                if (r == null) {
12122                    r = new StringBuilder(256);
12123                } else {
12124                    r.append(' ');
12125                }
12126                r.append(p.info.name);
12127            }
12128        }
12129        if (r != null) {
12130            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12131        }
12132
12133        N = pkg.services.size();
12134        r = null;
12135        for (i=0; i<N; i++) {
12136            PackageParser.Service s = pkg.services.get(i);
12137            mServices.removeService(s);
12138            if (chatty) {
12139                if (r == null) {
12140                    r = new StringBuilder(256);
12141                } else {
12142                    r.append(' ');
12143                }
12144                r.append(s.info.name);
12145            }
12146        }
12147        if (r != null) {
12148            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12149        }
12150
12151        N = pkg.receivers.size();
12152        r = null;
12153        for (i=0; i<N; i++) {
12154            PackageParser.Activity a = pkg.receivers.get(i);
12155            mReceivers.removeActivity(a, "receiver");
12156            if (DEBUG_REMOVE && chatty) {
12157                if (r == null) {
12158                    r = new StringBuilder(256);
12159                } else {
12160                    r.append(' ');
12161                }
12162                r.append(a.info.name);
12163            }
12164        }
12165        if (r != null) {
12166            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12167        }
12168
12169        N = pkg.activities.size();
12170        r = null;
12171        for (i=0; i<N; i++) {
12172            PackageParser.Activity a = pkg.activities.get(i);
12173            mActivities.removeActivity(a, "activity");
12174            if (DEBUG_REMOVE && chatty) {
12175                if (r == null) {
12176                    r = new StringBuilder(256);
12177                } else {
12178                    r.append(' ');
12179                }
12180                r.append(a.info.name);
12181            }
12182        }
12183        if (r != null) {
12184            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12185        }
12186
12187        mPermissionManager.removeAllPermissions(pkg, chatty);
12188
12189        N = pkg.instrumentation.size();
12190        r = null;
12191        for (i=0; i<N; i++) {
12192            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12193            mInstrumentation.remove(a.getComponentName());
12194            if (DEBUG_REMOVE && chatty) {
12195                if (r == null) {
12196                    r = new StringBuilder(256);
12197                } else {
12198                    r.append(' ');
12199                }
12200                r.append(a.info.name);
12201            }
12202        }
12203        if (r != null) {
12204            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12205        }
12206
12207        r = null;
12208        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12209            // Only system apps can hold shared libraries.
12210            if (pkg.libraryNames != null) {
12211                for (i = 0; i < pkg.libraryNames.size(); i++) {
12212                    String name = pkg.libraryNames.get(i);
12213                    if (removeSharedLibraryLPw(name, 0)) {
12214                        if (DEBUG_REMOVE && chatty) {
12215                            if (r == null) {
12216                                r = new StringBuilder(256);
12217                            } else {
12218                                r.append(' ');
12219                            }
12220                            r.append(name);
12221                        }
12222                    }
12223                }
12224            }
12225        }
12226
12227        r = null;
12228
12229        // Any package can hold static shared libraries.
12230        if (pkg.staticSharedLibName != null) {
12231            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12232                if (DEBUG_REMOVE && chatty) {
12233                    if (r == null) {
12234                        r = new StringBuilder(256);
12235                    } else {
12236                        r.append(' ');
12237                    }
12238                    r.append(pkg.staticSharedLibName);
12239                }
12240            }
12241        }
12242
12243        if (r != null) {
12244            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12245        }
12246    }
12247
12248
12249    final class ActivityIntentResolver
12250            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12251        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12252                boolean defaultOnly, int userId) {
12253            if (!sUserManager.exists(userId)) return null;
12254            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12255            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12256        }
12257
12258        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12259                int userId) {
12260            if (!sUserManager.exists(userId)) return null;
12261            mFlags = flags;
12262            return super.queryIntent(intent, resolvedType,
12263                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12264                    userId);
12265        }
12266
12267        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12268                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12269            if (!sUserManager.exists(userId)) return null;
12270            if (packageActivities == null) {
12271                return null;
12272            }
12273            mFlags = flags;
12274            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12275            final int N = packageActivities.size();
12276            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12277                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12278
12279            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12280            for (int i = 0; i < N; ++i) {
12281                intentFilters = packageActivities.get(i).intents;
12282                if (intentFilters != null && intentFilters.size() > 0) {
12283                    PackageParser.ActivityIntentInfo[] array =
12284                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12285                    intentFilters.toArray(array);
12286                    listCut.add(array);
12287                }
12288            }
12289            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12290        }
12291
12292        /**
12293         * Finds a privileged activity that matches the specified activity names.
12294         */
12295        private PackageParser.Activity findMatchingActivity(
12296                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12297            for (PackageParser.Activity sysActivity : activityList) {
12298                if (sysActivity.info.name.equals(activityInfo.name)) {
12299                    return sysActivity;
12300                }
12301                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12302                    return sysActivity;
12303                }
12304                if (sysActivity.info.targetActivity != null) {
12305                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12306                        return sysActivity;
12307                    }
12308                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12309                        return sysActivity;
12310                    }
12311                }
12312            }
12313            return null;
12314        }
12315
12316        public class IterGenerator<E> {
12317            public Iterator<E> generate(ActivityIntentInfo info) {
12318                return null;
12319            }
12320        }
12321
12322        public class ActionIterGenerator extends IterGenerator<String> {
12323            @Override
12324            public Iterator<String> generate(ActivityIntentInfo info) {
12325                return info.actionsIterator();
12326            }
12327        }
12328
12329        public class CategoriesIterGenerator extends IterGenerator<String> {
12330            @Override
12331            public Iterator<String> generate(ActivityIntentInfo info) {
12332                return info.categoriesIterator();
12333            }
12334        }
12335
12336        public class SchemesIterGenerator extends IterGenerator<String> {
12337            @Override
12338            public Iterator<String> generate(ActivityIntentInfo info) {
12339                return info.schemesIterator();
12340            }
12341        }
12342
12343        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12344            @Override
12345            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12346                return info.authoritiesIterator();
12347            }
12348        }
12349
12350        /**
12351         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12352         * MODIFIED. Do not pass in a list that should not be changed.
12353         */
12354        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12355                IterGenerator<T> generator, Iterator<T> searchIterator) {
12356            // loop through the set of actions; every one must be found in the intent filter
12357            while (searchIterator.hasNext()) {
12358                // we must have at least one filter in the list to consider a match
12359                if (intentList.size() == 0) {
12360                    break;
12361                }
12362
12363                final T searchAction = searchIterator.next();
12364
12365                // loop through the set of intent filters
12366                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12367                while (intentIter.hasNext()) {
12368                    final ActivityIntentInfo intentInfo = intentIter.next();
12369                    boolean selectionFound = false;
12370
12371                    // loop through the intent filter's selection criteria; at least one
12372                    // of them must match the searched criteria
12373                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12374                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12375                        final T intentSelection = intentSelectionIter.next();
12376                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12377                            selectionFound = true;
12378                            break;
12379                        }
12380                    }
12381
12382                    // the selection criteria wasn't found in this filter's set; this filter
12383                    // is not a potential match
12384                    if (!selectionFound) {
12385                        intentIter.remove();
12386                    }
12387                }
12388            }
12389        }
12390
12391        private boolean isProtectedAction(ActivityIntentInfo filter) {
12392            final Iterator<String> actionsIter = filter.actionsIterator();
12393            while (actionsIter != null && actionsIter.hasNext()) {
12394                final String filterAction = actionsIter.next();
12395                if (PROTECTED_ACTIONS.contains(filterAction)) {
12396                    return true;
12397                }
12398            }
12399            return false;
12400        }
12401
12402        /**
12403         * Adjusts the priority of the given intent filter according to policy.
12404         * <p>
12405         * <ul>
12406         * <li>The priority for non privileged applications is capped to '0'</li>
12407         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12408         * <li>The priority for unbundled updates to privileged applications is capped to the
12409         *      priority defined on the system partition</li>
12410         * </ul>
12411         * <p>
12412         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12413         * allowed to obtain any priority on any action.
12414         */
12415        private void adjustPriority(
12416                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12417            // nothing to do; priority is fine as-is
12418            if (intent.getPriority() <= 0) {
12419                return;
12420            }
12421
12422            final ActivityInfo activityInfo = intent.activity.info;
12423            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12424
12425            final boolean privilegedApp =
12426                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12427            if (!privilegedApp) {
12428                // non-privileged applications can never define a priority >0
12429                if (DEBUG_FILTERS) {
12430                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12431                            + " package: " + applicationInfo.packageName
12432                            + " activity: " + intent.activity.className
12433                            + " origPrio: " + intent.getPriority());
12434                }
12435                intent.setPriority(0);
12436                return;
12437            }
12438
12439            if (systemActivities == null) {
12440                // the system package is not disabled; we're parsing the system partition
12441                if (isProtectedAction(intent)) {
12442                    if (mDeferProtectedFilters) {
12443                        // We can't deal with these just yet. No component should ever obtain a
12444                        // >0 priority for a protected actions, with ONE exception -- the setup
12445                        // wizard. The setup wizard, however, cannot be known until we're able to
12446                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12447                        // until all intent filters have been processed. Chicken, meet egg.
12448                        // Let the filter temporarily have a high priority and rectify the
12449                        // priorities after all system packages have been scanned.
12450                        mProtectedFilters.add(intent);
12451                        if (DEBUG_FILTERS) {
12452                            Slog.i(TAG, "Protected action; save for later;"
12453                                    + " package: " + applicationInfo.packageName
12454                                    + " activity: " + intent.activity.className
12455                                    + " origPrio: " + intent.getPriority());
12456                        }
12457                        return;
12458                    } else {
12459                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12460                            Slog.i(TAG, "No setup wizard;"
12461                                + " All protected intents capped to priority 0");
12462                        }
12463                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12464                            if (DEBUG_FILTERS) {
12465                                Slog.i(TAG, "Found setup wizard;"
12466                                    + " allow priority " + intent.getPriority() + ";"
12467                                    + " package: " + intent.activity.info.packageName
12468                                    + " activity: " + intent.activity.className
12469                                    + " priority: " + intent.getPriority());
12470                            }
12471                            // setup wizard gets whatever it wants
12472                            return;
12473                        }
12474                        if (DEBUG_FILTERS) {
12475                            Slog.i(TAG, "Protected action; cap priority to 0;"
12476                                    + " package: " + intent.activity.info.packageName
12477                                    + " activity: " + intent.activity.className
12478                                    + " origPrio: " + intent.getPriority());
12479                        }
12480                        intent.setPriority(0);
12481                        return;
12482                    }
12483                }
12484                // privileged apps on the system image get whatever priority they request
12485                return;
12486            }
12487
12488            // privileged app unbundled update ... try to find the same activity
12489            final PackageParser.Activity foundActivity =
12490                    findMatchingActivity(systemActivities, activityInfo);
12491            if (foundActivity == null) {
12492                // this is a new activity; it cannot obtain >0 priority
12493                if (DEBUG_FILTERS) {
12494                    Slog.i(TAG, "New activity; cap priority to 0;"
12495                            + " package: " + applicationInfo.packageName
12496                            + " activity: " + intent.activity.className
12497                            + " origPrio: " + intent.getPriority());
12498                }
12499                intent.setPriority(0);
12500                return;
12501            }
12502
12503            // found activity, now check for filter equivalence
12504
12505            // a shallow copy is enough; we modify the list, not its contents
12506            final List<ActivityIntentInfo> intentListCopy =
12507                    new ArrayList<>(foundActivity.intents);
12508            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12509
12510            // find matching action subsets
12511            final Iterator<String> actionsIterator = intent.actionsIterator();
12512            if (actionsIterator != null) {
12513                getIntentListSubset(
12514                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12515                if (intentListCopy.size() == 0) {
12516                    // no more intents to match; we're not equivalent
12517                    if (DEBUG_FILTERS) {
12518                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12519                                + " package: " + applicationInfo.packageName
12520                                + " activity: " + intent.activity.className
12521                                + " origPrio: " + intent.getPriority());
12522                    }
12523                    intent.setPriority(0);
12524                    return;
12525                }
12526            }
12527
12528            // find matching category subsets
12529            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12530            if (categoriesIterator != null) {
12531                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12532                        categoriesIterator);
12533                if (intentListCopy.size() == 0) {
12534                    // no more intents to match; we're not equivalent
12535                    if (DEBUG_FILTERS) {
12536                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12537                                + " package: " + applicationInfo.packageName
12538                                + " activity: " + intent.activity.className
12539                                + " origPrio: " + intent.getPriority());
12540                    }
12541                    intent.setPriority(0);
12542                    return;
12543                }
12544            }
12545
12546            // find matching schemes subsets
12547            final Iterator<String> schemesIterator = intent.schemesIterator();
12548            if (schemesIterator != null) {
12549                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12550                        schemesIterator);
12551                if (intentListCopy.size() == 0) {
12552                    // no more intents to match; we're not equivalent
12553                    if (DEBUG_FILTERS) {
12554                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12555                                + " package: " + applicationInfo.packageName
12556                                + " activity: " + intent.activity.className
12557                                + " origPrio: " + intent.getPriority());
12558                    }
12559                    intent.setPriority(0);
12560                    return;
12561                }
12562            }
12563
12564            // find matching authorities subsets
12565            final Iterator<IntentFilter.AuthorityEntry>
12566                    authoritiesIterator = intent.authoritiesIterator();
12567            if (authoritiesIterator != null) {
12568                getIntentListSubset(intentListCopy,
12569                        new AuthoritiesIterGenerator(),
12570                        authoritiesIterator);
12571                if (intentListCopy.size() == 0) {
12572                    // no more intents to match; we're not equivalent
12573                    if (DEBUG_FILTERS) {
12574                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12575                                + " package: " + applicationInfo.packageName
12576                                + " activity: " + intent.activity.className
12577                                + " origPrio: " + intent.getPriority());
12578                    }
12579                    intent.setPriority(0);
12580                    return;
12581                }
12582            }
12583
12584            // we found matching filter(s); app gets the max priority of all intents
12585            int cappedPriority = 0;
12586            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12587                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12588            }
12589            if (intent.getPriority() > cappedPriority) {
12590                if (DEBUG_FILTERS) {
12591                    Slog.i(TAG, "Found matching filter(s);"
12592                            + " cap priority to " + cappedPriority + ";"
12593                            + " package: " + applicationInfo.packageName
12594                            + " activity: " + intent.activity.className
12595                            + " origPrio: " + intent.getPriority());
12596                }
12597                intent.setPriority(cappedPriority);
12598                return;
12599            }
12600            // all this for nothing; the requested priority was <= what was on the system
12601        }
12602
12603        public final void addActivity(PackageParser.Activity a, String type) {
12604            mActivities.put(a.getComponentName(), a);
12605            if (DEBUG_SHOW_INFO)
12606                Log.v(
12607                TAG, "  " + type + " " +
12608                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12609            if (DEBUG_SHOW_INFO)
12610                Log.v(TAG, "    Class=" + a.info.name);
12611            final int NI = a.intents.size();
12612            for (int j=0; j<NI; j++) {
12613                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12614                if ("activity".equals(type)) {
12615                    final PackageSetting ps =
12616                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12617                    final List<PackageParser.Activity> systemActivities =
12618                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12619                    adjustPriority(systemActivities, intent);
12620                }
12621                if (DEBUG_SHOW_INFO) {
12622                    Log.v(TAG, "    IntentFilter:");
12623                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12624                }
12625                if (!intent.debugCheck()) {
12626                    Log.w(TAG, "==> For Activity " + a.info.name);
12627                }
12628                addFilter(intent);
12629            }
12630        }
12631
12632        public final void removeActivity(PackageParser.Activity a, String type) {
12633            mActivities.remove(a.getComponentName());
12634            if (DEBUG_SHOW_INFO) {
12635                Log.v(TAG, "  " + type + " "
12636                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12637                                : a.info.name) + ":");
12638                Log.v(TAG, "    Class=" + a.info.name);
12639            }
12640            final int NI = a.intents.size();
12641            for (int j=0; j<NI; j++) {
12642                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12643                if (DEBUG_SHOW_INFO) {
12644                    Log.v(TAG, "    IntentFilter:");
12645                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12646                }
12647                removeFilter(intent);
12648            }
12649        }
12650
12651        @Override
12652        protected boolean allowFilterResult(
12653                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12654            ActivityInfo filterAi = filter.activity.info;
12655            for (int i=dest.size()-1; i>=0; i--) {
12656                ActivityInfo destAi = dest.get(i).activityInfo;
12657                if (destAi.name == filterAi.name
12658                        && destAi.packageName == filterAi.packageName) {
12659                    return false;
12660                }
12661            }
12662            return true;
12663        }
12664
12665        @Override
12666        protected ActivityIntentInfo[] newArray(int size) {
12667            return new ActivityIntentInfo[size];
12668        }
12669
12670        @Override
12671        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12672            if (!sUserManager.exists(userId)) return true;
12673            PackageParser.Package p = filter.activity.owner;
12674            if (p != null) {
12675                PackageSetting ps = (PackageSetting)p.mExtras;
12676                if (ps != null) {
12677                    // System apps are never considered stopped for purposes of
12678                    // filtering, because there may be no way for the user to
12679                    // actually re-launch them.
12680                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12681                            && ps.getStopped(userId);
12682                }
12683            }
12684            return false;
12685        }
12686
12687        @Override
12688        protected boolean isPackageForFilter(String packageName,
12689                PackageParser.ActivityIntentInfo info) {
12690            return packageName.equals(info.activity.owner.packageName);
12691        }
12692
12693        @Override
12694        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12695                int match, int userId) {
12696            if (!sUserManager.exists(userId)) return null;
12697            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12698                return null;
12699            }
12700            final PackageParser.Activity activity = info.activity;
12701            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12702            if (ps == null) {
12703                return null;
12704            }
12705            final PackageUserState userState = ps.readUserState(userId);
12706            ActivityInfo ai =
12707                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12708            if (ai == null) {
12709                return null;
12710            }
12711            final boolean matchExplicitlyVisibleOnly =
12712                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12713            final boolean matchVisibleToInstantApp =
12714                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12715            final boolean componentVisible =
12716                    matchVisibleToInstantApp
12717                    && info.isVisibleToInstantApp()
12718                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12719            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12720            // throw out filters that aren't visible to ephemeral apps
12721            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12722                return null;
12723            }
12724            // throw out instant app filters if we're not explicitly requesting them
12725            if (!matchInstantApp && userState.instantApp) {
12726                return null;
12727            }
12728            // throw out instant app filters if updates are available; will trigger
12729            // instant app resolution
12730            if (userState.instantApp && ps.isUpdateAvailable()) {
12731                return null;
12732            }
12733            final ResolveInfo res = new ResolveInfo();
12734            res.activityInfo = ai;
12735            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12736                res.filter = info;
12737            }
12738            if (info != null) {
12739                res.handleAllWebDataURI = info.handleAllWebDataURI();
12740            }
12741            res.priority = info.getPriority();
12742            res.preferredOrder = activity.owner.mPreferredOrder;
12743            //System.out.println("Result: " + res.activityInfo.className +
12744            //                   " = " + res.priority);
12745            res.match = match;
12746            res.isDefault = info.hasDefault;
12747            res.labelRes = info.labelRes;
12748            res.nonLocalizedLabel = info.nonLocalizedLabel;
12749            if (userNeedsBadging(userId)) {
12750                res.noResourceId = true;
12751            } else {
12752                res.icon = info.icon;
12753            }
12754            res.iconResourceId = info.icon;
12755            res.system = res.activityInfo.applicationInfo.isSystemApp();
12756            res.isInstantAppAvailable = userState.instantApp;
12757            return res;
12758        }
12759
12760        @Override
12761        protected void sortResults(List<ResolveInfo> results) {
12762            Collections.sort(results, mResolvePrioritySorter);
12763        }
12764
12765        @Override
12766        protected void dumpFilter(PrintWriter out, String prefix,
12767                PackageParser.ActivityIntentInfo filter) {
12768            out.print(prefix); out.print(
12769                    Integer.toHexString(System.identityHashCode(filter.activity)));
12770                    out.print(' ');
12771                    filter.activity.printComponentShortName(out);
12772                    out.print(" filter ");
12773                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12774        }
12775
12776        @Override
12777        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12778            return filter.activity;
12779        }
12780
12781        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12782            PackageParser.Activity activity = (PackageParser.Activity)label;
12783            out.print(prefix); out.print(
12784                    Integer.toHexString(System.identityHashCode(activity)));
12785                    out.print(' ');
12786                    activity.printComponentShortName(out);
12787            if (count > 1) {
12788                out.print(" ("); out.print(count); out.print(" filters)");
12789            }
12790            out.println();
12791        }
12792
12793        // Keys are String (activity class name), values are Activity.
12794        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12795                = new ArrayMap<ComponentName, PackageParser.Activity>();
12796        private int mFlags;
12797    }
12798
12799    private final class ServiceIntentResolver
12800            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12801        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12802                boolean defaultOnly, int userId) {
12803            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12804            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12805        }
12806
12807        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12808                int userId) {
12809            if (!sUserManager.exists(userId)) return null;
12810            mFlags = flags;
12811            return super.queryIntent(intent, resolvedType,
12812                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12813                    userId);
12814        }
12815
12816        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12817                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12818            if (!sUserManager.exists(userId)) return null;
12819            if (packageServices == null) {
12820                return null;
12821            }
12822            mFlags = flags;
12823            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12824            final int N = packageServices.size();
12825            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12826                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12827
12828            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12829            for (int i = 0; i < N; ++i) {
12830                intentFilters = packageServices.get(i).intents;
12831                if (intentFilters != null && intentFilters.size() > 0) {
12832                    PackageParser.ServiceIntentInfo[] array =
12833                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12834                    intentFilters.toArray(array);
12835                    listCut.add(array);
12836                }
12837            }
12838            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12839        }
12840
12841        public final void addService(PackageParser.Service s) {
12842            mServices.put(s.getComponentName(), s);
12843            if (DEBUG_SHOW_INFO) {
12844                Log.v(TAG, "  "
12845                        + (s.info.nonLocalizedLabel != null
12846                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12847                Log.v(TAG, "    Class=" + s.info.name);
12848            }
12849            final int NI = s.intents.size();
12850            int j;
12851            for (j=0; j<NI; j++) {
12852                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12853                if (DEBUG_SHOW_INFO) {
12854                    Log.v(TAG, "    IntentFilter:");
12855                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12856                }
12857                if (!intent.debugCheck()) {
12858                    Log.w(TAG, "==> For Service " + s.info.name);
12859                }
12860                addFilter(intent);
12861            }
12862        }
12863
12864        public final void removeService(PackageParser.Service s) {
12865            mServices.remove(s.getComponentName());
12866            if (DEBUG_SHOW_INFO) {
12867                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12868                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12869                Log.v(TAG, "    Class=" + s.info.name);
12870            }
12871            final int NI = s.intents.size();
12872            int j;
12873            for (j=0; j<NI; j++) {
12874                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12875                if (DEBUG_SHOW_INFO) {
12876                    Log.v(TAG, "    IntentFilter:");
12877                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12878                }
12879                removeFilter(intent);
12880            }
12881        }
12882
12883        @Override
12884        protected boolean allowFilterResult(
12885                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12886            ServiceInfo filterSi = filter.service.info;
12887            for (int i=dest.size()-1; i>=0; i--) {
12888                ServiceInfo destAi = dest.get(i).serviceInfo;
12889                if (destAi.name == filterSi.name
12890                        && destAi.packageName == filterSi.packageName) {
12891                    return false;
12892                }
12893            }
12894            return true;
12895        }
12896
12897        @Override
12898        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12899            return new PackageParser.ServiceIntentInfo[size];
12900        }
12901
12902        @Override
12903        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12904            if (!sUserManager.exists(userId)) return true;
12905            PackageParser.Package p = filter.service.owner;
12906            if (p != null) {
12907                PackageSetting ps = (PackageSetting)p.mExtras;
12908                if (ps != null) {
12909                    // System apps are never considered stopped for purposes of
12910                    // filtering, because there may be no way for the user to
12911                    // actually re-launch them.
12912                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12913                            && ps.getStopped(userId);
12914                }
12915            }
12916            return false;
12917        }
12918
12919        @Override
12920        protected boolean isPackageForFilter(String packageName,
12921                PackageParser.ServiceIntentInfo info) {
12922            return packageName.equals(info.service.owner.packageName);
12923        }
12924
12925        @Override
12926        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12927                int match, int userId) {
12928            if (!sUserManager.exists(userId)) return null;
12929            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12930            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12931                return null;
12932            }
12933            final PackageParser.Service service = info.service;
12934            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12935            if (ps == null) {
12936                return null;
12937            }
12938            final PackageUserState userState = ps.readUserState(userId);
12939            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12940                    userState, userId);
12941            if (si == null) {
12942                return null;
12943            }
12944            final boolean matchVisibleToInstantApp =
12945                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12946            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12947            // throw out filters that aren't visible to ephemeral apps
12948            if (matchVisibleToInstantApp
12949                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12950                return null;
12951            }
12952            // throw out ephemeral filters if we're not explicitly requesting them
12953            if (!isInstantApp && userState.instantApp) {
12954                return null;
12955            }
12956            // throw out instant app filters if updates are available; will trigger
12957            // instant app resolution
12958            if (userState.instantApp && ps.isUpdateAvailable()) {
12959                return null;
12960            }
12961            final ResolveInfo res = new ResolveInfo();
12962            res.serviceInfo = si;
12963            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12964                res.filter = filter;
12965            }
12966            res.priority = info.getPriority();
12967            res.preferredOrder = service.owner.mPreferredOrder;
12968            res.match = match;
12969            res.isDefault = info.hasDefault;
12970            res.labelRes = info.labelRes;
12971            res.nonLocalizedLabel = info.nonLocalizedLabel;
12972            res.icon = info.icon;
12973            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12974            return res;
12975        }
12976
12977        @Override
12978        protected void sortResults(List<ResolveInfo> results) {
12979            Collections.sort(results, mResolvePrioritySorter);
12980        }
12981
12982        @Override
12983        protected void dumpFilter(PrintWriter out, String prefix,
12984                PackageParser.ServiceIntentInfo filter) {
12985            out.print(prefix); out.print(
12986                    Integer.toHexString(System.identityHashCode(filter.service)));
12987                    out.print(' ');
12988                    filter.service.printComponentShortName(out);
12989                    out.print(" filter ");
12990                    out.print(Integer.toHexString(System.identityHashCode(filter)));
12991                    if (filter.service.info.permission != null) {
12992                        out.print(" permission "); out.println(filter.service.info.permission);
12993                    } else {
12994                        out.println();
12995                    }
12996        }
12997
12998        @Override
12999        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13000            return filter.service;
13001        }
13002
13003        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13004            PackageParser.Service service = (PackageParser.Service)label;
13005            out.print(prefix); out.print(
13006                    Integer.toHexString(System.identityHashCode(service)));
13007                    out.print(' ');
13008                    service.printComponentShortName(out);
13009            if (count > 1) {
13010                out.print(" ("); out.print(count); out.print(" filters)");
13011            }
13012            out.println();
13013        }
13014
13015//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13016//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13017//            final List<ResolveInfo> retList = Lists.newArrayList();
13018//            while (i.hasNext()) {
13019//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13020//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13021//                    retList.add(resolveInfo);
13022//                }
13023//            }
13024//            return retList;
13025//        }
13026
13027        // Keys are String (activity class name), values are Activity.
13028        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13029                = new ArrayMap<ComponentName, PackageParser.Service>();
13030        private int mFlags;
13031    }
13032
13033    private final class ProviderIntentResolver
13034            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13035        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13036                boolean defaultOnly, int userId) {
13037            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13038            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13039        }
13040
13041        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13042                int userId) {
13043            if (!sUserManager.exists(userId))
13044                return null;
13045            mFlags = flags;
13046            return super.queryIntent(intent, resolvedType,
13047                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13048                    userId);
13049        }
13050
13051        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13052                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13053            if (!sUserManager.exists(userId))
13054                return null;
13055            if (packageProviders == null) {
13056                return null;
13057            }
13058            mFlags = flags;
13059            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13060            final int N = packageProviders.size();
13061            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13062                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13063
13064            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13065            for (int i = 0; i < N; ++i) {
13066                intentFilters = packageProviders.get(i).intents;
13067                if (intentFilters != null && intentFilters.size() > 0) {
13068                    PackageParser.ProviderIntentInfo[] array =
13069                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13070                    intentFilters.toArray(array);
13071                    listCut.add(array);
13072                }
13073            }
13074            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13075        }
13076
13077        public final void addProvider(PackageParser.Provider p) {
13078            if (mProviders.containsKey(p.getComponentName())) {
13079                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13080                return;
13081            }
13082
13083            mProviders.put(p.getComponentName(), p);
13084            if (DEBUG_SHOW_INFO) {
13085                Log.v(TAG, "  "
13086                        + (p.info.nonLocalizedLabel != null
13087                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13088                Log.v(TAG, "    Class=" + p.info.name);
13089            }
13090            final int NI = p.intents.size();
13091            int j;
13092            for (j = 0; j < NI; j++) {
13093                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13094                if (DEBUG_SHOW_INFO) {
13095                    Log.v(TAG, "    IntentFilter:");
13096                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13097                }
13098                if (!intent.debugCheck()) {
13099                    Log.w(TAG, "==> For Provider " + p.info.name);
13100                }
13101                addFilter(intent);
13102            }
13103        }
13104
13105        public final void removeProvider(PackageParser.Provider p) {
13106            mProviders.remove(p.getComponentName());
13107            if (DEBUG_SHOW_INFO) {
13108                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13109                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13110                Log.v(TAG, "    Class=" + p.info.name);
13111            }
13112            final int NI = p.intents.size();
13113            int j;
13114            for (j = 0; j < NI; j++) {
13115                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13116                if (DEBUG_SHOW_INFO) {
13117                    Log.v(TAG, "    IntentFilter:");
13118                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13119                }
13120                removeFilter(intent);
13121            }
13122        }
13123
13124        @Override
13125        protected boolean allowFilterResult(
13126                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13127            ProviderInfo filterPi = filter.provider.info;
13128            for (int i = dest.size() - 1; i >= 0; i--) {
13129                ProviderInfo destPi = dest.get(i).providerInfo;
13130                if (destPi.name == filterPi.name
13131                        && destPi.packageName == filterPi.packageName) {
13132                    return false;
13133                }
13134            }
13135            return true;
13136        }
13137
13138        @Override
13139        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13140            return new PackageParser.ProviderIntentInfo[size];
13141        }
13142
13143        @Override
13144        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13145            if (!sUserManager.exists(userId))
13146                return true;
13147            PackageParser.Package p = filter.provider.owner;
13148            if (p != null) {
13149                PackageSetting ps = (PackageSetting) p.mExtras;
13150                if (ps != null) {
13151                    // System apps are never considered stopped for purposes of
13152                    // filtering, because there may be no way for the user to
13153                    // actually re-launch them.
13154                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13155                            && ps.getStopped(userId);
13156                }
13157            }
13158            return false;
13159        }
13160
13161        @Override
13162        protected boolean isPackageForFilter(String packageName,
13163                PackageParser.ProviderIntentInfo info) {
13164            return packageName.equals(info.provider.owner.packageName);
13165        }
13166
13167        @Override
13168        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13169                int match, int userId) {
13170            if (!sUserManager.exists(userId))
13171                return null;
13172            final PackageParser.ProviderIntentInfo info = filter;
13173            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13174                return null;
13175            }
13176            final PackageParser.Provider provider = info.provider;
13177            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13178            if (ps == null) {
13179                return null;
13180            }
13181            final PackageUserState userState = ps.readUserState(userId);
13182            final boolean matchVisibleToInstantApp =
13183                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13184            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13185            // throw out filters that aren't visible to instant applications
13186            if (matchVisibleToInstantApp
13187                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13188                return null;
13189            }
13190            // throw out instant application filters if we're not explicitly requesting them
13191            if (!isInstantApp && userState.instantApp) {
13192                return null;
13193            }
13194            // throw out instant application filters if updates are available; will trigger
13195            // instant application resolution
13196            if (userState.instantApp && ps.isUpdateAvailable()) {
13197                return null;
13198            }
13199            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13200                    userState, userId);
13201            if (pi == null) {
13202                return null;
13203            }
13204            final ResolveInfo res = new ResolveInfo();
13205            res.providerInfo = pi;
13206            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13207                res.filter = filter;
13208            }
13209            res.priority = info.getPriority();
13210            res.preferredOrder = provider.owner.mPreferredOrder;
13211            res.match = match;
13212            res.isDefault = info.hasDefault;
13213            res.labelRes = info.labelRes;
13214            res.nonLocalizedLabel = info.nonLocalizedLabel;
13215            res.icon = info.icon;
13216            res.system = res.providerInfo.applicationInfo.isSystemApp();
13217            return res;
13218        }
13219
13220        @Override
13221        protected void sortResults(List<ResolveInfo> results) {
13222            Collections.sort(results, mResolvePrioritySorter);
13223        }
13224
13225        @Override
13226        protected void dumpFilter(PrintWriter out, String prefix,
13227                PackageParser.ProviderIntentInfo filter) {
13228            out.print(prefix);
13229            out.print(
13230                    Integer.toHexString(System.identityHashCode(filter.provider)));
13231            out.print(' ');
13232            filter.provider.printComponentShortName(out);
13233            out.print(" filter ");
13234            out.println(Integer.toHexString(System.identityHashCode(filter)));
13235        }
13236
13237        @Override
13238        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13239            return filter.provider;
13240        }
13241
13242        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13243            PackageParser.Provider provider = (PackageParser.Provider)label;
13244            out.print(prefix); out.print(
13245                    Integer.toHexString(System.identityHashCode(provider)));
13246                    out.print(' ');
13247                    provider.printComponentShortName(out);
13248            if (count > 1) {
13249                out.print(" ("); out.print(count); out.print(" filters)");
13250            }
13251            out.println();
13252        }
13253
13254        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13255                = new ArrayMap<ComponentName, PackageParser.Provider>();
13256        private int mFlags;
13257    }
13258
13259    static final class InstantAppIntentResolver
13260            extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
13261            AuxiliaryResolveInfo.AuxiliaryFilter> {
13262        /**
13263         * The result that has the highest defined order. Ordering applies on a
13264         * per-package basis. Mapping is from package name to Pair of order and
13265         * EphemeralResolveInfo.
13266         * <p>
13267         * NOTE: This is implemented as a field variable for convenience and efficiency.
13268         * By having a field variable, we're able to track filter ordering as soon as
13269         * a non-zero order is defined. Otherwise, multiple loops across the result set
13270         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13271         * this needs to be contained entirely within {@link #filterResults}.
13272         */
13273        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13274
13275        @Override
13276        protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
13277            return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
13278        }
13279
13280        @Override
13281        protected boolean isPackageForFilter(String packageName,
13282                AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
13283            return true;
13284        }
13285
13286        @Override
13287        protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
13288                AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
13289            if (!sUserManager.exists(userId)) {
13290                return null;
13291            }
13292            final String packageName = responseObj.resolveInfo.getPackageName();
13293            final Integer order = responseObj.getOrder();
13294            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13295                    mOrderResult.get(packageName);
13296            // ordering is enabled and this item's order isn't high enough
13297            if (lastOrderResult != null && lastOrderResult.first >= order) {
13298                return null;
13299            }
13300            final InstantAppResolveInfo res = responseObj.resolveInfo;
13301            if (order > 0) {
13302                // non-zero order, enable ordering
13303                mOrderResult.put(packageName, new Pair<>(order, res));
13304            }
13305            return responseObj;
13306        }
13307
13308        @Override
13309        protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
13310            // only do work if ordering is enabled [most of the time it won't be]
13311            if (mOrderResult.size() == 0) {
13312                return;
13313            }
13314            int resultSize = results.size();
13315            for (int i = 0; i < resultSize; i++) {
13316                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13317                final String packageName = info.getPackageName();
13318                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13319                if (savedInfo == null) {
13320                    // package doesn't having ordering
13321                    continue;
13322                }
13323                if (savedInfo.second == info) {
13324                    // circled back to the highest ordered item; remove from order list
13325                    mOrderResult.remove(packageName);
13326                    if (mOrderResult.size() == 0) {
13327                        // no more ordered items
13328                        break;
13329                    }
13330                    continue;
13331                }
13332                // item has a worse order, remove it from the result list
13333                results.remove(i);
13334                resultSize--;
13335                i--;
13336            }
13337        }
13338    }
13339
13340    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13341            new Comparator<ResolveInfo>() {
13342        public int compare(ResolveInfo r1, ResolveInfo r2) {
13343            int v1 = r1.priority;
13344            int v2 = r2.priority;
13345            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13346            if (v1 != v2) {
13347                return (v1 > v2) ? -1 : 1;
13348            }
13349            v1 = r1.preferredOrder;
13350            v2 = r2.preferredOrder;
13351            if (v1 != v2) {
13352                return (v1 > v2) ? -1 : 1;
13353            }
13354            if (r1.isDefault != r2.isDefault) {
13355                return r1.isDefault ? -1 : 1;
13356            }
13357            v1 = r1.match;
13358            v2 = r2.match;
13359            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13360            if (v1 != v2) {
13361                return (v1 > v2) ? -1 : 1;
13362            }
13363            if (r1.system != r2.system) {
13364                return r1.system ? -1 : 1;
13365            }
13366            if (r1.activityInfo != null) {
13367                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13368            }
13369            if (r1.serviceInfo != null) {
13370                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13371            }
13372            if (r1.providerInfo != null) {
13373                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13374            }
13375            return 0;
13376        }
13377    };
13378
13379    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13380            new Comparator<ProviderInfo>() {
13381        public int compare(ProviderInfo p1, ProviderInfo p2) {
13382            final int v1 = p1.initOrder;
13383            final int v2 = p2.initOrder;
13384            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13385        }
13386    };
13387
13388    @Override
13389    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13390            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13391            final int[] userIds, int[] instantUserIds) {
13392        mHandler.post(new Runnable() {
13393            @Override
13394            public void run() {
13395                try {
13396                    final IActivityManager am = ActivityManager.getService();
13397                    if (am == null) return;
13398                    final int[] resolvedUserIds;
13399                    if (userIds == null) {
13400                        resolvedUserIds = am.getRunningUserIds();
13401                    } else {
13402                        resolvedUserIds = userIds;
13403                    }
13404                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13405                            resolvedUserIds, false);
13406                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13407                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13408                                instantUserIds, true);
13409                    }
13410                } catch (RemoteException ex) {
13411                }
13412            }
13413        });
13414    }
13415
13416    @Override
13417    public void notifyPackageAdded(String packageName) {
13418        final PackageListObserver[] observers;
13419        synchronized (mPackages) {
13420            if (mPackageListObservers.size() == 0) {
13421                return;
13422            }
13423            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13424        }
13425        for (int i = observers.length - 1; i >= 0; --i) {
13426            observers[i].onPackageAdded(packageName);
13427        }
13428    }
13429
13430    @Override
13431    public void notifyPackageRemoved(String packageName) {
13432        final PackageListObserver[] observers;
13433        synchronized (mPackages) {
13434            if (mPackageListObservers.size() == 0) {
13435                return;
13436            }
13437            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13438        }
13439        for (int i = observers.length - 1; i >= 0; --i) {
13440            observers[i].onPackageRemoved(packageName);
13441        }
13442    }
13443
13444    /**
13445     * Sends a broadcast for the given action.
13446     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13447     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13448     * the system and applications allowed to see instant applications to receive package
13449     * lifecycle events for instant applications.
13450     */
13451    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13452            int flags, String targetPkg, IIntentReceiver finishedReceiver,
13453            int[] userIds, boolean isInstantApp)
13454                    throws RemoteException {
13455        for (int id : userIds) {
13456            final Intent intent = new Intent(action,
13457                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13458            final String[] requiredPermissions =
13459                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13460            if (extras != null) {
13461                intent.putExtras(extras);
13462            }
13463            if (targetPkg != null) {
13464                intent.setPackage(targetPkg);
13465            }
13466            // Modify the UID when posting to other users
13467            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13468            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13469                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13470                intent.putExtra(Intent.EXTRA_UID, uid);
13471            }
13472            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13473            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13474            if (DEBUG_BROADCASTS) {
13475                RuntimeException here = new RuntimeException("here");
13476                here.fillInStackTrace();
13477                Slog.d(TAG, "Sending to user " + id + ": "
13478                        + intent.toShortString(false, true, false, false)
13479                        + " " + intent.getExtras(), here);
13480            }
13481            am.broadcastIntent(null, intent, null, finishedReceiver,
13482                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13483                    null, finishedReceiver != null, false, id);
13484        }
13485    }
13486
13487    /**
13488     * Check if the external storage media is available. This is true if there
13489     * is a mounted external storage medium or if the external storage is
13490     * emulated.
13491     */
13492    private boolean isExternalMediaAvailable() {
13493        return mMediaMounted || Environment.isExternalStorageEmulated();
13494    }
13495
13496    @Override
13497    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13498        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13499            return null;
13500        }
13501        if (!isExternalMediaAvailable()) {
13502                // If the external storage is no longer mounted at this point,
13503                // the caller may not have been able to delete all of this
13504                // packages files and can not delete any more.  Bail.
13505            return null;
13506        }
13507        synchronized (mPackages) {
13508            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13509            if (lastPackage != null) {
13510                pkgs.remove(lastPackage);
13511            }
13512            if (pkgs.size() > 0) {
13513                return pkgs.get(0);
13514            }
13515        }
13516        return null;
13517    }
13518
13519    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13520        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13521                userId, andCode ? 1 : 0, packageName);
13522        if (mSystemReady) {
13523            msg.sendToTarget();
13524        } else {
13525            if (mPostSystemReadyMessages == null) {
13526                mPostSystemReadyMessages = new ArrayList<>();
13527            }
13528            mPostSystemReadyMessages.add(msg);
13529        }
13530    }
13531
13532    void startCleaningPackages() {
13533        // reader
13534        if (!isExternalMediaAvailable()) {
13535            return;
13536        }
13537        synchronized (mPackages) {
13538            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13539                return;
13540            }
13541        }
13542        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13543        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13544        IActivityManager am = ActivityManager.getService();
13545        if (am != null) {
13546            int dcsUid = -1;
13547            synchronized (mPackages) {
13548                if (!mDefaultContainerWhitelisted) {
13549                    mDefaultContainerWhitelisted = true;
13550                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13551                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13552                }
13553            }
13554            try {
13555                if (dcsUid > 0) {
13556                    am.backgroundWhitelistUid(dcsUid);
13557                }
13558                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13559                        UserHandle.USER_SYSTEM);
13560            } catch (RemoteException e) {
13561            }
13562        }
13563    }
13564
13565    /**
13566     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13567     * it is acting on behalf on an enterprise or the user).
13568     *
13569     * Note that the ordering of the conditionals in this method is important. The checks we perform
13570     * are as follows, in this order:
13571     *
13572     * 1) If the install is being performed by a system app, we can trust the app to have set the
13573     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13574     *    what it is.
13575     * 2) If the install is being performed by a device or profile owner app, the install reason
13576     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13577     *    set the install reason correctly. If the app targets an older SDK version where install
13578     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13579     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13580     * 3) In all other cases, the install is being performed by a regular app that is neither part
13581     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13582     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13583     *    set to enterprise policy and if so, change it to unknown instead.
13584     */
13585    private int fixUpInstallReason(String installerPackageName, int installerUid,
13586            int installReason) {
13587        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13588                == PERMISSION_GRANTED) {
13589            // If the install is being performed by a system app, we trust that app to have set the
13590            // install reason correctly.
13591            return installReason;
13592        }
13593
13594        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13595            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13596        if (dpm != null) {
13597            ComponentName owner = null;
13598            try {
13599                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13600                if (owner == null) {
13601                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13602                }
13603            } catch (RemoteException e) {
13604            }
13605            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13606                // If the install is being performed by a device or profile owner, the install
13607                // reason should be enterprise policy.
13608                return PackageManager.INSTALL_REASON_POLICY;
13609            }
13610        }
13611
13612        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13613            // If the install is being performed by a regular app (i.e. neither system app nor
13614            // device or profile owner), we have no reason to believe that the app is acting on
13615            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13616            // change it to unknown instead.
13617            return PackageManager.INSTALL_REASON_UNKNOWN;
13618        }
13619
13620        // If the install is being performed by a regular app and the install reason was set to any
13621        // value but enterprise policy, leave the install reason unchanged.
13622        return installReason;
13623    }
13624
13625    void installStage(String packageName, File stagedDir,
13626            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13627            String installerPackageName, int installerUid, UserHandle user,
13628            PackageParser.SigningDetails signingDetails) {
13629        if (DEBUG_INSTANT) {
13630            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13631                Slog.d(TAG, "Ephemeral install of " + packageName);
13632            }
13633        }
13634        final VerificationInfo verificationInfo = new VerificationInfo(
13635                sessionParams.originatingUri, sessionParams.referrerUri,
13636                sessionParams.originatingUid, installerUid);
13637
13638        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13639
13640        final Message msg = mHandler.obtainMessage(INIT_COPY);
13641        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13642                sessionParams.installReason);
13643        final InstallParams params = new InstallParams(origin, null, observer,
13644                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13645                verificationInfo, user, sessionParams.abiOverride,
13646                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13647        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13648        msg.obj = params;
13649
13650        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13651                System.identityHashCode(msg.obj));
13652        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13653                System.identityHashCode(msg.obj));
13654
13655        mHandler.sendMessage(msg);
13656    }
13657
13658    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13659            int userId) {
13660        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13661        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13662        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13663        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13664        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13665                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13666
13667        // Send a session commit broadcast
13668        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13669        info.installReason = pkgSetting.getInstallReason(userId);
13670        info.appPackageName = packageName;
13671        sendSessionCommitBroadcast(info, userId);
13672    }
13673
13674    @Override
13675    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13676            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13677        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13678            return;
13679        }
13680        Bundle extras = new Bundle(1);
13681        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13682        final int uid = UserHandle.getUid(
13683                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13684        extras.putInt(Intent.EXTRA_UID, uid);
13685
13686        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13687                packageName, extras, 0, null, null, userIds, instantUserIds);
13688        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13689            mHandler.post(() -> {
13690                        for (int userId : userIds) {
13691                            sendBootCompletedBroadcastToSystemApp(
13692                                    packageName, includeStopped, userId);
13693                        }
13694                    }
13695            );
13696        }
13697    }
13698
13699    /**
13700     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13701     * automatically without needing an explicit launch.
13702     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13703     */
13704    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13705            int userId) {
13706        // If user is not running, the app didn't miss any broadcast
13707        if (!mUserManagerInternal.isUserRunning(userId)) {
13708            return;
13709        }
13710        final IActivityManager am = ActivityManager.getService();
13711        try {
13712            // Deliver LOCKED_BOOT_COMPLETED first
13713            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13714                    .setPackage(packageName);
13715            if (includeStopped) {
13716                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13717            }
13718            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13719            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13720                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13721
13722            // Deliver BOOT_COMPLETED only if user is unlocked
13723            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13724                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13725                if (includeStopped) {
13726                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13727                }
13728                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13729                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13730            }
13731        } catch (RemoteException e) {
13732            throw e.rethrowFromSystemServer();
13733        }
13734    }
13735
13736    @Override
13737    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13738            int userId) {
13739        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13740        PackageSetting pkgSetting;
13741        final int callingUid = Binder.getCallingUid();
13742        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13743                true /* requireFullPermission */, true /* checkShell */,
13744                "setApplicationHiddenSetting for user " + userId);
13745
13746        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13747            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13748            return false;
13749        }
13750
13751        long callingId = Binder.clearCallingIdentity();
13752        try {
13753            boolean sendAdded = false;
13754            boolean sendRemoved = false;
13755            // writer
13756            synchronized (mPackages) {
13757                pkgSetting = mSettings.mPackages.get(packageName);
13758                if (pkgSetting == null) {
13759                    return false;
13760                }
13761                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13762                    return false;
13763                }
13764                // Do not allow "android" is being disabled
13765                if ("android".equals(packageName)) {
13766                    Slog.w(TAG, "Cannot hide package: android");
13767                    return false;
13768                }
13769                // Cannot hide static shared libs as they are considered
13770                // a part of the using app (emulating static linking). Also
13771                // static libs are installed always on internal storage.
13772                PackageParser.Package pkg = mPackages.get(packageName);
13773                if (pkg != null && pkg.staticSharedLibName != null) {
13774                    Slog.w(TAG, "Cannot hide package: " + packageName
13775                            + " providing static shared library: "
13776                            + pkg.staticSharedLibName);
13777                    return false;
13778                }
13779                // Only allow protected packages to hide themselves.
13780                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13781                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13782                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13783                    return false;
13784                }
13785
13786                if (pkgSetting.getHidden(userId) != hidden) {
13787                    pkgSetting.setHidden(hidden, userId);
13788                    mSettings.writePackageRestrictionsLPr(userId);
13789                    if (hidden) {
13790                        sendRemoved = true;
13791                    } else {
13792                        sendAdded = true;
13793                    }
13794                }
13795            }
13796            if (sendAdded) {
13797                sendPackageAddedForUser(packageName, pkgSetting, userId);
13798                return true;
13799            }
13800            if (sendRemoved) {
13801                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13802                        "hiding pkg");
13803                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13804                return true;
13805            }
13806        } finally {
13807            Binder.restoreCallingIdentity(callingId);
13808        }
13809        return false;
13810    }
13811
13812    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13813            int userId) {
13814        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13815        info.removedPackage = packageName;
13816        info.installerPackageName = pkgSetting.installerPackageName;
13817        info.removedUsers = new int[] {userId};
13818        info.broadcastUsers = new int[] {userId};
13819        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13820        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13821    }
13822
13823    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13824        if (pkgList.length > 0) {
13825            Bundle extras = new Bundle(1);
13826            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13827
13828            sendPackageBroadcast(
13829                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13830                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13831                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13832                    new int[] {userId}, null);
13833        }
13834    }
13835
13836    /**
13837     * Returns true if application is not found or there was an error. Otherwise it returns
13838     * the hidden state of the package for the given user.
13839     */
13840    @Override
13841    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13842        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13843        final int callingUid = Binder.getCallingUid();
13844        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13845                true /* requireFullPermission */, false /* checkShell */,
13846                "getApplicationHidden for user " + userId);
13847        PackageSetting ps;
13848        long callingId = Binder.clearCallingIdentity();
13849        try {
13850            // writer
13851            synchronized (mPackages) {
13852                ps = mSettings.mPackages.get(packageName);
13853                if (ps == null) {
13854                    return true;
13855                }
13856                if (filterAppAccessLPr(ps, callingUid, userId)) {
13857                    return true;
13858                }
13859                return ps.getHidden(userId);
13860            }
13861        } finally {
13862            Binder.restoreCallingIdentity(callingId);
13863        }
13864    }
13865
13866    /**
13867     * @hide
13868     */
13869    @Override
13870    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13871            int installReason) {
13872        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13873                null);
13874        PackageSetting pkgSetting;
13875        final int callingUid = Binder.getCallingUid();
13876        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13877                true /* requireFullPermission */, true /* checkShell */,
13878                "installExistingPackage for user " + userId);
13879        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13880            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13881        }
13882
13883        long callingId = Binder.clearCallingIdentity();
13884        try {
13885            boolean installed = false;
13886            final boolean instantApp =
13887                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13888            final boolean fullApp =
13889                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13890
13891            // writer
13892            synchronized (mPackages) {
13893                pkgSetting = mSettings.mPackages.get(packageName);
13894                if (pkgSetting == null) {
13895                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13896                }
13897                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13898                    // only allow the existing package to be used if it's installed as a full
13899                    // application for at least one user
13900                    boolean installAllowed = false;
13901                    for (int checkUserId : sUserManager.getUserIds()) {
13902                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13903                        if (installAllowed) {
13904                            break;
13905                        }
13906                    }
13907                    if (!installAllowed) {
13908                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13909                    }
13910                }
13911                if (!pkgSetting.getInstalled(userId)) {
13912                    pkgSetting.setInstalled(true, userId);
13913                    pkgSetting.setHidden(false, userId);
13914                    pkgSetting.setInstallReason(installReason, userId);
13915                    mSettings.writePackageRestrictionsLPr(userId);
13916                    mSettings.writeKernelMappingLPr(pkgSetting);
13917                    installed = true;
13918                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13919                    // upgrade app from instant to full; we don't allow app downgrade
13920                    installed = true;
13921                }
13922                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13923            }
13924
13925            if (installed) {
13926                if (pkgSetting.pkg != null) {
13927                    synchronized (mInstallLock) {
13928                        // We don't need to freeze for a brand new install
13929                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13930                    }
13931                }
13932                sendPackageAddedForUser(packageName, pkgSetting, userId);
13933                synchronized (mPackages) {
13934                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13935                }
13936            }
13937        } finally {
13938            Binder.restoreCallingIdentity(callingId);
13939        }
13940
13941        return PackageManager.INSTALL_SUCCEEDED;
13942    }
13943
13944    static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13945            boolean instantApp, boolean fullApp) {
13946        // no state specified; do nothing
13947        if (!instantApp && !fullApp) {
13948            return;
13949        }
13950        if (userId != UserHandle.USER_ALL) {
13951            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13952                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13953            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13954                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13955            }
13956        } else {
13957            for (int currentUserId : sUserManager.getUserIds()) {
13958                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13959                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13960                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13961                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13962                }
13963            }
13964        }
13965    }
13966
13967    boolean isUserRestricted(int userId, String restrictionKey) {
13968        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13969        if (restrictions.getBoolean(restrictionKey, false)) {
13970            Log.w(TAG, "User is restricted: " + restrictionKey);
13971            return true;
13972        }
13973        return false;
13974    }
13975
13976    @Override
13977    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13978            int userId) {
13979        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13980        final int callingUid = Binder.getCallingUid();
13981        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13982                true /* requireFullPermission */, true /* checkShell */,
13983                "setPackagesSuspended for user " + userId);
13984
13985        if (ArrayUtils.isEmpty(packageNames)) {
13986            return packageNames;
13987        }
13988
13989        // List of package names for whom the suspended state has changed.
13990        List<String> changedPackages = new ArrayList<>(packageNames.length);
13991        // List of package names for whom the suspended state is not set as requested in this
13992        // method.
13993        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13994        long callingId = Binder.clearCallingIdentity();
13995        try {
13996            for (int i = 0; i < packageNames.length; i++) {
13997                String packageName = packageNames[i];
13998                boolean changed = false;
13999                final int appId;
14000                synchronized (mPackages) {
14001                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14002                    if (pkgSetting == null
14003                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14004                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14005                                + "\". Skipping suspending/un-suspending.");
14006                        unactionedPackages.add(packageName);
14007                        continue;
14008                    }
14009                    appId = pkgSetting.appId;
14010                    if (pkgSetting.getSuspended(userId) != suspended) {
14011                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14012                            unactionedPackages.add(packageName);
14013                            continue;
14014                        }
14015                        pkgSetting.setSuspended(suspended, userId);
14016                        mSettings.writePackageRestrictionsLPr(userId);
14017                        changed = true;
14018                        changedPackages.add(packageName);
14019                    }
14020                }
14021
14022                if (changed && suspended) {
14023                    killApplication(packageName, UserHandle.getUid(userId, appId),
14024                            "suspending package");
14025                }
14026            }
14027        } finally {
14028            Binder.restoreCallingIdentity(callingId);
14029        }
14030
14031        if (!changedPackages.isEmpty()) {
14032            sendPackagesSuspendedForUser(changedPackages.toArray(
14033                    new String[changedPackages.size()]), userId, suspended);
14034        }
14035
14036        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14037    }
14038
14039    @Override
14040    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14041        final int callingUid = Binder.getCallingUid();
14042        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14043                true /* requireFullPermission */, false /* checkShell */,
14044                "isPackageSuspendedForUser for user " + userId);
14045        synchronized (mPackages) {
14046            final PackageSetting ps = mSettings.mPackages.get(packageName);
14047            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14048                throw new IllegalArgumentException("Unknown target package: " + packageName);
14049            }
14050            return ps.getSuspended(userId);
14051        }
14052    }
14053
14054    @GuardedBy("mPackages")
14055    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14056        if (isPackageDeviceAdmin(packageName, userId)) {
14057            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14058                    + "\": has an active device admin");
14059            return false;
14060        }
14061
14062        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14063        if (packageName.equals(activeLauncherPackageName)) {
14064            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14065                    + "\": contains the active launcher");
14066            return false;
14067        }
14068
14069        if (packageName.equals(mRequiredInstallerPackage)) {
14070            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14071                    + "\": required for package installation");
14072            return false;
14073        }
14074
14075        if (packageName.equals(mRequiredUninstallerPackage)) {
14076            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14077                    + "\": required for package uninstallation");
14078            return false;
14079        }
14080
14081        if (packageName.equals(mRequiredVerifierPackage)) {
14082            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14083                    + "\": required for package verification");
14084            return false;
14085        }
14086
14087        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14088            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14089                    + "\": is the default dialer");
14090            return false;
14091        }
14092
14093        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14094            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14095                    + "\": protected package");
14096            return false;
14097        }
14098
14099        // Cannot suspend static shared libs as they are considered
14100        // a part of the using app (emulating static linking). Also
14101        // static libs are installed always on internal storage.
14102        PackageParser.Package pkg = mPackages.get(packageName);
14103        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14104            Slog.w(TAG, "Cannot suspend package: " + packageName
14105                    + " providing static shared library: "
14106                    + pkg.staticSharedLibName);
14107            return false;
14108        }
14109
14110        return true;
14111    }
14112
14113    private String getActiveLauncherPackageName(int userId) {
14114        Intent intent = new Intent(Intent.ACTION_MAIN);
14115        intent.addCategory(Intent.CATEGORY_HOME);
14116        ResolveInfo resolveInfo = resolveIntent(
14117                intent,
14118                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14119                PackageManager.MATCH_DEFAULT_ONLY,
14120                userId);
14121
14122        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14123    }
14124
14125    private String getDefaultDialerPackageName(int userId) {
14126        synchronized (mPackages) {
14127            return mSettings.getDefaultDialerPackageNameLPw(userId);
14128        }
14129    }
14130
14131    @Override
14132    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14133        mContext.enforceCallingOrSelfPermission(
14134                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14135                "Only package verification agents can verify applications");
14136
14137        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14138        final PackageVerificationResponse response = new PackageVerificationResponse(
14139                verificationCode, Binder.getCallingUid());
14140        msg.arg1 = id;
14141        msg.obj = response;
14142        mHandler.sendMessage(msg);
14143    }
14144
14145    @Override
14146    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14147            long millisecondsToDelay) {
14148        mContext.enforceCallingOrSelfPermission(
14149                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14150                "Only package verification agents can extend verification timeouts");
14151
14152        final PackageVerificationState state = mPendingVerification.get(id);
14153        final PackageVerificationResponse response = new PackageVerificationResponse(
14154                verificationCodeAtTimeout, Binder.getCallingUid());
14155
14156        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14157            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14158        }
14159        if (millisecondsToDelay < 0) {
14160            millisecondsToDelay = 0;
14161        }
14162        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14163                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14164            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14165        }
14166
14167        if ((state != null) && !state.timeoutExtended()) {
14168            state.extendTimeout();
14169
14170            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14171            msg.arg1 = id;
14172            msg.obj = response;
14173            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14174        }
14175    }
14176
14177    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14178            int verificationCode, UserHandle user) {
14179        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14180        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14181        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14182        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14183        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14184
14185        mContext.sendBroadcastAsUser(intent, user,
14186                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14187    }
14188
14189    private ComponentName matchComponentForVerifier(String packageName,
14190            List<ResolveInfo> receivers) {
14191        ActivityInfo targetReceiver = null;
14192
14193        final int NR = receivers.size();
14194        for (int i = 0; i < NR; i++) {
14195            final ResolveInfo info = receivers.get(i);
14196            if (info.activityInfo == null) {
14197                continue;
14198            }
14199
14200            if (packageName.equals(info.activityInfo.packageName)) {
14201                targetReceiver = info.activityInfo;
14202                break;
14203            }
14204        }
14205
14206        if (targetReceiver == null) {
14207            return null;
14208        }
14209
14210        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14211    }
14212
14213    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14214            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14215        if (pkgInfo.verifiers.length == 0) {
14216            return null;
14217        }
14218
14219        final int N = pkgInfo.verifiers.length;
14220        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14221        for (int i = 0; i < N; i++) {
14222            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14223
14224            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14225                    receivers);
14226            if (comp == null) {
14227                continue;
14228            }
14229
14230            final int verifierUid = getUidForVerifier(verifierInfo);
14231            if (verifierUid == -1) {
14232                continue;
14233            }
14234
14235            if (DEBUG_VERIFY) {
14236                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14237                        + " with the correct signature");
14238            }
14239            sufficientVerifiers.add(comp);
14240            verificationState.addSufficientVerifier(verifierUid);
14241        }
14242
14243        return sufficientVerifiers;
14244    }
14245
14246    private int getUidForVerifier(VerifierInfo verifierInfo) {
14247        synchronized (mPackages) {
14248            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14249            if (pkg == null) {
14250                return -1;
14251            } else if (pkg.mSigningDetails.signatures.length != 1) {
14252                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14253                        + " has more than one signature; ignoring");
14254                return -1;
14255            }
14256
14257            /*
14258             * If the public key of the package's signature does not match
14259             * our expected public key, then this is a different package and
14260             * we should skip.
14261             */
14262
14263            final byte[] expectedPublicKey;
14264            try {
14265                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14266                final PublicKey publicKey = verifierSig.getPublicKey();
14267                expectedPublicKey = publicKey.getEncoded();
14268            } catch (CertificateException e) {
14269                return -1;
14270            }
14271
14272            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14273
14274            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14275                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14276                        + " does not have the expected public key; ignoring");
14277                return -1;
14278            }
14279
14280            return pkg.applicationInfo.uid;
14281        }
14282    }
14283
14284    @Override
14285    public void finishPackageInstall(int token, boolean didLaunch) {
14286        enforceSystemOrRoot("Only the system is allowed to finish installs");
14287
14288        if (DEBUG_INSTALL) {
14289            Slog.v(TAG, "BM finishing package install for " + token);
14290        }
14291        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14292
14293        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14294        mHandler.sendMessage(msg);
14295    }
14296
14297    /**
14298     * Get the verification agent timeout.  Used for both the APK verifier and the
14299     * intent filter verifier.
14300     *
14301     * @return verification timeout in milliseconds
14302     */
14303    private long getVerificationTimeout() {
14304        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14305                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14306                DEFAULT_VERIFICATION_TIMEOUT);
14307    }
14308
14309    /**
14310     * Get the default verification agent response code.
14311     *
14312     * @return default verification response code
14313     */
14314    private int getDefaultVerificationResponse(UserHandle user) {
14315        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14316            return PackageManager.VERIFICATION_REJECT;
14317        }
14318        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14319                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14320                DEFAULT_VERIFICATION_RESPONSE);
14321    }
14322
14323    /**
14324     * Check whether or not package verification has been enabled.
14325     *
14326     * @return true if verification should be performed
14327     */
14328    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14329        if (!DEFAULT_VERIFY_ENABLE) {
14330            return false;
14331        }
14332
14333        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14334
14335        // Check if installing from ADB
14336        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14337            // Do not run verification in a test harness environment
14338            if (ActivityManager.isRunningInTestHarness()) {
14339                return false;
14340            }
14341            if (ensureVerifyAppsEnabled) {
14342                return true;
14343            }
14344            // Check if the developer does not want package verification for ADB installs
14345            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14346                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14347                return false;
14348            }
14349        } else {
14350            // only when not installed from ADB, skip verification for instant apps when
14351            // the installer and verifier are the same.
14352            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14353                if (mInstantAppInstallerActivity != null
14354                        && mInstantAppInstallerActivity.packageName.equals(
14355                                mRequiredVerifierPackage)) {
14356                    try {
14357                        mContext.getSystemService(AppOpsManager.class)
14358                                .checkPackage(installerUid, mRequiredVerifierPackage);
14359                        if (DEBUG_VERIFY) {
14360                            Slog.i(TAG, "disable verification for instant app");
14361                        }
14362                        return false;
14363                    } catch (SecurityException ignore) { }
14364                }
14365            }
14366        }
14367
14368        if (ensureVerifyAppsEnabled) {
14369            return true;
14370        }
14371
14372        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14373                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14374    }
14375
14376    @Override
14377    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14378            throws RemoteException {
14379        mContext.enforceCallingOrSelfPermission(
14380                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14381                "Only intentfilter verification agents can verify applications");
14382
14383        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14384        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14385                Binder.getCallingUid(), verificationCode, failedDomains);
14386        msg.arg1 = id;
14387        msg.obj = response;
14388        mHandler.sendMessage(msg);
14389    }
14390
14391    @Override
14392    public int getIntentVerificationStatus(String packageName, int userId) {
14393        final int callingUid = Binder.getCallingUid();
14394        if (UserHandle.getUserId(callingUid) != userId) {
14395            mContext.enforceCallingOrSelfPermission(
14396                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14397                    "getIntentVerificationStatus" + userId);
14398        }
14399        if (getInstantAppPackageName(callingUid) != null) {
14400            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14401        }
14402        synchronized (mPackages) {
14403            final PackageSetting ps = mSettings.mPackages.get(packageName);
14404            if (ps == null
14405                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14406                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14407            }
14408            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14409        }
14410    }
14411
14412    @Override
14413    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14414        mContext.enforceCallingOrSelfPermission(
14415                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14416
14417        boolean result = false;
14418        synchronized (mPackages) {
14419            final PackageSetting ps = mSettings.mPackages.get(packageName);
14420            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14421                return false;
14422            }
14423            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14424        }
14425        if (result) {
14426            scheduleWritePackageRestrictionsLocked(userId);
14427        }
14428        return result;
14429    }
14430
14431    @Override
14432    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14433            String packageName) {
14434        final int callingUid = Binder.getCallingUid();
14435        if (getInstantAppPackageName(callingUid) != null) {
14436            return ParceledListSlice.emptyList();
14437        }
14438        synchronized (mPackages) {
14439            final PackageSetting ps = mSettings.mPackages.get(packageName);
14440            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14441                return ParceledListSlice.emptyList();
14442            }
14443            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14444        }
14445    }
14446
14447    @Override
14448    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14449        if (TextUtils.isEmpty(packageName)) {
14450            return ParceledListSlice.emptyList();
14451        }
14452        final int callingUid = Binder.getCallingUid();
14453        final int callingUserId = UserHandle.getUserId(callingUid);
14454        synchronized (mPackages) {
14455            PackageParser.Package pkg = mPackages.get(packageName);
14456            if (pkg == null || pkg.activities == null) {
14457                return ParceledListSlice.emptyList();
14458            }
14459            if (pkg.mExtras == null) {
14460                return ParceledListSlice.emptyList();
14461            }
14462            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14463            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14464                return ParceledListSlice.emptyList();
14465            }
14466            final int count = pkg.activities.size();
14467            ArrayList<IntentFilter> result = new ArrayList<>();
14468            for (int n=0; n<count; n++) {
14469                PackageParser.Activity activity = pkg.activities.get(n);
14470                if (activity.intents != null && activity.intents.size() > 0) {
14471                    result.addAll(activity.intents);
14472                }
14473            }
14474            return new ParceledListSlice<>(result);
14475        }
14476    }
14477
14478    @Override
14479    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14480        mContext.enforceCallingOrSelfPermission(
14481                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14482        if (UserHandle.getCallingUserId() != userId) {
14483            mContext.enforceCallingOrSelfPermission(
14484                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14485        }
14486
14487        synchronized (mPackages) {
14488            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14489            if (packageName != null) {
14490                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14491                        packageName, userId);
14492            }
14493            return result;
14494        }
14495    }
14496
14497    @Override
14498    public String getDefaultBrowserPackageName(int userId) {
14499        if (UserHandle.getCallingUserId() != userId) {
14500            mContext.enforceCallingOrSelfPermission(
14501                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14502        }
14503        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14504            return null;
14505        }
14506        synchronized (mPackages) {
14507            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14508        }
14509    }
14510
14511    /**
14512     * Get the "allow unknown sources" setting.
14513     *
14514     * @return the current "allow unknown sources" setting
14515     */
14516    private int getUnknownSourcesSettings() {
14517        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14518                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14519                -1);
14520    }
14521
14522    @Override
14523    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14524        final int callingUid = Binder.getCallingUid();
14525        if (getInstantAppPackageName(callingUid) != null) {
14526            return;
14527        }
14528        // writer
14529        synchronized (mPackages) {
14530            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14531            if (targetPackageSetting == null
14532                    || filterAppAccessLPr(
14533                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14534                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14535            }
14536
14537            PackageSetting installerPackageSetting;
14538            if (installerPackageName != null) {
14539                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14540                if (installerPackageSetting == null) {
14541                    throw new IllegalArgumentException("Unknown installer package: "
14542                            + installerPackageName);
14543                }
14544            } else {
14545                installerPackageSetting = null;
14546            }
14547
14548            Signature[] callerSignature;
14549            Object obj = mSettings.getUserIdLPr(callingUid);
14550            if (obj != null) {
14551                if (obj instanceof SharedUserSetting) {
14552                    callerSignature =
14553                            ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14554                } else if (obj instanceof PackageSetting) {
14555                    callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14556                } else {
14557                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14558                }
14559            } else {
14560                throw new SecurityException("Unknown calling UID: " + callingUid);
14561            }
14562
14563            // Verify: can't set installerPackageName to a package that is
14564            // not signed with the same cert as the caller.
14565            if (installerPackageSetting != null) {
14566                if (compareSignatures(callerSignature,
14567                        installerPackageSetting.signatures.mSigningDetails.signatures)
14568                        != PackageManager.SIGNATURE_MATCH) {
14569                    throw new SecurityException(
14570                            "Caller does not have same cert as new installer package "
14571                            + installerPackageName);
14572                }
14573            }
14574
14575            // Verify: if target already has an installer package, it must
14576            // be signed with the same cert as the caller.
14577            if (targetPackageSetting.installerPackageName != null) {
14578                PackageSetting setting = mSettings.mPackages.get(
14579                        targetPackageSetting.installerPackageName);
14580                // If the currently set package isn't valid, then it's always
14581                // okay to change it.
14582                if (setting != null) {
14583                    if (compareSignatures(callerSignature,
14584                            setting.signatures.mSigningDetails.signatures)
14585                            != PackageManager.SIGNATURE_MATCH) {
14586                        throw new SecurityException(
14587                                "Caller does not have same cert as old installer package "
14588                                + targetPackageSetting.installerPackageName);
14589                    }
14590                }
14591            }
14592
14593            // Okay!
14594            targetPackageSetting.installerPackageName = installerPackageName;
14595            if (installerPackageName != null) {
14596                mSettings.mInstallerPackages.add(installerPackageName);
14597            }
14598            scheduleWriteSettingsLocked();
14599        }
14600    }
14601
14602    @Override
14603    public void setApplicationCategoryHint(String packageName, int categoryHint,
14604            String callerPackageName) {
14605        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14606            throw new SecurityException("Instant applications don't have access to this method");
14607        }
14608        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14609                callerPackageName);
14610        synchronized (mPackages) {
14611            PackageSetting ps = mSettings.mPackages.get(packageName);
14612            if (ps == null) {
14613                throw new IllegalArgumentException("Unknown target package " + packageName);
14614            }
14615            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14616                throw new IllegalArgumentException("Unknown target package " + packageName);
14617            }
14618            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14619                throw new IllegalArgumentException("Calling package " + callerPackageName
14620                        + " is not installer for " + packageName);
14621            }
14622
14623            if (ps.categoryHint != categoryHint) {
14624                ps.categoryHint = categoryHint;
14625                scheduleWriteSettingsLocked();
14626            }
14627        }
14628    }
14629
14630    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14631        // Queue up an async operation since the package installation may take a little while.
14632        mHandler.post(new Runnable() {
14633            public void run() {
14634                mHandler.removeCallbacks(this);
14635                 // Result object to be returned
14636                PackageInstalledInfo res = new PackageInstalledInfo();
14637                res.setReturnCode(currentStatus);
14638                res.uid = -1;
14639                res.pkg = null;
14640                res.removedInfo = null;
14641                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14642                    args.doPreInstall(res.returnCode);
14643                    synchronized (mInstallLock) {
14644                        installPackageTracedLI(args, res);
14645                    }
14646                    args.doPostInstall(res.returnCode, res.uid);
14647                }
14648
14649                // A restore should be performed at this point if (a) the install
14650                // succeeded, (b) the operation is not an update, and (c) the new
14651                // package has not opted out of backup participation.
14652                final boolean update = res.removedInfo != null
14653                        && res.removedInfo.removedPackage != null;
14654                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14655                boolean doRestore = !update
14656                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14657
14658                // Set up the post-install work request bookkeeping.  This will be used
14659                // and cleaned up by the post-install event handling regardless of whether
14660                // there's a restore pass performed.  Token values are >= 1.
14661                int token;
14662                if (mNextInstallToken < 0) mNextInstallToken = 1;
14663                token = mNextInstallToken++;
14664
14665                PostInstallData data = new PostInstallData(args, res);
14666                mRunningInstalls.put(token, data);
14667                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14668
14669                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14670                    // Pass responsibility to the Backup Manager.  It will perform a
14671                    // restore if appropriate, then pass responsibility back to the
14672                    // Package Manager to run the post-install observer callbacks
14673                    // and broadcasts.
14674                    IBackupManager bm = IBackupManager.Stub.asInterface(
14675                            ServiceManager.getService(Context.BACKUP_SERVICE));
14676                    if (bm != null) {
14677                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14678                                + " to BM for possible restore");
14679                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14680                        try {
14681                            // TODO: http://b/22388012
14682                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14683                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14684                            } else {
14685                                doRestore = false;
14686                            }
14687                        } catch (RemoteException e) {
14688                            // can't happen; the backup manager is local
14689                        } catch (Exception e) {
14690                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14691                            doRestore = false;
14692                        }
14693                    } else {
14694                        Slog.e(TAG, "Backup Manager not found!");
14695                        doRestore = false;
14696                    }
14697                }
14698
14699                if (!doRestore) {
14700                    // No restore possible, or the Backup Manager was mysteriously not
14701                    // available -- just fire the post-install work request directly.
14702                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14703
14704                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14705
14706                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14707                    mHandler.sendMessage(msg);
14708                }
14709            }
14710        });
14711    }
14712
14713    /**
14714     * Callback from PackageSettings whenever an app is first transitioned out of the
14715     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14716     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14717     * here whether the app is the target of an ongoing install, and only send the
14718     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14719     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14720     * handling.
14721     */
14722    void notifyFirstLaunch(final String packageName, final String installerPackage,
14723            final int userId) {
14724        // Serialize this with the rest of the install-process message chain.  In the
14725        // restore-at-install case, this Runnable will necessarily run before the
14726        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14727        // are coherent.  In the non-restore case, the app has already completed install
14728        // and been launched through some other means, so it is not in a problematic
14729        // state for observers to see the FIRST_LAUNCH signal.
14730        mHandler.post(new Runnable() {
14731            @Override
14732            public void run() {
14733                for (int i = 0; i < mRunningInstalls.size(); i++) {
14734                    final PostInstallData data = mRunningInstalls.valueAt(i);
14735                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14736                        continue;
14737                    }
14738                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14739                        // right package; but is it for the right user?
14740                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14741                            if (userId == data.res.newUsers[uIndex]) {
14742                                if (DEBUG_BACKUP) {
14743                                    Slog.i(TAG, "Package " + packageName
14744                                            + " being restored so deferring FIRST_LAUNCH");
14745                                }
14746                                return;
14747                            }
14748                        }
14749                    }
14750                }
14751                // didn't find it, so not being restored
14752                if (DEBUG_BACKUP) {
14753                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14754                }
14755                final boolean isInstantApp = isInstantApp(packageName, userId);
14756                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14757                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14758                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14759            }
14760        });
14761    }
14762
14763    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14764            int[] userIds, int[] instantUserIds) {
14765        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14766                installerPkg, null, userIds, instantUserIds);
14767    }
14768
14769    private abstract class HandlerParams {
14770        private static final int MAX_RETRIES = 4;
14771
14772        /**
14773         * Number of times startCopy() has been attempted and had a non-fatal
14774         * error.
14775         */
14776        private int mRetries = 0;
14777
14778        /** User handle for the user requesting the information or installation. */
14779        private final UserHandle mUser;
14780        String traceMethod;
14781        int traceCookie;
14782
14783        HandlerParams(UserHandle user) {
14784            mUser = user;
14785        }
14786
14787        UserHandle getUser() {
14788            return mUser;
14789        }
14790
14791        HandlerParams setTraceMethod(String traceMethod) {
14792            this.traceMethod = traceMethod;
14793            return this;
14794        }
14795
14796        HandlerParams setTraceCookie(int traceCookie) {
14797            this.traceCookie = traceCookie;
14798            return this;
14799        }
14800
14801        final boolean startCopy() {
14802            boolean res;
14803            try {
14804                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14805
14806                if (++mRetries > MAX_RETRIES) {
14807                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14808                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14809                    handleServiceError();
14810                    return false;
14811                } else {
14812                    handleStartCopy();
14813                    res = true;
14814                }
14815            } catch (RemoteException e) {
14816                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14817                mHandler.sendEmptyMessage(MCS_RECONNECT);
14818                res = false;
14819            }
14820            handleReturnCode();
14821            return res;
14822        }
14823
14824        final void serviceError() {
14825            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14826            handleServiceError();
14827            handleReturnCode();
14828        }
14829
14830        abstract void handleStartCopy() throws RemoteException;
14831        abstract void handleServiceError();
14832        abstract void handleReturnCode();
14833    }
14834
14835    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14836        for (File path : paths) {
14837            try {
14838                mcs.clearDirectory(path.getAbsolutePath());
14839            } catch (RemoteException e) {
14840            }
14841        }
14842    }
14843
14844    static class OriginInfo {
14845        /**
14846         * Location where install is coming from, before it has been
14847         * copied/renamed into place. This could be a single monolithic APK
14848         * file, or a cluster directory. This location may be untrusted.
14849         */
14850        final File file;
14851
14852        /**
14853         * Flag indicating that {@link #file} or {@link #cid} has already been
14854         * staged, meaning downstream users don't need to defensively copy the
14855         * contents.
14856         */
14857        final boolean staged;
14858
14859        /**
14860         * Flag indicating that {@link #file} or {@link #cid} is an already
14861         * installed app that is being moved.
14862         */
14863        final boolean existing;
14864
14865        final String resolvedPath;
14866        final File resolvedFile;
14867
14868        static OriginInfo fromNothing() {
14869            return new OriginInfo(null, false, false);
14870        }
14871
14872        static OriginInfo fromUntrustedFile(File file) {
14873            return new OriginInfo(file, false, false);
14874        }
14875
14876        static OriginInfo fromExistingFile(File file) {
14877            return new OriginInfo(file, false, true);
14878        }
14879
14880        static OriginInfo fromStagedFile(File file) {
14881            return new OriginInfo(file, true, false);
14882        }
14883
14884        private OriginInfo(File file, boolean staged, boolean existing) {
14885            this.file = file;
14886            this.staged = staged;
14887            this.existing = existing;
14888
14889            if (file != null) {
14890                resolvedPath = file.getAbsolutePath();
14891                resolvedFile = file;
14892            } else {
14893                resolvedPath = null;
14894                resolvedFile = null;
14895            }
14896        }
14897    }
14898
14899    static class MoveInfo {
14900        final int moveId;
14901        final String fromUuid;
14902        final String toUuid;
14903        final String packageName;
14904        final String dataAppName;
14905        final int appId;
14906        final String seinfo;
14907        final int targetSdkVersion;
14908
14909        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14910                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14911            this.moveId = moveId;
14912            this.fromUuid = fromUuid;
14913            this.toUuid = toUuid;
14914            this.packageName = packageName;
14915            this.dataAppName = dataAppName;
14916            this.appId = appId;
14917            this.seinfo = seinfo;
14918            this.targetSdkVersion = targetSdkVersion;
14919        }
14920    }
14921
14922    static class VerificationInfo {
14923        /** A constant used to indicate that a uid value is not present. */
14924        public static final int NO_UID = -1;
14925
14926        /** URI referencing where the package was downloaded from. */
14927        final Uri originatingUri;
14928
14929        /** HTTP referrer URI associated with the originatingURI. */
14930        final Uri referrer;
14931
14932        /** UID of the application that the install request originated from. */
14933        final int originatingUid;
14934
14935        /** UID of application requesting the install */
14936        final int installerUid;
14937
14938        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14939            this.originatingUri = originatingUri;
14940            this.referrer = referrer;
14941            this.originatingUid = originatingUid;
14942            this.installerUid = installerUid;
14943        }
14944    }
14945
14946    class InstallParams extends HandlerParams {
14947        final OriginInfo origin;
14948        final MoveInfo move;
14949        final IPackageInstallObserver2 observer;
14950        int installFlags;
14951        final String installerPackageName;
14952        final String volumeUuid;
14953        private InstallArgs mArgs;
14954        private int mRet;
14955        final String packageAbiOverride;
14956        final String[] grantedRuntimePermissions;
14957        final VerificationInfo verificationInfo;
14958        final PackageParser.SigningDetails signingDetails;
14959        final int installReason;
14960
14961        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14962                int installFlags, String installerPackageName, String volumeUuid,
14963                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14964                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
14965            super(user);
14966            this.origin = origin;
14967            this.move = move;
14968            this.observer = observer;
14969            this.installFlags = installFlags;
14970            this.installerPackageName = installerPackageName;
14971            this.volumeUuid = volumeUuid;
14972            this.verificationInfo = verificationInfo;
14973            this.packageAbiOverride = packageAbiOverride;
14974            this.grantedRuntimePermissions = grantedPermissions;
14975            this.signingDetails = signingDetails;
14976            this.installReason = installReason;
14977        }
14978
14979        @Override
14980        public String toString() {
14981            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14982                    + " file=" + origin.file + "}";
14983        }
14984
14985        private int installLocationPolicy(PackageInfoLite pkgLite) {
14986            String packageName = pkgLite.packageName;
14987            int installLocation = pkgLite.installLocation;
14988            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14989            // reader
14990            synchronized (mPackages) {
14991                // Currently installed package which the new package is attempting to replace or
14992                // null if no such package is installed.
14993                PackageParser.Package installedPkg = mPackages.get(packageName);
14994                // Package which currently owns the data which the new package will own if installed.
14995                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14996                // will be null whereas dataOwnerPkg will contain information about the package
14997                // which was uninstalled while keeping its data.
14998                PackageParser.Package dataOwnerPkg = installedPkg;
14999                if (dataOwnerPkg  == null) {
15000                    PackageSetting ps = mSettings.mPackages.get(packageName);
15001                    if (ps != null) {
15002                        dataOwnerPkg = ps.pkg;
15003                    }
15004                }
15005
15006                if (dataOwnerPkg != null) {
15007                    // If installed, the package will get access to data left on the device by its
15008                    // predecessor. As a security measure, this is permited only if this is not a
15009                    // version downgrade or if the predecessor package is marked as debuggable and
15010                    // a downgrade is explicitly requested.
15011                    //
15012                    // On debuggable platform builds, downgrades are permitted even for
15013                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15014                    // not offer security guarantees and thus it's OK to disable some security
15015                    // mechanisms to make debugging/testing easier on those builds. However, even on
15016                    // debuggable builds downgrades of packages are permitted only if requested via
15017                    // installFlags. This is because we aim to keep the behavior of debuggable
15018                    // platform builds as close as possible to the behavior of non-debuggable
15019                    // platform builds.
15020                    final boolean downgradeRequested =
15021                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15022                    final boolean packageDebuggable =
15023                                (dataOwnerPkg.applicationInfo.flags
15024                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15025                    final boolean downgradePermitted =
15026                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15027                    if (!downgradePermitted) {
15028                        try {
15029                            checkDowngrade(dataOwnerPkg, pkgLite);
15030                        } catch (PackageManagerException e) {
15031                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15032                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15033                        }
15034                    }
15035                }
15036
15037                if (installedPkg != null) {
15038                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15039                        // Check for updated system application.
15040                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15041                            if (onSd) {
15042                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15043                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15044                            }
15045                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15046                        } else {
15047                            if (onSd) {
15048                                // Install flag overrides everything.
15049                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15050                            }
15051                            // If current upgrade specifies particular preference
15052                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15053                                // Application explicitly specified internal.
15054                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15055                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15056                                // App explictly prefers external. Let policy decide
15057                            } else {
15058                                // Prefer previous location
15059                                if (isExternal(installedPkg)) {
15060                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15061                                }
15062                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15063                            }
15064                        }
15065                    } else {
15066                        // Invalid install. Return error code
15067                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15068                    }
15069                }
15070            }
15071            // All the special cases have been taken care of.
15072            // Return result based on recommended install location.
15073            if (onSd) {
15074                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15075            }
15076            return pkgLite.recommendedInstallLocation;
15077        }
15078
15079        /*
15080         * Invoke remote method to get package information and install
15081         * location values. Override install location based on default
15082         * policy if needed and then create install arguments based
15083         * on the install location.
15084         */
15085        public void handleStartCopy() throws RemoteException {
15086            int ret = PackageManager.INSTALL_SUCCEEDED;
15087
15088            // If we're already staged, we've firmly committed to an install location
15089            if (origin.staged) {
15090                if (origin.file != null) {
15091                    installFlags |= PackageManager.INSTALL_INTERNAL;
15092                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15093                } else {
15094                    throw new IllegalStateException("Invalid stage location");
15095                }
15096            }
15097
15098            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15099            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15100            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15101            PackageInfoLite pkgLite = null;
15102
15103            if (onInt && onSd) {
15104                // Check if both bits are set.
15105                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15106                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15107            } else if (onSd && ephemeral) {
15108                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15109                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15110            } else {
15111                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15112                        packageAbiOverride);
15113
15114                if (DEBUG_INSTANT && ephemeral) {
15115                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15116                }
15117
15118                /*
15119                 * If we have too little free space, try to free cache
15120                 * before giving up.
15121                 */
15122                if (!origin.staged && pkgLite.recommendedInstallLocation
15123                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15124                    // TODO: focus freeing disk space on the target device
15125                    final StorageManager storage = StorageManager.from(mContext);
15126                    final long lowThreshold = storage.getStorageLowBytes(
15127                            Environment.getDataDirectory());
15128
15129                    final long sizeBytes = mContainerService.calculateInstalledSize(
15130                            origin.resolvedPath, packageAbiOverride);
15131
15132                    try {
15133                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15134                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15135                                installFlags, packageAbiOverride);
15136                    } catch (InstallerException e) {
15137                        Slog.w(TAG, "Failed to free cache", e);
15138                    }
15139
15140                    /*
15141                     * The cache free must have deleted the file we
15142                     * downloaded to install.
15143                     *
15144                     * TODO: fix the "freeCache" call to not delete
15145                     *       the file we care about.
15146                     */
15147                    if (pkgLite.recommendedInstallLocation
15148                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15149                        pkgLite.recommendedInstallLocation
15150                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15151                    }
15152                }
15153            }
15154
15155            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15156                int loc = pkgLite.recommendedInstallLocation;
15157                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15158                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15159                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15160                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15161                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15162                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15163                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15164                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15165                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15166                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15167                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15168                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15169                } else {
15170                    // Override with defaults if needed.
15171                    loc = installLocationPolicy(pkgLite);
15172                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15173                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15174                    } else if (!onSd && !onInt) {
15175                        // Override install location with flags
15176                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15177                            // Set the flag to install on external media.
15178                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15179                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15180                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15181                            if (DEBUG_INSTANT) {
15182                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15183                            }
15184                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15185                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15186                                    |PackageManager.INSTALL_INTERNAL);
15187                        } else {
15188                            // Make sure the flag for installing on external
15189                            // media is unset
15190                            installFlags |= PackageManager.INSTALL_INTERNAL;
15191                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15192                        }
15193                    }
15194                }
15195            }
15196
15197            final InstallArgs args = createInstallArgs(this);
15198            mArgs = args;
15199
15200            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15201                // TODO: http://b/22976637
15202                // Apps installed for "all" users use the device owner to verify the app
15203                UserHandle verifierUser = getUser();
15204                if (verifierUser == UserHandle.ALL) {
15205                    verifierUser = UserHandle.SYSTEM;
15206                }
15207
15208                /*
15209                 * Determine if we have any installed package verifiers. If we
15210                 * do, then we'll defer to them to verify the packages.
15211                 */
15212                final int requiredUid = mRequiredVerifierPackage == null ? -1
15213                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15214                                verifierUser.getIdentifier());
15215                final int installerUid =
15216                        verificationInfo == null ? -1 : verificationInfo.installerUid;
15217                if (!origin.existing && requiredUid != -1
15218                        && isVerificationEnabled(
15219                                verifierUser.getIdentifier(), installFlags, installerUid)) {
15220                    final Intent verification = new Intent(
15221                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15222                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15223                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15224                            PACKAGE_MIME_TYPE);
15225                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15226
15227                    // Query all live verifiers based on current user state
15228                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15229                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15230                            false /*allowDynamicSplits*/);
15231
15232                    if (DEBUG_VERIFY) {
15233                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15234                                + verification.toString() + " with " + pkgLite.verifiers.length
15235                                + " optional verifiers");
15236                    }
15237
15238                    final int verificationId = mPendingVerificationToken++;
15239
15240                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15241
15242                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15243                            installerPackageName);
15244
15245                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15246                            installFlags);
15247
15248                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15249                            pkgLite.packageName);
15250
15251                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15252                            pkgLite.versionCode);
15253
15254                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15255                            pkgLite.getLongVersionCode());
15256
15257                    if (verificationInfo != null) {
15258                        if (verificationInfo.originatingUri != null) {
15259                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15260                                    verificationInfo.originatingUri);
15261                        }
15262                        if (verificationInfo.referrer != null) {
15263                            verification.putExtra(Intent.EXTRA_REFERRER,
15264                                    verificationInfo.referrer);
15265                        }
15266                        if (verificationInfo.originatingUid >= 0) {
15267                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15268                                    verificationInfo.originatingUid);
15269                        }
15270                        if (verificationInfo.installerUid >= 0) {
15271                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15272                                    verificationInfo.installerUid);
15273                        }
15274                    }
15275
15276                    final PackageVerificationState verificationState = new PackageVerificationState(
15277                            requiredUid, args);
15278
15279                    mPendingVerification.append(verificationId, verificationState);
15280
15281                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15282                            receivers, verificationState);
15283
15284                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15285                    final long idleDuration = getVerificationTimeout();
15286
15287                    /*
15288                     * If any sufficient verifiers were listed in the package
15289                     * manifest, attempt to ask them.
15290                     */
15291                    if (sufficientVerifiers != null) {
15292                        final int N = sufficientVerifiers.size();
15293                        if (N == 0) {
15294                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15295                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15296                        } else {
15297                            for (int i = 0; i < N; i++) {
15298                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15299                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15300                                        verifierComponent.getPackageName(), idleDuration,
15301                                        verifierUser.getIdentifier(), false, "package verifier");
15302
15303                                final Intent sufficientIntent = new Intent(verification);
15304                                sufficientIntent.setComponent(verifierComponent);
15305                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15306                            }
15307                        }
15308                    }
15309
15310                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15311                            mRequiredVerifierPackage, receivers);
15312                    if (ret == PackageManager.INSTALL_SUCCEEDED
15313                            && mRequiredVerifierPackage != null) {
15314                        Trace.asyncTraceBegin(
15315                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15316                        /*
15317                         * Send the intent to the required verification agent,
15318                         * but only start the verification timeout after the
15319                         * target BroadcastReceivers have run.
15320                         */
15321                        verification.setComponent(requiredVerifierComponent);
15322                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15323                                mRequiredVerifierPackage, idleDuration,
15324                                verifierUser.getIdentifier(), false, "package verifier");
15325                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15326                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15327                                new BroadcastReceiver() {
15328                                    @Override
15329                                    public void onReceive(Context context, Intent intent) {
15330                                        final Message msg = mHandler
15331                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15332                                        msg.arg1 = verificationId;
15333                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15334                                    }
15335                                }, null, 0, null, null);
15336
15337                        /*
15338                         * We don't want the copy to proceed until verification
15339                         * succeeds, so null out this field.
15340                         */
15341                        mArgs = null;
15342                    }
15343                } else {
15344                    /*
15345                     * No package verification is enabled, so immediately start
15346                     * the remote call to initiate copy using temporary file.
15347                     */
15348                    ret = args.copyApk(mContainerService, true);
15349                }
15350            }
15351
15352            mRet = ret;
15353        }
15354
15355        @Override
15356        void handleReturnCode() {
15357            // If mArgs is null, then MCS couldn't be reached. When it
15358            // reconnects, it will try again to install. At that point, this
15359            // will succeed.
15360            if (mArgs != null) {
15361                processPendingInstall(mArgs, mRet);
15362            }
15363        }
15364
15365        @Override
15366        void handleServiceError() {
15367            mArgs = createInstallArgs(this);
15368            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15369        }
15370    }
15371
15372    private InstallArgs createInstallArgs(InstallParams params) {
15373        if (params.move != null) {
15374            return new MoveInstallArgs(params);
15375        } else {
15376            return new FileInstallArgs(params);
15377        }
15378    }
15379
15380    /**
15381     * Create args that describe an existing installed package. Typically used
15382     * when cleaning up old installs, or used as a move source.
15383     */
15384    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15385            String resourcePath, String[] instructionSets) {
15386        return new FileInstallArgs(codePath, resourcePath, instructionSets);
15387    }
15388
15389    static abstract class InstallArgs {
15390        /** @see InstallParams#origin */
15391        final OriginInfo origin;
15392        /** @see InstallParams#move */
15393        final MoveInfo move;
15394
15395        final IPackageInstallObserver2 observer;
15396        // Always refers to PackageManager flags only
15397        final int installFlags;
15398        final String installerPackageName;
15399        final String volumeUuid;
15400        final UserHandle user;
15401        final String abiOverride;
15402        final String[] installGrantPermissions;
15403        /** If non-null, drop an async trace when the install completes */
15404        final String traceMethod;
15405        final int traceCookie;
15406        final PackageParser.SigningDetails signingDetails;
15407        final int installReason;
15408
15409        // The list of instruction sets supported by this app. This is currently
15410        // only used during the rmdex() phase to clean up resources. We can get rid of this
15411        // if we move dex files under the common app path.
15412        /* nullable */ String[] instructionSets;
15413
15414        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15415                int installFlags, String installerPackageName, String volumeUuid,
15416                UserHandle user, String[] instructionSets,
15417                String abiOverride, String[] installGrantPermissions,
15418                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15419                int installReason) {
15420            this.origin = origin;
15421            this.move = move;
15422            this.installFlags = installFlags;
15423            this.observer = observer;
15424            this.installerPackageName = installerPackageName;
15425            this.volumeUuid = volumeUuid;
15426            this.user = user;
15427            this.instructionSets = instructionSets;
15428            this.abiOverride = abiOverride;
15429            this.installGrantPermissions = installGrantPermissions;
15430            this.traceMethod = traceMethod;
15431            this.traceCookie = traceCookie;
15432            this.signingDetails = signingDetails;
15433            this.installReason = installReason;
15434        }
15435
15436        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15437        abstract int doPreInstall(int status);
15438
15439        /**
15440         * Rename package into final resting place. All paths on the given
15441         * scanned package should be updated to reflect the rename.
15442         */
15443        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15444        abstract int doPostInstall(int status, int uid);
15445
15446        /** @see PackageSettingBase#codePathString */
15447        abstract String getCodePath();
15448        /** @see PackageSettingBase#resourcePathString */
15449        abstract String getResourcePath();
15450
15451        // Need installer lock especially for dex file removal.
15452        abstract void cleanUpResourcesLI();
15453        abstract boolean doPostDeleteLI(boolean delete);
15454
15455        /**
15456         * Called before the source arguments are copied. This is used mostly
15457         * for MoveParams when it needs to read the source file to put it in the
15458         * destination.
15459         */
15460        int doPreCopy() {
15461            return PackageManager.INSTALL_SUCCEEDED;
15462        }
15463
15464        /**
15465         * Called after the source arguments are copied. This is used mostly for
15466         * MoveParams when it needs to read the source file to put it in the
15467         * destination.
15468         */
15469        int doPostCopy(int uid) {
15470            return PackageManager.INSTALL_SUCCEEDED;
15471        }
15472
15473        protected boolean isFwdLocked() {
15474            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15475        }
15476
15477        protected boolean isExternalAsec() {
15478            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15479        }
15480
15481        protected boolean isEphemeral() {
15482            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15483        }
15484
15485        UserHandle getUser() {
15486            return user;
15487        }
15488    }
15489
15490    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15491        if (!allCodePaths.isEmpty()) {
15492            if (instructionSets == null) {
15493                throw new IllegalStateException("instructionSet == null");
15494            }
15495            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15496            for (String codePath : allCodePaths) {
15497                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15498                    try {
15499                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15500                    } catch (InstallerException ignored) {
15501                    }
15502                }
15503            }
15504        }
15505    }
15506
15507    /**
15508     * Logic to handle installation of non-ASEC applications, including copying
15509     * and renaming logic.
15510     */
15511    class FileInstallArgs extends InstallArgs {
15512        private File codeFile;
15513        private File resourceFile;
15514
15515        // Example topology:
15516        // /data/app/com.example/base.apk
15517        // /data/app/com.example/split_foo.apk
15518        // /data/app/com.example/lib/arm/libfoo.so
15519        // /data/app/com.example/lib/arm64/libfoo.so
15520        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15521
15522        /** New install */
15523        FileInstallArgs(InstallParams params) {
15524            super(params.origin, params.move, params.observer, params.installFlags,
15525                    params.installerPackageName, params.volumeUuid,
15526                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15527                    params.grantedRuntimePermissions,
15528                    params.traceMethod, params.traceCookie, params.signingDetails,
15529                    params.installReason);
15530            if (isFwdLocked()) {
15531                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15532            }
15533        }
15534
15535        /** Existing install */
15536        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15537            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15538                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15539                    PackageManager.INSTALL_REASON_UNKNOWN);
15540            this.codeFile = (codePath != null) ? new File(codePath) : null;
15541            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15542        }
15543
15544        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15545            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15546            try {
15547                return doCopyApk(imcs, temp);
15548            } finally {
15549                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15550            }
15551        }
15552
15553        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15554            if (origin.staged) {
15555                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15556                codeFile = origin.file;
15557                resourceFile = origin.file;
15558                return PackageManager.INSTALL_SUCCEEDED;
15559            }
15560
15561            try {
15562                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15563                final File tempDir =
15564                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15565                codeFile = tempDir;
15566                resourceFile = tempDir;
15567            } catch (IOException e) {
15568                Slog.w(TAG, "Failed to create copy file: " + e);
15569                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15570            }
15571
15572            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15573                @Override
15574                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15575                    if (!FileUtils.isValidExtFilename(name)) {
15576                        throw new IllegalArgumentException("Invalid filename: " + name);
15577                    }
15578                    try {
15579                        final File file = new File(codeFile, name);
15580                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15581                                O_RDWR | O_CREAT, 0644);
15582                        Os.chmod(file.getAbsolutePath(), 0644);
15583                        return new ParcelFileDescriptor(fd);
15584                    } catch (ErrnoException e) {
15585                        throw new RemoteException("Failed to open: " + e.getMessage());
15586                    }
15587                }
15588            };
15589
15590            int ret = PackageManager.INSTALL_SUCCEEDED;
15591            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15592            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15593                Slog.e(TAG, "Failed to copy package");
15594                return ret;
15595            }
15596
15597            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15598            NativeLibraryHelper.Handle handle = null;
15599            try {
15600                handle = NativeLibraryHelper.Handle.create(codeFile);
15601                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15602                        abiOverride);
15603            } catch (IOException e) {
15604                Slog.e(TAG, "Copying native libraries failed", e);
15605                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15606            } finally {
15607                IoUtils.closeQuietly(handle);
15608            }
15609
15610            return ret;
15611        }
15612
15613        int doPreInstall(int status) {
15614            if (status != PackageManager.INSTALL_SUCCEEDED) {
15615                cleanUp();
15616            }
15617            return status;
15618        }
15619
15620        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15621            if (status != PackageManager.INSTALL_SUCCEEDED) {
15622                cleanUp();
15623                return false;
15624            }
15625
15626            final File targetDir = codeFile.getParentFile();
15627            final File beforeCodeFile = codeFile;
15628            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15629
15630            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15631            try {
15632                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15633            } catch (ErrnoException e) {
15634                Slog.w(TAG, "Failed to rename", e);
15635                return false;
15636            }
15637
15638            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15639                Slog.w(TAG, "Failed to restorecon");
15640                return false;
15641            }
15642
15643            // Reflect the rename internally
15644            codeFile = afterCodeFile;
15645            resourceFile = afterCodeFile;
15646
15647            // Reflect the rename in scanned details
15648            try {
15649                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15650            } catch (IOException e) {
15651                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15652                return false;
15653            }
15654            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15655                    afterCodeFile, pkg.baseCodePath));
15656            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15657                    afterCodeFile, pkg.splitCodePaths));
15658
15659            // Reflect the rename in app info
15660            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15661            pkg.setApplicationInfoCodePath(pkg.codePath);
15662            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15663            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15664            pkg.setApplicationInfoResourcePath(pkg.codePath);
15665            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15666            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15667
15668            return true;
15669        }
15670
15671        int doPostInstall(int status, int uid) {
15672            if (status != PackageManager.INSTALL_SUCCEEDED) {
15673                cleanUp();
15674            }
15675            return status;
15676        }
15677
15678        @Override
15679        String getCodePath() {
15680            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15681        }
15682
15683        @Override
15684        String getResourcePath() {
15685            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15686        }
15687
15688        private boolean cleanUp() {
15689            if (codeFile == null || !codeFile.exists()) {
15690                return false;
15691            }
15692
15693            removeCodePathLI(codeFile);
15694
15695            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15696                resourceFile.delete();
15697            }
15698
15699            return true;
15700        }
15701
15702        void cleanUpResourcesLI() {
15703            // Try enumerating all code paths before deleting
15704            List<String> allCodePaths = Collections.EMPTY_LIST;
15705            if (codeFile != null && codeFile.exists()) {
15706                try {
15707                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15708                    allCodePaths = pkg.getAllCodePaths();
15709                } catch (PackageParserException e) {
15710                    // Ignored; we tried our best
15711                }
15712            }
15713
15714            cleanUp();
15715            removeDexFiles(allCodePaths, instructionSets);
15716        }
15717
15718        boolean doPostDeleteLI(boolean delete) {
15719            // XXX err, shouldn't we respect the delete flag?
15720            cleanUpResourcesLI();
15721            return true;
15722        }
15723    }
15724
15725    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15726            PackageManagerException {
15727        if (copyRet < 0) {
15728            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15729                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15730                throw new PackageManagerException(copyRet, message);
15731            }
15732        }
15733    }
15734
15735    /**
15736     * Extract the StorageManagerService "container ID" from the full code path of an
15737     * .apk.
15738     */
15739    static String cidFromCodePath(String fullCodePath) {
15740        int eidx = fullCodePath.lastIndexOf("/");
15741        String subStr1 = fullCodePath.substring(0, eidx);
15742        int sidx = subStr1.lastIndexOf("/");
15743        return subStr1.substring(sidx+1, eidx);
15744    }
15745
15746    /**
15747     * Logic to handle movement of existing installed applications.
15748     */
15749    class MoveInstallArgs extends InstallArgs {
15750        private File codeFile;
15751        private File resourceFile;
15752
15753        /** New install */
15754        MoveInstallArgs(InstallParams params) {
15755            super(params.origin, params.move, params.observer, params.installFlags,
15756                    params.installerPackageName, params.volumeUuid,
15757                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15758                    params.grantedRuntimePermissions,
15759                    params.traceMethod, params.traceCookie, params.signingDetails,
15760                    params.installReason);
15761        }
15762
15763        int copyApk(IMediaContainerService imcs, boolean temp) {
15764            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15765                    + move.fromUuid + " to " + move.toUuid);
15766            synchronized (mInstaller) {
15767                try {
15768                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15769                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15770                } catch (InstallerException e) {
15771                    Slog.w(TAG, "Failed to move app", e);
15772                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15773                }
15774            }
15775
15776            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15777            resourceFile = codeFile;
15778            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15779
15780            return PackageManager.INSTALL_SUCCEEDED;
15781        }
15782
15783        int doPreInstall(int status) {
15784            if (status != PackageManager.INSTALL_SUCCEEDED) {
15785                cleanUp(move.toUuid);
15786            }
15787            return status;
15788        }
15789
15790        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15791            if (status != PackageManager.INSTALL_SUCCEEDED) {
15792                cleanUp(move.toUuid);
15793                return false;
15794            }
15795
15796            // Reflect the move in app info
15797            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15798            pkg.setApplicationInfoCodePath(pkg.codePath);
15799            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15800            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15801            pkg.setApplicationInfoResourcePath(pkg.codePath);
15802            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15803            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15804
15805            return true;
15806        }
15807
15808        int doPostInstall(int status, int uid) {
15809            if (status == PackageManager.INSTALL_SUCCEEDED) {
15810                cleanUp(move.fromUuid);
15811            } else {
15812                cleanUp(move.toUuid);
15813            }
15814            return status;
15815        }
15816
15817        @Override
15818        String getCodePath() {
15819            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15820        }
15821
15822        @Override
15823        String getResourcePath() {
15824            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15825        }
15826
15827        private boolean cleanUp(String volumeUuid) {
15828            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15829                    move.dataAppName);
15830            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15831            final int[] userIds = sUserManager.getUserIds();
15832            synchronized (mInstallLock) {
15833                // Clean up both app data and code
15834                // All package moves are frozen until finished
15835                for (int userId : userIds) {
15836                    try {
15837                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15838                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15839                    } catch (InstallerException e) {
15840                        Slog.w(TAG, String.valueOf(e));
15841                    }
15842                }
15843                removeCodePathLI(codeFile);
15844            }
15845            return true;
15846        }
15847
15848        void cleanUpResourcesLI() {
15849            throw new UnsupportedOperationException();
15850        }
15851
15852        boolean doPostDeleteLI(boolean delete) {
15853            throw new UnsupportedOperationException();
15854        }
15855    }
15856
15857    static String getAsecPackageName(String packageCid) {
15858        int idx = packageCid.lastIndexOf("-");
15859        if (idx == -1) {
15860            return packageCid;
15861        }
15862        return packageCid.substring(0, idx);
15863    }
15864
15865    // Utility method used to create code paths based on package name and available index.
15866    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15867        String idxStr = "";
15868        int idx = 1;
15869        // Fall back to default value of idx=1 if prefix is not
15870        // part of oldCodePath
15871        if (oldCodePath != null) {
15872            String subStr = oldCodePath;
15873            // Drop the suffix right away
15874            if (suffix != null && subStr.endsWith(suffix)) {
15875                subStr = subStr.substring(0, subStr.length() - suffix.length());
15876            }
15877            // If oldCodePath already contains prefix find out the
15878            // ending index to either increment or decrement.
15879            int sidx = subStr.lastIndexOf(prefix);
15880            if (sidx != -1) {
15881                subStr = subStr.substring(sidx + prefix.length());
15882                if (subStr != null) {
15883                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15884                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15885                    }
15886                    try {
15887                        idx = Integer.parseInt(subStr);
15888                        if (idx <= 1) {
15889                            idx++;
15890                        } else {
15891                            idx--;
15892                        }
15893                    } catch(NumberFormatException e) {
15894                    }
15895                }
15896            }
15897        }
15898        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15899        return prefix + idxStr;
15900    }
15901
15902    private File getNextCodePath(File targetDir, String packageName) {
15903        File result;
15904        SecureRandom random = new SecureRandom();
15905        byte[] bytes = new byte[16];
15906        do {
15907            random.nextBytes(bytes);
15908            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15909            result = new File(targetDir, packageName + "-" + suffix);
15910        } while (result.exists());
15911        return result;
15912    }
15913
15914    // Utility method that returns the relative package path with respect
15915    // to the installation directory. Like say for /data/data/com.test-1.apk
15916    // string com.test-1 is returned.
15917    static String deriveCodePathName(String codePath) {
15918        if (codePath == null) {
15919            return null;
15920        }
15921        final File codeFile = new File(codePath);
15922        final String name = codeFile.getName();
15923        if (codeFile.isDirectory()) {
15924            return name;
15925        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15926            final int lastDot = name.lastIndexOf('.');
15927            return name.substring(0, lastDot);
15928        } else {
15929            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15930            return null;
15931        }
15932    }
15933
15934    static class PackageInstalledInfo {
15935        String name;
15936        int uid;
15937        // The set of users that originally had this package installed.
15938        int[] origUsers;
15939        // The set of users that now have this package installed.
15940        int[] newUsers;
15941        PackageParser.Package pkg;
15942        int returnCode;
15943        String returnMsg;
15944        String installerPackageName;
15945        PackageRemovedInfo removedInfo;
15946        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15947
15948        public void setError(int code, String msg) {
15949            setReturnCode(code);
15950            setReturnMessage(msg);
15951            Slog.w(TAG, msg);
15952        }
15953
15954        public void setError(String msg, PackageParserException e) {
15955            setReturnCode(e.error);
15956            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15957            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15958            for (int i = 0; i < childCount; i++) {
15959                addedChildPackages.valueAt(i).setError(msg, e);
15960            }
15961            Slog.w(TAG, msg, e);
15962        }
15963
15964        public void setError(String msg, PackageManagerException e) {
15965            returnCode = e.error;
15966            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15967            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15968            for (int i = 0; i < childCount; i++) {
15969                addedChildPackages.valueAt(i).setError(msg, e);
15970            }
15971            Slog.w(TAG, msg, e);
15972        }
15973
15974        public void setReturnCode(int returnCode) {
15975            this.returnCode = returnCode;
15976            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15977            for (int i = 0; i < childCount; i++) {
15978                addedChildPackages.valueAt(i).returnCode = returnCode;
15979            }
15980        }
15981
15982        private void setReturnMessage(String returnMsg) {
15983            this.returnMsg = returnMsg;
15984            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15985            for (int i = 0; i < childCount; i++) {
15986                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15987            }
15988        }
15989
15990        // In some error cases we want to convey more info back to the observer
15991        String origPackage;
15992        String origPermission;
15993    }
15994
15995    /*
15996     * Install a non-existing package.
15997     */
15998    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15999            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16000            String volumeUuid, PackageInstalledInfo res, int installReason) {
16001        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16002
16003        // Remember this for later, in case we need to rollback this install
16004        String pkgName = pkg.packageName;
16005
16006        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16007
16008        synchronized(mPackages) {
16009            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16010            if (renamedPackage != null) {
16011                // A package with the same name is already installed, though
16012                // it has been renamed to an older name.  The package we
16013                // are trying to install should be installed as an update to
16014                // the existing one, but that has not been requested, so bail.
16015                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16016                        + " without first uninstalling package running as "
16017                        + renamedPackage);
16018                return;
16019            }
16020            if (mPackages.containsKey(pkgName)) {
16021                // Don't allow installation over an existing package with the same name.
16022                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16023                        + " without first uninstalling.");
16024                return;
16025            }
16026        }
16027
16028        try {
16029            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
16030                    System.currentTimeMillis(), user);
16031
16032            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16033
16034            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16035                prepareAppDataAfterInstallLIF(newPackage);
16036
16037            } else {
16038                // Remove package from internal structures, but keep around any
16039                // data that might have already existed
16040                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16041                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16042            }
16043        } catch (PackageManagerException e) {
16044            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16045        }
16046
16047        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16048    }
16049
16050    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16051        try (DigestInputStream digestStream =
16052                new DigestInputStream(new FileInputStream(file), digest)) {
16053            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16054        }
16055    }
16056
16057    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16058            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16059            PackageInstalledInfo res, int installReason) {
16060        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16061
16062        final PackageParser.Package oldPackage;
16063        final PackageSetting ps;
16064        final String pkgName = pkg.packageName;
16065        final int[] allUsers;
16066        final int[] installedUsers;
16067
16068        synchronized(mPackages) {
16069            oldPackage = mPackages.get(pkgName);
16070            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16071
16072            // don't allow upgrade to target a release SDK from a pre-release SDK
16073            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16074                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16075            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16076                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16077            if (oldTargetsPreRelease
16078                    && !newTargetsPreRelease
16079                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16080                Slog.w(TAG, "Can't install package targeting released sdk");
16081                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16082                return;
16083            }
16084
16085            ps = mSettings.mPackages.get(pkgName);
16086
16087            // verify signatures are valid
16088            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16089            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16090                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
16091                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16092                            "New package not signed by keys specified by upgrade-keysets: "
16093                                    + pkgName);
16094                    return;
16095                }
16096            } else {
16097
16098                // default to original signature matching
16099                if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
16100                        PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
16101                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16102                            "New package has a different signature: " + pkgName);
16103                    return;
16104                }
16105            }
16106
16107            // don't allow a system upgrade unless the upgrade hash matches
16108            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
16109                byte[] digestBytes = null;
16110                try {
16111                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16112                    updateDigest(digest, new File(pkg.baseCodePath));
16113                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16114                        for (String path : pkg.splitCodePaths) {
16115                            updateDigest(digest, new File(path));
16116                        }
16117                    }
16118                    digestBytes = digest.digest();
16119                } catch (NoSuchAlgorithmException | IOException e) {
16120                    res.setError(INSTALL_FAILED_INVALID_APK,
16121                            "Could not compute hash: " + pkgName);
16122                    return;
16123                }
16124                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16125                    res.setError(INSTALL_FAILED_INVALID_APK,
16126                            "New package fails restrict-update check: " + pkgName);
16127                    return;
16128                }
16129                // retain upgrade restriction
16130                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16131            }
16132
16133            // Check for shared user id changes
16134            String invalidPackageName =
16135                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16136            if (invalidPackageName != null) {
16137                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16138                        "Package " + invalidPackageName + " tried to change user "
16139                                + oldPackage.mSharedUserId);
16140                return;
16141            }
16142
16143            // check if the new package supports all of the abis which the old package supports
16144            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
16145            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
16146            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
16147                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16148                        "Update to package " + pkgName + " doesn't support multi arch");
16149                return;
16150            }
16151
16152            // In case of rollback, remember per-user/profile install state
16153            allUsers = sUserManager.getUserIds();
16154            installedUsers = ps.queryInstalledUsers(allUsers, true);
16155
16156            // don't allow an upgrade from full to ephemeral
16157            if (isInstantApp) {
16158                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16159                    for (int currentUser : allUsers) {
16160                        if (!ps.getInstantApp(currentUser)) {
16161                            // can't downgrade from full to instant
16162                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16163                                    + " for user: " + currentUser);
16164                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16165                            return;
16166                        }
16167                    }
16168                } else if (!ps.getInstantApp(user.getIdentifier())) {
16169                    // can't downgrade from full to instant
16170                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16171                            + " for user: " + user.getIdentifier());
16172                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16173                    return;
16174                }
16175            }
16176        }
16177
16178        // Update what is removed
16179        res.removedInfo = new PackageRemovedInfo(this);
16180        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16181        res.removedInfo.removedPackage = oldPackage.packageName;
16182        res.removedInfo.installerPackageName = ps.installerPackageName;
16183        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16184        res.removedInfo.isUpdate = true;
16185        res.removedInfo.origUsers = installedUsers;
16186        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16187        for (int i = 0; i < installedUsers.length; i++) {
16188            final int userId = installedUsers[i];
16189            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16190        }
16191
16192        final int childCount = (oldPackage.childPackages != null)
16193                ? oldPackage.childPackages.size() : 0;
16194        for (int i = 0; i < childCount; i++) {
16195            boolean childPackageUpdated = false;
16196            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16197            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16198            if (res.addedChildPackages != null) {
16199                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16200                if (childRes != null) {
16201                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16202                    childRes.removedInfo.removedPackage = childPkg.packageName;
16203                    if (childPs != null) {
16204                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16205                    }
16206                    childRes.removedInfo.isUpdate = true;
16207                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16208                    childPackageUpdated = true;
16209                }
16210            }
16211            if (!childPackageUpdated) {
16212                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16213                childRemovedRes.removedPackage = childPkg.packageName;
16214                if (childPs != null) {
16215                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16216                }
16217                childRemovedRes.isUpdate = false;
16218                childRemovedRes.dataRemoved = true;
16219                synchronized (mPackages) {
16220                    if (childPs != null) {
16221                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16222                    }
16223                }
16224                if (res.removedInfo.removedChildPackages == null) {
16225                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16226                }
16227                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16228            }
16229        }
16230
16231        boolean sysPkg = (isSystemApp(oldPackage));
16232        if (sysPkg) {
16233            // Set the system/privileged/oem/vendor/product flags as needed
16234            final boolean privileged =
16235                    (oldPackage.applicationInfo.privateFlags
16236                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16237            final boolean oem =
16238                    (oldPackage.applicationInfo.privateFlags
16239                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16240            final boolean vendor =
16241                    (oldPackage.applicationInfo.privateFlags
16242                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16243            final boolean product =
16244                    (oldPackage.applicationInfo.privateFlags
16245                            & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
16246            final @ParseFlags int systemParseFlags = parseFlags;
16247            final @ScanFlags int systemScanFlags = scanFlags
16248                    | SCAN_AS_SYSTEM
16249                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
16250                    | (oem ? SCAN_AS_OEM : 0)
16251                    | (vendor ? SCAN_AS_VENDOR : 0)
16252                    | (product ? SCAN_AS_PRODUCT : 0);
16253
16254            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
16255                    user, allUsers, installerPackageName, res, installReason);
16256        } else {
16257            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
16258                    user, allUsers, installerPackageName, res, installReason);
16259        }
16260    }
16261
16262    @Override
16263    public List<String> getPreviousCodePaths(String packageName) {
16264        final int callingUid = Binder.getCallingUid();
16265        final List<String> result = new ArrayList<>();
16266        if (getInstantAppPackageName(callingUid) != null) {
16267            return result;
16268        }
16269        final PackageSetting ps = mSettings.mPackages.get(packageName);
16270        if (ps != null
16271                && ps.oldCodePaths != null
16272                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
16273            result.addAll(ps.oldCodePaths);
16274        }
16275        return result;
16276    }
16277
16278    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16279            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16280            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
16281            String installerPackageName, PackageInstalledInfo res, int installReason) {
16282        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16283                + deletedPackage);
16284
16285        String pkgName = deletedPackage.packageName;
16286        boolean deletedPkg = true;
16287        boolean addedPkg = false;
16288        boolean updatedSettings = false;
16289        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16290        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16291                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16292
16293        final long origUpdateTime = (pkg.mExtras != null)
16294                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16295
16296        // First delete the existing package while retaining the data directory
16297        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16298                res.removedInfo, true, pkg)) {
16299            // If the existing package wasn't successfully deleted
16300            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16301            deletedPkg = false;
16302        } else {
16303            // Successfully deleted the old package; proceed with replace.
16304
16305            // If deleted package lived in a container, give users a chance to
16306            // relinquish resources before killing.
16307            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16308                if (DEBUG_INSTALL) {
16309                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16310                }
16311                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16312                final ArrayList<String> pkgList = new ArrayList<String>(1);
16313                pkgList.add(deletedPackage.applicationInfo.packageName);
16314                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16315            }
16316
16317            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16318                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16319
16320            try {
16321                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16322                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16323                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16324                        installReason);
16325
16326                // Update the in-memory copy of the previous code paths.
16327                PackageSetting ps = mSettings.mPackages.get(pkgName);
16328                if (!killApp) {
16329                    if (ps.oldCodePaths == null) {
16330                        ps.oldCodePaths = new ArraySet<>();
16331                    }
16332                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16333                    if (deletedPackage.splitCodePaths != null) {
16334                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16335                    }
16336                } else {
16337                    ps.oldCodePaths = null;
16338                }
16339                if (ps.childPackageNames != null) {
16340                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16341                        final String childPkgName = ps.childPackageNames.get(i);
16342                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16343                        childPs.oldCodePaths = ps.oldCodePaths;
16344                    }
16345                }
16346                prepareAppDataAfterInstallLIF(newPackage);
16347                addedPkg = true;
16348                mDexManager.notifyPackageUpdated(newPackage.packageName,
16349                        newPackage.baseCodePath, newPackage.splitCodePaths);
16350            } catch (PackageManagerException e) {
16351                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16352            }
16353        }
16354
16355        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16356            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16357
16358            // Revert all internal state mutations and added folders for the failed install
16359            if (addedPkg) {
16360                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16361                        res.removedInfo, true, null);
16362            }
16363
16364            // Restore the old package
16365            if (deletedPkg) {
16366                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16367                File restoreFile = new File(deletedPackage.codePath);
16368                // Parse old package
16369                boolean oldExternal = isExternal(deletedPackage);
16370                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16371                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16372                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16373                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16374                try {
16375                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16376                            null);
16377                } catch (PackageManagerException e) {
16378                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16379                            + e.getMessage());
16380                    return;
16381                }
16382
16383                synchronized (mPackages) {
16384                    // Ensure the installer package name up to date
16385                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16386
16387                    // Update permissions for restored package
16388                    mPermissionManager.updatePermissions(
16389                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16390                            mPermissionCallback);
16391
16392                    mSettings.writeLPr();
16393                }
16394
16395                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16396            }
16397        } else {
16398            synchronized (mPackages) {
16399                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16400                if (ps != null) {
16401                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16402                    if (res.removedInfo.removedChildPackages != null) {
16403                        final int childCount = res.removedInfo.removedChildPackages.size();
16404                        // Iterate in reverse as we may modify the collection
16405                        for (int i = childCount - 1; i >= 0; i--) {
16406                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16407                            if (res.addedChildPackages.containsKey(childPackageName)) {
16408                                res.removedInfo.removedChildPackages.removeAt(i);
16409                            } else {
16410                                PackageRemovedInfo childInfo = res.removedInfo
16411                                        .removedChildPackages.valueAt(i);
16412                                childInfo.removedForAllUsers = mPackages.get(
16413                                        childInfo.removedPackage) == null;
16414                            }
16415                        }
16416                    }
16417                }
16418            }
16419        }
16420    }
16421
16422    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16423            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16424            final @ScanFlags int scanFlags, UserHandle user,
16425            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16426            int installReason) {
16427        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16428                + ", old=" + deletedPackage);
16429
16430        final boolean disabledSystem;
16431
16432        // Remove existing system package
16433        removePackageLI(deletedPackage, true);
16434
16435        synchronized (mPackages) {
16436            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16437        }
16438        if (!disabledSystem) {
16439            // We didn't need to disable the .apk as a current system package,
16440            // which means we are replacing another update that is already
16441            // installed.  We need to make sure to delete the older one's .apk.
16442            res.removedInfo.args = createInstallArgsForExisting(0,
16443                    deletedPackage.applicationInfo.getCodePath(),
16444                    deletedPackage.applicationInfo.getResourcePath(),
16445                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16446        } else {
16447            res.removedInfo.args = null;
16448        }
16449
16450        // Successfully disabled the old package. Now proceed with re-installation
16451        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16452                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16453
16454        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16455        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16456                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16457
16458        PackageParser.Package newPackage = null;
16459        try {
16460            // Add the package to the internal data structures
16461            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16462
16463            // Set the update and install times
16464            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16465            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16466                    System.currentTimeMillis());
16467
16468            // Update the package dynamic state if succeeded
16469            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16470                // Now that the install succeeded make sure we remove data
16471                // directories for any child package the update removed.
16472                final int deletedChildCount = (deletedPackage.childPackages != null)
16473                        ? deletedPackage.childPackages.size() : 0;
16474                final int newChildCount = (newPackage.childPackages != null)
16475                        ? newPackage.childPackages.size() : 0;
16476                for (int i = 0; i < deletedChildCount; i++) {
16477                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16478                    boolean childPackageDeleted = true;
16479                    for (int j = 0; j < newChildCount; j++) {
16480                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16481                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16482                            childPackageDeleted = false;
16483                            break;
16484                        }
16485                    }
16486                    if (childPackageDeleted) {
16487                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16488                                deletedChildPkg.packageName);
16489                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16490                            PackageRemovedInfo removedChildRes = res.removedInfo
16491                                    .removedChildPackages.get(deletedChildPkg.packageName);
16492                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16493                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16494                        }
16495                    }
16496                }
16497
16498                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16499                        installReason);
16500                prepareAppDataAfterInstallLIF(newPackage);
16501
16502                mDexManager.notifyPackageUpdated(newPackage.packageName,
16503                            newPackage.baseCodePath, newPackage.splitCodePaths);
16504            }
16505        } catch (PackageManagerException e) {
16506            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16507            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16508        }
16509
16510        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16511            // Re installation failed. Restore old information
16512            // Remove new pkg information
16513            if (newPackage != null) {
16514                removeInstalledPackageLI(newPackage, true);
16515            }
16516            // Add back the old system package
16517            try {
16518                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16519            } catch (PackageManagerException e) {
16520                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16521            }
16522
16523            synchronized (mPackages) {
16524                if (disabledSystem) {
16525                    enableSystemPackageLPw(deletedPackage);
16526                }
16527
16528                // Ensure the installer package name up to date
16529                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16530
16531                // Update permissions for restored package
16532                mPermissionManager.updatePermissions(
16533                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16534                        mPermissionCallback);
16535
16536                mSettings.writeLPr();
16537            }
16538
16539            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16540                    + " after failed upgrade");
16541        }
16542    }
16543
16544    /**
16545     * Checks whether the parent or any of the child packages have a change shared
16546     * user. For a package to be a valid update the shred users of the parent and
16547     * the children should match. We may later support changing child shared users.
16548     * @param oldPkg The updated package.
16549     * @param newPkg The update package.
16550     * @return The shared user that change between the versions.
16551     */
16552    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16553            PackageParser.Package newPkg) {
16554        // Check parent shared user
16555        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16556            return newPkg.packageName;
16557        }
16558        // Check child shared users
16559        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16560        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16561        for (int i = 0; i < newChildCount; i++) {
16562            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16563            // If this child was present, did it have the same shared user?
16564            for (int j = 0; j < oldChildCount; j++) {
16565                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16566                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16567                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16568                    return newChildPkg.packageName;
16569                }
16570            }
16571        }
16572        return null;
16573    }
16574
16575    private void removeNativeBinariesLI(PackageSetting ps) {
16576        // Remove the lib path for the parent package
16577        if (ps != null) {
16578            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16579            // Remove the lib path for the child packages
16580            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16581            for (int i = 0; i < childCount; i++) {
16582                PackageSetting childPs = null;
16583                synchronized (mPackages) {
16584                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16585                }
16586                if (childPs != null) {
16587                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16588                            .legacyNativeLibraryPathString);
16589                }
16590            }
16591        }
16592    }
16593
16594    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16595        // Enable the parent package
16596        mSettings.enableSystemPackageLPw(pkg.packageName);
16597        // Enable the child packages
16598        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16599        for (int i = 0; i < childCount; i++) {
16600            PackageParser.Package childPkg = pkg.childPackages.get(i);
16601            mSettings.enableSystemPackageLPw(childPkg.packageName);
16602        }
16603    }
16604
16605    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16606            PackageParser.Package newPkg) {
16607        // Disable the parent package (parent always replaced)
16608        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16609        // Disable the child packages
16610        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16611        for (int i = 0; i < childCount; i++) {
16612            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16613            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16614            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16615        }
16616        return disabled;
16617    }
16618
16619    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16620            String installerPackageName) {
16621        // Enable the parent package
16622        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16623        // Enable the child packages
16624        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16625        for (int i = 0; i < childCount; i++) {
16626            PackageParser.Package childPkg = pkg.childPackages.get(i);
16627            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16628        }
16629    }
16630
16631    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16632            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16633        // Update the parent package setting
16634        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16635                res, user, installReason);
16636        // Update the child packages setting
16637        final int childCount = (newPackage.childPackages != null)
16638                ? newPackage.childPackages.size() : 0;
16639        for (int i = 0; i < childCount; i++) {
16640            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16641            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16642            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16643                    childRes.origUsers, childRes, user, installReason);
16644        }
16645    }
16646
16647    private void updateSettingsInternalLI(PackageParser.Package pkg,
16648            String installerPackageName, int[] allUsers, int[] installedForUsers,
16649            PackageInstalledInfo res, UserHandle user, int installReason) {
16650        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16651
16652        final String pkgName = pkg.packageName;
16653
16654        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16655        synchronized (mPackages) {
16656// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16657            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16658                    mPermissionCallback);
16659            // For system-bundled packages, we assume that installing an upgraded version
16660            // of the package implies that the user actually wants to run that new code,
16661            // so we enable the package.
16662            PackageSetting ps = mSettings.mPackages.get(pkgName);
16663            final int userId = user.getIdentifier();
16664            if (ps != null) {
16665                if (isSystemApp(pkg)) {
16666                    if (DEBUG_INSTALL) {
16667                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16668                    }
16669                    // Enable system package for requested users
16670                    if (res.origUsers != null) {
16671                        for (int origUserId : res.origUsers) {
16672                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16673                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16674                                        origUserId, installerPackageName);
16675                            }
16676                        }
16677                    }
16678                    // Also convey the prior install/uninstall state
16679                    if (allUsers != null && installedForUsers != null) {
16680                        for (int currentUserId : allUsers) {
16681                            final boolean installed = ArrayUtils.contains(
16682                                    installedForUsers, currentUserId);
16683                            if (DEBUG_INSTALL) {
16684                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16685                            }
16686                            ps.setInstalled(installed, currentUserId);
16687                        }
16688                        // these install state changes will be persisted in the
16689                        // upcoming call to mSettings.writeLPr().
16690                    }
16691                }
16692                // It's implied that when a user requests installation, they want the app to be
16693                // installed and enabled.
16694                if (userId != UserHandle.USER_ALL) {
16695                    ps.setInstalled(true, userId);
16696                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16697                } else {
16698                    for (int currentUserId : sUserManager.getUserIds()) {
16699                        ps.setInstalled(true, currentUserId);
16700                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
16701                                installerPackageName);
16702                    }
16703                }
16704
16705                // When replacing an existing package, preserve the original install reason for all
16706                // users that had the package installed before.
16707                final Set<Integer> previousUserIds = new ArraySet<>();
16708                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16709                    final int installReasonCount = res.removedInfo.installReasons.size();
16710                    for (int i = 0; i < installReasonCount; i++) {
16711                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16712                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16713                        ps.setInstallReason(previousInstallReason, previousUserId);
16714                        previousUserIds.add(previousUserId);
16715                    }
16716                }
16717
16718                // Set install reason for users that are having the package newly installed.
16719                if (userId == UserHandle.USER_ALL) {
16720                    for (int currentUserId : sUserManager.getUserIds()) {
16721                        if (!previousUserIds.contains(currentUserId)) {
16722                            ps.setInstallReason(installReason, currentUserId);
16723                        }
16724                    }
16725                } else if (!previousUserIds.contains(userId)) {
16726                    ps.setInstallReason(installReason, userId);
16727                }
16728                mSettings.writeKernelMappingLPr(ps);
16729            }
16730            res.name = pkgName;
16731            res.uid = pkg.applicationInfo.uid;
16732            res.pkg = pkg;
16733            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16734            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16735            //to update install status
16736            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16737            mSettings.writeLPr();
16738            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16739        }
16740
16741        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16742    }
16743
16744    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16745        try {
16746            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16747            installPackageLI(args, res);
16748        } finally {
16749            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16750        }
16751    }
16752
16753    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16754        final int installFlags = args.installFlags;
16755        final String installerPackageName = args.installerPackageName;
16756        final String volumeUuid = args.volumeUuid;
16757        final File tmpPackageFile = new File(args.getCodePath());
16758        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16759        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16760                || (args.volumeUuid != null));
16761        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16762        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16763        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16764        final boolean virtualPreload =
16765                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16766        boolean replace = false;
16767        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16768        if (args.move != null) {
16769            // moving a complete application; perform an initial scan on the new install location
16770            scanFlags |= SCAN_INITIAL;
16771        }
16772        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16773            scanFlags |= SCAN_DONT_KILL_APP;
16774        }
16775        if (instantApp) {
16776            scanFlags |= SCAN_AS_INSTANT_APP;
16777        }
16778        if (fullApp) {
16779            scanFlags |= SCAN_AS_FULL_APP;
16780        }
16781        if (virtualPreload) {
16782            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16783        }
16784
16785        // Result object to be returned
16786        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16787        res.installerPackageName = installerPackageName;
16788
16789        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16790
16791        // Sanity check
16792        if (instantApp && (forwardLocked || onExternal)) {
16793            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16794                    + " external=" + onExternal);
16795            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16796            return;
16797        }
16798
16799        // Retrieve PackageSettings and parse package
16800        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16801                | PackageParser.PARSE_ENFORCE_CODE
16802                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16803                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16804                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16805        PackageParser pp = new PackageParser();
16806        pp.setSeparateProcesses(mSeparateProcesses);
16807        pp.setDisplayMetrics(mMetrics);
16808        pp.setCallback(mPackageParserCallback);
16809
16810        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16811        final PackageParser.Package pkg;
16812        try {
16813            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16814            DexMetadataHelper.validatePackageDexMetadata(pkg);
16815        } catch (PackageParserException e) {
16816            res.setError("Failed parse during installPackageLI", e);
16817            return;
16818        } finally {
16819            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16820        }
16821
16822        // Instant apps have several additional install-time checks.
16823        if (instantApp) {
16824            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
16825                Slog.w(TAG,
16826                        "Instant app package " + pkg.packageName + " does not target at least O");
16827                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16828                        "Instant app package must target at least O");
16829                return;
16830            }
16831            if (pkg.applicationInfo.targetSandboxVersion != 2) {
16832                Slog.w(TAG, "Instant app package " + pkg.packageName
16833                        + " does not target targetSandboxVersion 2");
16834                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16835                        "Instant app package must use targetSandboxVersion 2");
16836                return;
16837            }
16838            if (pkg.mSharedUserId != null) {
16839                Slog.w(TAG, "Instant app package " + pkg.packageName
16840                        + " may not declare sharedUserId.");
16841                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16842                        "Instant app package may not declare a sharedUserId");
16843                return;
16844            }
16845        }
16846
16847        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16848            // Static shared libraries have synthetic package names
16849            renameStaticSharedLibraryPackage(pkg);
16850
16851            // No static shared libs on external storage
16852            if (onExternal) {
16853                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16854                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16855                        "Packages declaring static-shared libs cannot be updated");
16856                return;
16857            }
16858        }
16859
16860        // If we are installing a clustered package add results for the children
16861        if (pkg.childPackages != null) {
16862            synchronized (mPackages) {
16863                final int childCount = pkg.childPackages.size();
16864                for (int i = 0; i < childCount; i++) {
16865                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16866                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16867                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16868                    childRes.pkg = childPkg;
16869                    childRes.name = childPkg.packageName;
16870                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16871                    if (childPs != null) {
16872                        childRes.origUsers = childPs.queryInstalledUsers(
16873                                sUserManager.getUserIds(), true);
16874                    }
16875                    if ((mPackages.containsKey(childPkg.packageName))) {
16876                        childRes.removedInfo = new PackageRemovedInfo(this);
16877                        childRes.removedInfo.removedPackage = childPkg.packageName;
16878                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16879                    }
16880                    if (res.addedChildPackages == null) {
16881                        res.addedChildPackages = new ArrayMap<>();
16882                    }
16883                    res.addedChildPackages.put(childPkg.packageName, childRes);
16884                }
16885            }
16886        }
16887
16888        // If package doesn't declare API override, mark that we have an install
16889        // time CPU ABI override.
16890        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16891            pkg.cpuAbiOverride = args.abiOverride;
16892        }
16893
16894        String pkgName = res.name = pkg.packageName;
16895        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16896            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16897                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16898                return;
16899            }
16900        }
16901
16902        try {
16903            // either use what we've been given or parse directly from the APK
16904            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16905                pkg.setSigningDetails(args.signingDetails);
16906            } else {
16907                PackageParser.collectCertificates(pkg, false /* skipVerify */);
16908            }
16909        } catch (PackageParserException e) {
16910            res.setError("Failed collect during installPackageLI", e);
16911            return;
16912        }
16913
16914        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
16915                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16916            Slog.w(TAG, "Instant app package " + pkg.packageName
16917                    + " is not signed with at least APK Signature Scheme v2");
16918            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16919                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
16920            return;
16921        }
16922
16923        // Get rid of all references to package scan path via parser.
16924        pp = null;
16925        String oldCodePath = null;
16926        boolean systemApp = false;
16927        synchronized (mPackages) {
16928            // Check if installing already existing package
16929            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16930                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16931                if (pkg.mOriginalPackages != null
16932                        && pkg.mOriginalPackages.contains(oldName)
16933                        && mPackages.containsKey(oldName)) {
16934                    // This package is derived from an original package,
16935                    // and this device has been updating from that original
16936                    // name.  We must continue using the original name, so
16937                    // rename the new package here.
16938                    pkg.setPackageName(oldName);
16939                    pkgName = pkg.packageName;
16940                    replace = true;
16941                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16942                            + oldName + " pkgName=" + pkgName);
16943                } else if (mPackages.containsKey(pkgName)) {
16944                    // This package, under its official name, already exists
16945                    // on the device; we should replace it.
16946                    replace = true;
16947                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16948                }
16949
16950                // Child packages are installed through the parent package
16951                if (pkg.parentPackage != null) {
16952                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16953                            "Package " + pkg.packageName + " is child of package "
16954                                    + pkg.parentPackage.parentPackage + ". Child packages "
16955                                    + "can be updated only through the parent package.");
16956                    return;
16957                }
16958
16959                if (replace) {
16960                    // Prevent apps opting out from runtime permissions
16961                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16962                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16963                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16964                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16965                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16966                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16967                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16968                                        + " doesn't support runtime permissions but the old"
16969                                        + " target SDK " + oldTargetSdk + " does.");
16970                        return;
16971                    }
16972                    // Prevent persistent apps from being updated
16973                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16974                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16975                                "Package " + oldPackage.packageName + " is a persistent app. "
16976                                        + "Persistent apps are not updateable.");
16977                        return;
16978                    }
16979                    // Prevent apps from downgrading their targetSandbox.
16980                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16981                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16982                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16983                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16984                                "Package " + pkg.packageName + " new target sandbox "
16985                                + newTargetSandbox + " is incompatible with the previous value of"
16986                                + oldTargetSandbox + ".");
16987                        return;
16988                    }
16989
16990                    // Prevent installing of child packages
16991                    if (oldPackage.parentPackage != null) {
16992                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16993                                "Package " + pkg.packageName + " is child of package "
16994                                        + oldPackage.parentPackage + ". Child packages "
16995                                        + "can be updated only through the parent package.");
16996                        return;
16997                    }
16998                }
16999            }
17000
17001            PackageSetting ps = mSettings.mPackages.get(pkgName);
17002            if (ps != null) {
17003                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17004
17005                // Static shared libs have same package with different versions where
17006                // we internally use a synthetic package name to allow multiple versions
17007                // of the same package, therefore we need to compare signatures against
17008                // the package setting for the latest library version.
17009                PackageSetting signatureCheckPs = ps;
17010                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17011                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17012                    if (libraryEntry != null) {
17013                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17014                    }
17015                }
17016
17017                // Quick sanity check that we're signed correctly if updating;
17018                // we'll check this again later when scanning, but we want to
17019                // bail early here before tripping over redefined permissions.
17020                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17021                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
17022                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
17023                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17024                                + pkg.packageName + " upgrade keys do not match the "
17025                                + "previously installed version");
17026                        return;
17027                    }
17028                } else {
17029                    try {
17030                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
17031                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
17032                        // We don't care about disabledPkgSetting on install for now.
17033                        final boolean compatMatch = verifySignatures(
17034                                signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
17035                                compareRecover);
17036                        // The new KeySets will be re-added later in the scanning process.
17037                        if (compatMatch) {
17038                            synchronized (mPackages) {
17039                                ksms.removeAppKeySetDataLPw(pkg.packageName);
17040                            }
17041                        }
17042                    } catch (PackageManagerException e) {
17043                        res.setError(e.error, e.getMessage());
17044                        return;
17045                    }
17046                }
17047
17048                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17049                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17050                    systemApp = (ps.pkg.applicationInfo.flags &
17051                            ApplicationInfo.FLAG_SYSTEM) != 0;
17052                }
17053                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17054            }
17055
17056            int N = pkg.permissions.size();
17057            for (int i = N-1; i >= 0; i--) {
17058                final PackageParser.Permission perm = pkg.permissions.get(i);
17059                final BasePermission bp =
17060                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
17061
17062                // Don't allow anyone but the system to define ephemeral permissions.
17063                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
17064                        && !systemApp) {
17065                    Slog.w(TAG, "Non-System package " + pkg.packageName
17066                            + " attempting to delcare ephemeral permission "
17067                            + perm.info.name + "; Removing ephemeral.");
17068                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
17069                }
17070
17071                // Check whether the newly-scanned package wants to define an already-defined perm
17072                if (bp != null) {
17073                    // If the defining package is signed with our cert, it's okay.  This
17074                    // also includes the "updating the same package" case, of course.
17075                    // "updating same package" could also involve key-rotation.
17076                    final boolean sigsOk;
17077                    final String sourcePackageName = bp.getSourcePackageName();
17078                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17079                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17080                    if (sourcePackageName.equals(pkg.packageName)
17081                            && (ksms.shouldCheckUpgradeKeySetLocked(
17082                                    sourcePackageSetting, scanFlags))) {
17083                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17084                    } else {
17085
17086                        // in the event of signing certificate rotation, we need to see if the
17087                        // package's certificate has rotated from the current one, or if it is an
17088                        // older certificate with which the current is ok with sharing permissions
17089                        if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17090                                        pkg.mSigningDetails,
17091                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17092                            sigsOk = true;
17093                        } else if (pkg.mSigningDetails.checkCapability(
17094                                        sourcePackageSetting.signatures.mSigningDetails,
17095                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17096
17097                            // the scanned package checks out, has signing certificate rotation
17098                            // history, and is newer; bring it over
17099                            sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17100                            sigsOk = true;
17101                        } else {
17102                            sigsOk = false;
17103                        }
17104                    }
17105                    if (!sigsOk) {
17106                        // If the owning package is the system itself, we log but allow
17107                        // install to proceed; we fail the install on all other permission
17108                        // redefinitions.
17109                        if (!sourcePackageName.equals("android")) {
17110                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17111                                    + pkg.packageName + " attempting to redeclare permission "
17112                                    + perm.info.name + " already owned by " + sourcePackageName);
17113                            res.origPermission = perm.info.name;
17114                            res.origPackage = sourcePackageName;
17115                            return;
17116                        } else {
17117                            Slog.w(TAG, "Package " + pkg.packageName
17118                                    + " attempting to redeclare system permission "
17119                                    + perm.info.name + "; ignoring new declaration");
17120                            pkg.permissions.remove(i);
17121                        }
17122                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17123                        // Prevent apps to change protection level to dangerous from any other
17124                        // type as this would allow a privilege escalation where an app adds a
17125                        // normal/signature permission in other app's group and later redefines
17126                        // it as dangerous leading to the group auto-grant.
17127                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17128                                == PermissionInfo.PROTECTION_DANGEROUS) {
17129                            if (bp != null && !bp.isRuntime()) {
17130                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17131                                        + "non-runtime permission " + perm.info.name
17132                                        + " to runtime; keeping old protection level");
17133                                perm.info.protectionLevel = bp.getProtectionLevel();
17134                            }
17135                        }
17136                    }
17137                }
17138            }
17139        }
17140
17141        if (systemApp) {
17142            if (onExternal) {
17143                // Abort update; system app can't be replaced with app on sdcard
17144                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17145                        "Cannot install updates to system apps on sdcard");
17146                return;
17147            } else if (instantApp) {
17148                // Abort update; system app can't be replaced with an instant app
17149                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17150                        "Cannot update a system app with an instant app");
17151                return;
17152            }
17153        }
17154
17155        if (args.move != null) {
17156            // We did an in-place move, so dex is ready to roll
17157            scanFlags |= SCAN_NO_DEX;
17158            scanFlags |= SCAN_MOVE;
17159
17160            synchronized (mPackages) {
17161                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17162                if (ps == null) {
17163                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17164                            "Missing settings for moved package " + pkgName);
17165                }
17166
17167                // We moved the entire application as-is, so bring over the
17168                // previously derived ABI information.
17169                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17170                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17171            }
17172
17173        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17174            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17175            scanFlags |= SCAN_NO_DEX;
17176
17177            try {
17178                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17179                    args.abiOverride : pkg.cpuAbiOverride);
17180                final boolean extractNativeLibs = !pkg.isLibrary();
17181                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17182            } catch (PackageManagerException pme) {
17183                Slog.e(TAG, "Error deriving application ABI", pme);
17184                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17185                return;
17186            }
17187
17188            // Shared libraries for the package need to be updated.
17189            synchronized (mPackages) {
17190                try {
17191                    updateSharedLibrariesLPr(pkg, null);
17192                } catch (PackageManagerException e) {
17193                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17194                }
17195            }
17196        }
17197
17198        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17199            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17200            return;
17201        }
17202
17203        if (PackageManagerServiceUtils.isApkVerityEnabled()) {
17204            String apkPath = null;
17205            synchronized (mPackages) {
17206                // Note that if the attacker managed to skip verify setup, for example by tampering
17207                // with the package settings, upon reboot we will do full apk verification when
17208                // verity is not detected.
17209                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17210                if (ps != null && ps.isPrivileged()) {
17211                    apkPath = pkg.baseCodePath;
17212                }
17213            }
17214
17215            if (apkPath != null) {
17216                final VerityUtils.SetupResult result =
17217                        VerityUtils.generateApkVeritySetupData(apkPath);
17218                if (result.isOk()) {
17219                    if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
17220                    FileDescriptor fd = result.getUnownedFileDescriptor();
17221                    try {
17222                        mInstaller.installApkVerity(apkPath, fd);
17223                    } catch (InstallerException e) {
17224                        res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17225                                "Failed to set up verity: " + e);
17226                        return;
17227                    } finally {
17228                        IoUtils.closeQuietly(fd);
17229                    }
17230                } else if (result.isFailed()) {
17231                    res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Failed to generate verity");
17232                    return;
17233                } else {
17234                    // Do nothing if verity is skipped. Will fall back to full apk verification on
17235                    // reboot.
17236                }
17237            }
17238        }
17239
17240        if (!instantApp) {
17241            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17242        } else {
17243            if (DEBUG_DOMAIN_VERIFICATION) {
17244                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17245            }
17246        }
17247
17248        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17249                "installPackageLI")) {
17250            if (replace) {
17251                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17252                    // Static libs have a synthetic package name containing the version
17253                    // and cannot be updated as an update would get a new package name,
17254                    // unless this is the exact same version code which is useful for
17255                    // development.
17256                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17257                    if (existingPkg != null &&
17258                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17259                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17260                                + "static-shared libs cannot be updated");
17261                        return;
17262                    }
17263                }
17264                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
17265                        installerPackageName, res, args.installReason);
17266            } else {
17267                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17268                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17269            }
17270        }
17271
17272        // Prepare the application profiles for the new code paths.
17273        // This needs to be done before invoking dexopt so that any install-time profile
17274        // can be used for optimizations.
17275        mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
17276
17277        // Check whether we need to dexopt the app.
17278        //
17279        // NOTE: it is IMPORTANT to call dexopt:
17280        //   - after doRename which will sync the package data from PackageParser.Package and its
17281        //     corresponding ApplicationInfo.
17282        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
17283        //     uid of the application (pkg.applicationInfo.uid).
17284        //     This update happens in place!
17285        //
17286        // We only need to dexopt if the package meets ALL of the following conditions:
17287        //   1) it is not forward locked.
17288        //   2) it is not on on an external ASEC container.
17289        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
17290        //
17291        // Note that we do not dexopt instant apps by default. dexopt can take some time to
17292        // complete, so we skip this step during installation. Instead, we'll take extra time
17293        // the first time the instant app starts. It's preferred to do it this way to provide
17294        // continuous progress to the useur instead of mysteriously blocking somewhere in the
17295        // middle of running an instant app. The default behaviour can be overridden
17296        // via gservices.
17297        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
17298                && !forwardLocked
17299                && !pkg.applicationInfo.isExternalAsec()
17300                && (!instantApp || Global.getInt(mContext.getContentResolver(),
17301                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
17302
17303        if (performDexopt) {
17304            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17305            // Do not run PackageDexOptimizer through the local performDexOpt
17306            // method because `pkg` may not be in `mPackages` yet.
17307            //
17308            // Also, don't fail application installs if the dexopt step fails.
17309            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
17310                    REASON_INSTALL,
17311                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
17312                    DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17313            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17314                    null /* instructionSets */,
17315                    getOrCreateCompilerPackageStats(pkg),
17316                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
17317                    dexoptOptions);
17318            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17319        }
17320
17321        // Notify BackgroundDexOptService that the package has been changed.
17322        // If this is an update of a package which used to fail to compile,
17323        // BackgroundDexOptService will remove it from its blacklist.
17324        // TODO: Layering violation
17325        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17326
17327        synchronized (mPackages) {
17328            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17329            if (ps != null) {
17330                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17331                ps.setUpdateAvailable(false /*updateAvailable*/);
17332            }
17333
17334            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17335            for (int i = 0; i < childCount; i++) {
17336                PackageParser.Package childPkg = pkg.childPackages.get(i);
17337                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17338                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17339                if (childPs != null) {
17340                    childRes.newUsers = childPs.queryInstalledUsers(
17341                            sUserManager.getUserIds(), true);
17342                }
17343            }
17344
17345            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17346                updateSequenceNumberLP(ps, res.newUsers);
17347                updateInstantAppInstallerLocked(pkgName);
17348            }
17349        }
17350    }
17351
17352    private void startIntentFilterVerifications(int userId, boolean replacing,
17353            PackageParser.Package pkg) {
17354        if (mIntentFilterVerifierComponent == null) {
17355            Slog.w(TAG, "No IntentFilter verification will not be done as "
17356                    + "there is no IntentFilterVerifier available!");
17357            return;
17358        }
17359
17360        final int verifierUid = getPackageUid(
17361                mIntentFilterVerifierComponent.getPackageName(),
17362                MATCH_DEBUG_TRIAGED_MISSING,
17363                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17364
17365        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17366        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17367        mHandler.sendMessage(msg);
17368
17369        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17370        for (int i = 0; i < childCount; i++) {
17371            PackageParser.Package childPkg = pkg.childPackages.get(i);
17372            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17373            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17374            mHandler.sendMessage(msg);
17375        }
17376    }
17377
17378    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17379            PackageParser.Package pkg) {
17380        int size = pkg.activities.size();
17381        if (size == 0) {
17382            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17383                    "No activity, so no need to verify any IntentFilter!");
17384            return;
17385        }
17386
17387        final boolean hasDomainURLs = hasDomainURLs(pkg);
17388        if (!hasDomainURLs) {
17389            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17390                    "No domain URLs, so no need to verify any IntentFilter!");
17391            return;
17392        }
17393
17394        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17395                + " if any IntentFilter from the " + size
17396                + " Activities needs verification ...");
17397
17398        int count = 0;
17399        final String packageName = pkg.packageName;
17400
17401        synchronized (mPackages) {
17402            // If this is a new install and we see that we've already run verification for this
17403            // package, we have nothing to do: it means the state was restored from backup.
17404            if (!replacing) {
17405                IntentFilterVerificationInfo ivi =
17406                        mSettings.getIntentFilterVerificationLPr(packageName);
17407                if (ivi != null) {
17408                    if (DEBUG_DOMAIN_VERIFICATION) {
17409                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17410                                + ivi.getStatusString());
17411                    }
17412                    return;
17413                }
17414            }
17415
17416            // If any filters need to be verified, then all need to be.
17417            boolean needToVerify = false;
17418            for (PackageParser.Activity a : pkg.activities) {
17419                for (ActivityIntentInfo filter : a.intents) {
17420                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17421                        if (DEBUG_DOMAIN_VERIFICATION) {
17422                            Slog.d(TAG,
17423                                    "Intent filter needs verification, so processing all filters");
17424                        }
17425                        needToVerify = true;
17426                        break;
17427                    }
17428                }
17429            }
17430
17431            if (needToVerify) {
17432                final int verificationId = mIntentFilterVerificationToken++;
17433                for (PackageParser.Activity a : pkg.activities) {
17434                    for (ActivityIntentInfo filter : a.intents) {
17435                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17436                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17437                                    "Verification needed for IntentFilter:" + filter.toString());
17438                            mIntentFilterVerifier.addOneIntentFilterVerification(
17439                                    verifierUid, userId, verificationId, filter, packageName);
17440                            count++;
17441                        }
17442                    }
17443                }
17444            }
17445        }
17446
17447        if (count > 0) {
17448            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17449                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17450                    +  " for userId:" + userId);
17451            mIntentFilterVerifier.startVerifications(userId);
17452        } else {
17453            if (DEBUG_DOMAIN_VERIFICATION) {
17454                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17455            }
17456        }
17457    }
17458
17459    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17460        final ComponentName cn  = filter.activity.getComponentName();
17461        final String packageName = cn.getPackageName();
17462
17463        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17464                packageName);
17465        if (ivi == null) {
17466            return true;
17467        }
17468        int status = ivi.getStatus();
17469        switch (status) {
17470            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17471            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17472                return true;
17473
17474            default:
17475                // Nothing to do
17476                return false;
17477        }
17478    }
17479
17480    private static boolean isMultiArch(ApplicationInfo info) {
17481        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17482    }
17483
17484    private static boolean isExternal(PackageParser.Package pkg) {
17485        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17486    }
17487
17488    private static boolean isExternal(PackageSetting ps) {
17489        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17490    }
17491
17492    private static boolean isSystemApp(PackageParser.Package pkg) {
17493        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17494    }
17495
17496    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17497        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17498    }
17499
17500    private static boolean isOemApp(PackageParser.Package pkg) {
17501        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17502    }
17503
17504    private static boolean isVendorApp(PackageParser.Package pkg) {
17505        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17506    }
17507
17508    private static boolean isProductApp(PackageParser.Package pkg) {
17509        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
17510    }
17511
17512    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17513        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17514    }
17515
17516    private static boolean isSystemApp(PackageSetting ps) {
17517        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17518    }
17519
17520    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17521        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17522    }
17523
17524    private int packageFlagsToInstallFlags(PackageSetting ps) {
17525        int installFlags = 0;
17526        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17527            // This existing package was an external ASEC install when we have
17528            // the external flag without a UUID
17529            installFlags |= PackageManager.INSTALL_EXTERNAL;
17530        }
17531        if (ps.isForwardLocked()) {
17532            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17533        }
17534        return installFlags;
17535    }
17536
17537    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17538        if (isExternal(pkg)) {
17539            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17540                return mSettings.getExternalVersion();
17541            } else {
17542                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17543            }
17544        } else {
17545            return mSettings.getInternalVersion();
17546        }
17547    }
17548
17549    private void deleteTempPackageFiles() {
17550        final FilenameFilter filter = new FilenameFilter() {
17551            public boolean accept(File dir, String name) {
17552                return name.startsWith("vmdl") && name.endsWith(".tmp");
17553            }
17554        };
17555        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17556            file.delete();
17557        }
17558    }
17559
17560    @Override
17561    public void deletePackageAsUser(String packageName, int versionCode,
17562            IPackageDeleteObserver observer, int userId, int flags) {
17563        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17564                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17565    }
17566
17567    @Override
17568    public void deletePackageVersioned(VersionedPackage versionedPackage,
17569            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17570        final int callingUid = Binder.getCallingUid();
17571        mContext.enforceCallingOrSelfPermission(
17572                android.Manifest.permission.DELETE_PACKAGES, null);
17573        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17574        Preconditions.checkNotNull(versionedPackage);
17575        Preconditions.checkNotNull(observer);
17576        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17577                PackageManager.VERSION_CODE_HIGHEST,
17578                Long.MAX_VALUE, "versionCode must be >= -1");
17579
17580        final String packageName = versionedPackage.getPackageName();
17581        final long versionCode = versionedPackage.getLongVersionCode();
17582        final String internalPackageName;
17583        synchronized (mPackages) {
17584            // Normalize package name to handle renamed packages and static libs
17585            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17586        }
17587
17588        final int uid = Binder.getCallingUid();
17589        if (!isOrphaned(internalPackageName)
17590                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17591            try {
17592                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17593                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17594                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17595                observer.onUserActionRequired(intent);
17596            } catch (RemoteException re) {
17597            }
17598            return;
17599        }
17600        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17601        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17602        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17603            mContext.enforceCallingOrSelfPermission(
17604                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17605                    "deletePackage for user " + userId);
17606        }
17607
17608        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17609            try {
17610                observer.onPackageDeleted(packageName,
17611                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17612            } catch (RemoteException re) {
17613            }
17614            return;
17615        }
17616
17617        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17618            try {
17619                observer.onPackageDeleted(packageName,
17620                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17621            } catch (RemoteException re) {
17622            }
17623            return;
17624        }
17625
17626        if (DEBUG_REMOVE) {
17627            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17628                    + " deleteAllUsers: " + deleteAllUsers + " version="
17629                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17630                    ? "VERSION_CODE_HIGHEST" : versionCode));
17631        }
17632        // Queue up an async operation since the package deletion may take a little while.
17633        mHandler.post(new Runnable() {
17634            public void run() {
17635                mHandler.removeCallbacks(this);
17636                int returnCode;
17637                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17638                boolean doDeletePackage = true;
17639                if (ps != null) {
17640                    final boolean targetIsInstantApp =
17641                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17642                    doDeletePackage = !targetIsInstantApp
17643                            || canViewInstantApps;
17644                }
17645                if (doDeletePackage) {
17646                    if (!deleteAllUsers) {
17647                        returnCode = deletePackageX(internalPackageName, versionCode,
17648                                userId, deleteFlags);
17649                    } else {
17650                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17651                                internalPackageName, users);
17652                        // If nobody is blocking uninstall, proceed with delete for all users
17653                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17654                            returnCode = deletePackageX(internalPackageName, versionCode,
17655                                    userId, deleteFlags);
17656                        } else {
17657                            // Otherwise uninstall individually for users with blockUninstalls=false
17658                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17659                            for (int userId : users) {
17660                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17661                                    returnCode = deletePackageX(internalPackageName, versionCode,
17662                                            userId, userFlags);
17663                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17664                                        Slog.w(TAG, "Package delete failed for user " + userId
17665                                                + ", returnCode " + returnCode);
17666                                    }
17667                                }
17668                            }
17669                            // The app has only been marked uninstalled for certain users.
17670                            // We still need to report that delete was blocked
17671                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17672                        }
17673                    }
17674                } else {
17675                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17676                }
17677                try {
17678                    observer.onPackageDeleted(packageName, returnCode, null);
17679                } catch (RemoteException e) {
17680                    Log.i(TAG, "Observer no longer exists.");
17681                } //end catch
17682            } //end run
17683        });
17684    }
17685
17686    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17687        if (pkg.staticSharedLibName != null) {
17688            return pkg.manifestPackageName;
17689        }
17690        return pkg.packageName;
17691    }
17692
17693    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17694        // Handle renamed packages
17695        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17696        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17697
17698        // Is this a static library?
17699        LongSparseArray<SharedLibraryEntry> versionedLib =
17700                mStaticLibsByDeclaringPackage.get(packageName);
17701        if (versionedLib == null || versionedLib.size() <= 0) {
17702            return packageName;
17703        }
17704
17705        // Figure out which lib versions the caller can see
17706        LongSparseLongArray versionsCallerCanSee = null;
17707        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17708        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17709                && callingAppId != Process.ROOT_UID) {
17710            versionsCallerCanSee = new LongSparseLongArray();
17711            String libName = versionedLib.valueAt(0).info.getName();
17712            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17713            if (uidPackages != null) {
17714                for (String uidPackage : uidPackages) {
17715                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17716                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17717                    if (libIdx >= 0) {
17718                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17719                        versionsCallerCanSee.append(libVersion, libVersion);
17720                    }
17721                }
17722            }
17723        }
17724
17725        // Caller can see nothing - done
17726        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17727            return packageName;
17728        }
17729
17730        // Find the version the caller can see and the app version code
17731        SharedLibraryEntry highestVersion = null;
17732        final int versionCount = versionedLib.size();
17733        for (int i = 0; i < versionCount; i++) {
17734            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17735            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17736                    libEntry.info.getLongVersion()) < 0) {
17737                continue;
17738            }
17739            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17740            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17741                if (libVersionCode == versionCode) {
17742                    return libEntry.apk;
17743                }
17744            } else if (highestVersion == null) {
17745                highestVersion = libEntry;
17746            } else if (libVersionCode  > highestVersion.info
17747                    .getDeclaringPackage().getLongVersionCode()) {
17748                highestVersion = libEntry;
17749            }
17750        }
17751
17752        if (highestVersion != null) {
17753            return highestVersion.apk;
17754        }
17755
17756        return packageName;
17757    }
17758
17759    boolean isCallerVerifier(int callingUid) {
17760        final int callingUserId = UserHandle.getUserId(callingUid);
17761        return mRequiredVerifierPackage != null &&
17762                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17763    }
17764
17765    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17766        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17767              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17768            return true;
17769        }
17770        final int callingUserId = UserHandle.getUserId(callingUid);
17771        // If the caller installed the pkgName, then allow it to silently uninstall.
17772        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17773            return true;
17774        }
17775
17776        // Allow package verifier to silently uninstall.
17777        if (mRequiredVerifierPackage != null &&
17778                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17779            return true;
17780        }
17781
17782        // Allow package uninstaller to silently uninstall.
17783        if (mRequiredUninstallerPackage != null &&
17784                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17785            return true;
17786        }
17787
17788        // Allow storage manager to silently uninstall.
17789        if (mStorageManagerPackage != null &&
17790                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17791            return true;
17792        }
17793
17794        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17795        // uninstall for device owner provisioning.
17796        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17797                == PERMISSION_GRANTED) {
17798            return true;
17799        }
17800
17801        return false;
17802    }
17803
17804    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17805        int[] result = EMPTY_INT_ARRAY;
17806        for (int userId : userIds) {
17807            if (getBlockUninstallForUser(packageName, userId)) {
17808                result = ArrayUtils.appendInt(result, userId);
17809            }
17810        }
17811        return result;
17812    }
17813
17814    @Override
17815    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17816        final int callingUid = Binder.getCallingUid();
17817        if (getInstantAppPackageName(callingUid) != null
17818                && !isCallerSameApp(packageName, callingUid)) {
17819            return false;
17820        }
17821        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17822    }
17823
17824    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17825        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17826                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17827        try {
17828            if (dpm != null) {
17829                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17830                        /* callingUserOnly =*/ false);
17831                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17832                        : deviceOwnerComponentName.getPackageName();
17833                // Does the package contains the device owner?
17834                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17835                // this check is probably not needed, since DO should be registered as a device
17836                // admin on some user too. (Original bug for this: b/17657954)
17837                if (packageName.equals(deviceOwnerPackageName)) {
17838                    return true;
17839                }
17840                // Does it contain a device admin for any user?
17841                int[] users;
17842                if (userId == UserHandle.USER_ALL) {
17843                    users = sUserManager.getUserIds();
17844                } else {
17845                    users = new int[]{userId};
17846                }
17847                for (int i = 0; i < users.length; ++i) {
17848                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17849                        return true;
17850                    }
17851                }
17852            }
17853        } catch (RemoteException e) {
17854        }
17855        return false;
17856    }
17857
17858    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17859        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17860    }
17861
17862    /**
17863     *  This method is an internal method that could be get invoked either
17864     *  to delete an installed package or to clean up a failed installation.
17865     *  After deleting an installed package, a broadcast is sent to notify any
17866     *  listeners that the package has been removed. For cleaning up a failed
17867     *  installation, the broadcast is not necessary since the package's
17868     *  installation wouldn't have sent the initial broadcast either
17869     *  The key steps in deleting a package are
17870     *  deleting the package information in internal structures like mPackages,
17871     *  deleting the packages base directories through installd
17872     *  updating mSettings to reflect current status
17873     *  persisting settings for later use
17874     *  sending a broadcast if necessary
17875     */
17876    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17877        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17878        final boolean res;
17879
17880        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17881                ? UserHandle.USER_ALL : userId;
17882
17883        if (isPackageDeviceAdmin(packageName, removeUser)) {
17884            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17885            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17886        }
17887
17888        PackageSetting uninstalledPs = null;
17889        PackageParser.Package pkg = null;
17890
17891        // for the uninstall-updates case and restricted profiles, remember the per-
17892        // user handle installed state
17893        int[] allUsers;
17894        synchronized (mPackages) {
17895            uninstalledPs = mSettings.mPackages.get(packageName);
17896            if (uninstalledPs == null) {
17897                Slog.w(TAG, "Not removing non-existent package " + packageName);
17898                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17899            }
17900
17901            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17902                    && uninstalledPs.versionCode != versionCode) {
17903                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17904                        + uninstalledPs.versionCode + " != " + versionCode);
17905                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17906            }
17907
17908            // Static shared libs can be declared by any package, so let us not
17909            // allow removing a package if it provides a lib others depend on.
17910            pkg = mPackages.get(packageName);
17911
17912            allUsers = sUserManager.getUserIds();
17913
17914            if (pkg != null && pkg.staticSharedLibName != null) {
17915                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17916                        pkg.staticSharedLibVersion);
17917                if (libEntry != null) {
17918                    for (int currUserId : allUsers) {
17919                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17920                            continue;
17921                        }
17922                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17923                                libEntry.info, 0, currUserId);
17924                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17925                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17926                                    + " hosting lib " + libEntry.info.getName() + " version "
17927                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17928                                    + " for user " + currUserId);
17929                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17930                        }
17931                    }
17932                }
17933            }
17934
17935            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17936        }
17937
17938        final int freezeUser;
17939        if (isUpdatedSystemApp(uninstalledPs)
17940                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17941            // We're downgrading a system app, which will apply to all users, so
17942            // freeze them all during the downgrade
17943            freezeUser = UserHandle.USER_ALL;
17944        } else {
17945            freezeUser = removeUser;
17946        }
17947
17948        synchronized (mInstallLock) {
17949            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17950            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17951                    deleteFlags, "deletePackageX")) {
17952                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17953                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17954            }
17955            synchronized (mPackages) {
17956                if (res) {
17957                    if (pkg != null) {
17958                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17959                    }
17960                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17961                    updateInstantAppInstallerLocked(packageName);
17962                }
17963            }
17964        }
17965
17966        if (res) {
17967            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17968            info.sendPackageRemovedBroadcasts(killApp);
17969            info.sendSystemPackageUpdatedBroadcasts();
17970            info.sendSystemPackageAppearedBroadcasts();
17971        }
17972        // Force a gc here.
17973        Runtime.getRuntime().gc();
17974        // Delete the resources here after sending the broadcast to let
17975        // other processes clean up before deleting resources.
17976        if (info.args != null) {
17977            synchronized (mInstallLock) {
17978                info.args.doPostDeleteLI(true);
17979            }
17980        }
17981
17982        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17983    }
17984
17985    static class PackageRemovedInfo {
17986        final PackageSender packageSender;
17987        String removedPackage;
17988        String installerPackageName;
17989        int uid = -1;
17990        int removedAppId = -1;
17991        int[] origUsers;
17992        int[] removedUsers = null;
17993        int[] broadcastUsers = null;
17994        int[] instantUserIds = null;
17995        SparseArray<Integer> installReasons;
17996        boolean isRemovedPackageSystemUpdate = false;
17997        boolean isUpdate;
17998        boolean dataRemoved;
17999        boolean removedForAllUsers;
18000        boolean isStaticSharedLib;
18001        // Clean up resources deleted packages.
18002        InstallArgs args = null;
18003        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18004        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18005
18006        PackageRemovedInfo(PackageSender packageSender) {
18007            this.packageSender = packageSender;
18008        }
18009
18010        void sendPackageRemovedBroadcasts(boolean killApp) {
18011            sendPackageRemovedBroadcastInternal(killApp);
18012            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18013            for (int i = 0; i < childCount; i++) {
18014                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18015                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18016            }
18017        }
18018
18019        void sendSystemPackageUpdatedBroadcasts() {
18020            if (isRemovedPackageSystemUpdate) {
18021                sendSystemPackageUpdatedBroadcastsInternal();
18022                final int childCount = (removedChildPackages != null)
18023                        ? removedChildPackages.size() : 0;
18024                for (int i = 0; i < childCount; i++) {
18025                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18026                    if (childInfo.isRemovedPackageSystemUpdate) {
18027                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18028                    }
18029                }
18030            }
18031        }
18032
18033        void sendSystemPackageAppearedBroadcasts() {
18034            final int packageCount = (appearedChildPackages != null)
18035                    ? appearedChildPackages.size() : 0;
18036            for (int i = 0; i < packageCount; i++) {
18037                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18038                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18039                    true /*sendBootCompleted*/, false /*startReceiver*/,
18040                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
18041            }
18042        }
18043
18044        private void sendSystemPackageUpdatedBroadcastsInternal() {
18045            Bundle extras = new Bundle(2);
18046            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18047            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18048            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18049                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18050            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18051                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18052            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18053                null, null, 0, removedPackage, null, null, null);
18054            if (installerPackageName != null) {
18055                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18056                        removedPackage, extras, 0 /*flags*/,
18057                        installerPackageName, null, null, null);
18058                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18059                        removedPackage, extras, 0 /*flags*/,
18060                        installerPackageName, null, null, null);
18061            }
18062        }
18063
18064        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18065            // Don't send static shared library removal broadcasts as these
18066            // libs are visible only the the apps that depend on them an one
18067            // cannot remove the library if it has a dependency.
18068            if (isStaticSharedLib) {
18069                return;
18070            }
18071            Bundle extras = new Bundle(2);
18072            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18073            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18074            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18075            if (isUpdate || isRemovedPackageSystemUpdate) {
18076                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18077            }
18078            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18079            if (removedPackage != null) {
18080                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18081                    removedPackage, extras, 0, null /*targetPackage*/, null,
18082                    broadcastUsers, instantUserIds);
18083                if (installerPackageName != null) {
18084                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18085                            removedPackage, extras, 0 /*flags*/,
18086                            installerPackageName, null, broadcastUsers, instantUserIds);
18087                }
18088                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18089                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18090                        removedPackage, extras,
18091                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18092                        null, null, broadcastUsers, instantUserIds);
18093                    packageSender.notifyPackageRemoved(removedPackage);
18094                }
18095            }
18096            if (removedAppId >= 0) {
18097                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18098                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18099                    null, null, broadcastUsers, instantUserIds);
18100            }
18101        }
18102
18103        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18104            removedUsers = userIds;
18105            if (removedUsers == null) {
18106                broadcastUsers = null;
18107                return;
18108            }
18109
18110            broadcastUsers = EMPTY_INT_ARRAY;
18111            instantUserIds = EMPTY_INT_ARRAY;
18112            for (int i = userIds.length - 1; i >= 0; --i) {
18113                final int userId = userIds[i];
18114                if (deletedPackageSetting.getInstantApp(userId)) {
18115                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18116                } else {
18117                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18118                }
18119            }
18120        }
18121    }
18122
18123    /*
18124     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18125     * flag is not set, the data directory is removed as well.
18126     * make sure this flag is set for partially installed apps. If not its meaningless to
18127     * delete a partially installed application.
18128     */
18129    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18130            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18131        String packageName = ps.name;
18132        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18133        // Retrieve object to delete permissions for shared user later on
18134        final PackageParser.Package deletedPkg;
18135        final PackageSetting deletedPs;
18136        // reader
18137        synchronized (mPackages) {
18138            deletedPkg = mPackages.get(packageName);
18139            deletedPs = mSettings.mPackages.get(packageName);
18140            if (outInfo != null) {
18141                outInfo.removedPackage = packageName;
18142                outInfo.installerPackageName = ps.installerPackageName;
18143                outInfo.isStaticSharedLib = deletedPkg != null
18144                        && deletedPkg.staticSharedLibName != null;
18145                outInfo.populateUsers(deletedPs == null ? null
18146                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18147            }
18148        }
18149
18150        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
18151
18152        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18153            final PackageParser.Package resolvedPkg;
18154            if (deletedPkg != null) {
18155                resolvedPkg = deletedPkg;
18156            } else {
18157                // We don't have a parsed package when it lives on an ejected
18158                // adopted storage device, so fake something together
18159                resolvedPkg = new PackageParser.Package(ps.name);
18160                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18161            }
18162            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18163                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18164            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18165            if (outInfo != null) {
18166                outInfo.dataRemoved = true;
18167            }
18168            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18169        }
18170
18171        int removedAppId = -1;
18172
18173        // writer
18174        synchronized (mPackages) {
18175            boolean installedStateChanged = false;
18176            if (deletedPs != null) {
18177                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18178                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18179                    clearDefaultBrowserIfNeeded(packageName);
18180                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18181                    removedAppId = mSettings.removePackageLPw(packageName);
18182                    if (outInfo != null) {
18183                        outInfo.removedAppId = removedAppId;
18184                    }
18185                    mPermissionManager.updatePermissions(
18186                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18187                    if (deletedPs.sharedUser != null) {
18188                        // Remove permissions associated with package. Since runtime
18189                        // permissions are per user we have to kill the removed package
18190                        // or packages running under the shared user of the removed
18191                        // package if revoking the permissions requested only by the removed
18192                        // package is successful and this causes a change in gids.
18193                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18194                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18195                                    userId);
18196                            if (userIdToKill == UserHandle.USER_ALL
18197                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18198                                // If gids changed for this user, kill all affected packages.
18199                                mHandler.post(new Runnable() {
18200                                    @Override
18201                                    public void run() {
18202                                        // This has to happen with no lock held.
18203                                        killApplication(deletedPs.name, deletedPs.appId,
18204                                                KILL_APP_REASON_GIDS_CHANGED);
18205                                    }
18206                                });
18207                                break;
18208                            }
18209                        }
18210                    }
18211                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18212                }
18213                // make sure to preserve per-user disabled state if this removal was just
18214                // a downgrade of a system app to the factory package
18215                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18216                    if (DEBUG_REMOVE) {
18217                        Slog.d(TAG, "Propagating install state across downgrade");
18218                    }
18219                    for (int userId : allUserHandles) {
18220                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18221                        if (DEBUG_REMOVE) {
18222                            Slog.d(TAG, "    user " + userId + " => " + installed);
18223                        }
18224                        if (installed != ps.getInstalled(userId)) {
18225                            installedStateChanged = true;
18226                        }
18227                        ps.setInstalled(installed, userId);
18228                    }
18229                }
18230            }
18231            // can downgrade to reader
18232            if (writeSettings) {
18233                // Save settings now
18234                mSettings.writeLPr();
18235            }
18236            if (installedStateChanged) {
18237                mSettings.writeKernelMappingLPr(ps);
18238            }
18239        }
18240        if (removedAppId != -1) {
18241            // A user ID was deleted here. Go through all users and remove it
18242            // from KeyStore.
18243            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18244        }
18245    }
18246
18247    static boolean locationIsPrivileged(String path) {
18248        try {
18249            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18250            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18251            final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
18252            final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18253            return path.startsWith(privilegedAppDir.getCanonicalPath())
18254                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath())
18255                    || path.startsWith(privilegedOdmAppDir.getCanonicalPath())
18256                    || path.startsWith(privilegedProductAppDir.getCanonicalPath());
18257        } catch (IOException e) {
18258            Slog.e(TAG, "Unable to access code path " + path);
18259        }
18260        return false;
18261    }
18262
18263    static boolean locationIsOem(String path) {
18264        try {
18265            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
18266        } catch (IOException e) {
18267            Slog.e(TAG, "Unable to access code path " + path);
18268        }
18269        return false;
18270    }
18271
18272    static boolean locationIsVendor(String path) {
18273        try {
18274            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath())
18275                    || path.startsWith(Environment.getOdmDirectory().getCanonicalPath());
18276        } catch (IOException e) {
18277            Slog.e(TAG, "Unable to access code path " + path);
18278        }
18279        return false;
18280    }
18281
18282    static boolean locationIsProduct(String path) {
18283        try {
18284            return path.startsWith(Environment.getProductDirectory().getCanonicalPath());
18285        } catch (IOException e) {
18286            Slog.e(TAG, "Unable to access code path " + path);
18287        }
18288        return false;
18289    }
18290
18291    /*
18292     * Tries to delete system package.
18293     */
18294    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18295            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18296            boolean writeSettings) {
18297        if (deletedPs.parentPackageName != null) {
18298            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18299            return false;
18300        }
18301
18302        final boolean applyUserRestrictions
18303                = (allUserHandles != null) && (outInfo.origUsers != null);
18304        final PackageSetting disabledPs;
18305        // Confirm if the system package has been updated
18306        // An updated system app can be deleted. This will also have to restore
18307        // the system pkg from system partition
18308        // reader
18309        synchronized (mPackages) {
18310            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18311        }
18312
18313        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18314                + " disabledPs=" + disabledPs);
18315
18316        if (disabledPs == null) {
18317            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18318            return false;
18319        } else if (DEBUG_REMOVE) {
18320            Slog.d(TAG, "Deleting system pkg from data partition");
18321        }
18322
18323        if (DEBUG_REMOVE) {
18324            if (applyUserRestrictions) {
18325                Slog.d(TAG, "Remembering install states:");
18326                for (int userId : allUserHandles) {
18327                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18328                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18329                }
18330            }
18331        }
18332
18333        // Delete the updated package
18334        outInfo.isRemovedPackageSystemUpdate = true;
18335        if (outInfo.removedChildPackages != null) {
18336            final int childCount = (deletedPs.childPackageNames != null)
18337                    ? deletedPs.childPackageNames.size() : 0;
18338            for (int i = 0; i < childCount; i++) {
18339                String childPackageName = deletedPs.childPackageNames.get(i);
18340                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18341                        .contains(childPackageName)) {
18342                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18343                            childPackageName);
18344                    if (childInfo != null) {
18345                        childInfo.isRemovedPackageSystemUpdate = true;
18346                    }
18347                }
18348            }
18349        }
18350
18351        if (disabledPs.versionCode < deletedPs.versionCode) {
18352            // Delete data for downgrades
18353            flags &= ~PackageManager.DELETE_KEEP_DATA;
18354        } else {
18355            // Preserve data by setting flag
18356            flags |= PackageManager.DELETE_KEEP_DATA;
18357        }
18358
18359        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18360                outInfo, writeSettings, disabledPs.pkg);
18361        if (!ret) {
18362            return false;
18363        }
18364
18365        // writer
18366        synchronized (mPackages) {
18367            // NOTE: The system package always needs to be enabled; even if it's for
18368            // a compressed stub. If we don't, installing the system package fails
18369            // during scan [scanning checks the disabled packages]. We will reverse
18370            // this later, after we've "installed" the stub.
18371            // Reinstate the old system package
18372            enableSystemPackageLPw(disabledPs.pkg);
18373            // Remove any native libraries from the upgraded package.
18374            removeNativeBinariesLI(deletedPs);
18375        }
18376
18377        // Install the system package
18378        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18379        try {
18380            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18381                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18382        } catch (PackageManagerException e) {
18383            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18384                    + e.getMessage());
18385            return false;
18386        } finally {
18387            if (disabledPs.pkg.isStub) {
18388                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18389            }
18390        }
18391        return true;
18392    }
18393
18394    /**
18395     * Installs a package that's already on the system partition.
18396     */
18397    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18398            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18399            @Nullable PermissionsState origPermissionState, boolean writeSettings)
18400                    throws PackageManagerException {
18401        @ParseFlags int parseFlags =
18402                mDefParseFlags
18403                | PackageParser.PARSE_MUST_BE_APK
18404                | PackageParser.PARSE_IS_SYSTEM_DIR;
18405        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18406        if (isPrivileged || locationIsPrivileged(codePathString)) {
18407            scanFlags |= SCAN_AS_PRIVILEGED;
18408        }
18409        if (locationIsOem(codePathString)) {
18410            scanFlags |= SCAN_AS_OEM;
18411        }
18412        if (locationIsVendor(codePathString)) {
18413            scanFlags |= SCAN_AS_VENDOR;
18414        }
18415        if (locationIsProduct(codePathString)) {
18416            scanFlags |= SCAN_AS_PRODUCT;
18417        }
18418
18419        final File codePath = new File(codePathString);
18420        final PackageParser.Package pkg =
18421                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18422
18423        try {
18424            // update shared libraries for the newly re-installed system package
18425            updateSharedLibrariesLPr(pkg, null);
18426        } catch (PackageManagerException e) {
18427            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18428        }
18429
18430        prepareAppDataAfterInstallLIF(pkg);
18431
18432        // writer
18433        synchronized (mPackages) {
18434            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18435
18436            // Propagate the permissions state as we do not want to drop on the floor
18437            // runtime permissions. The update permissions method below will take
18438            // care of removing obsolete permissions and grant install permissions.
18439            if (origPermissionState != null) {
18440                ps.getPermissionsState().copyFrom(origPermissionState);
18441            }
18442            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18443                    mPermissionCallback);
18444
18445            final boolean applyUserRestrictions
18446                    = (allUserHandles != null) && (origUserHandles != null);
18447            if (applyUserRestrictions) {
18448                boolean installedStateChanged = false;
18449                if (DEBUG_REMOVE) {
18450                    Slog.d(TAG, "Propagating install state across reinstall");
18451                }
18452                for (int userId : allUserHandles) {
18453                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18454                    if (DEBUG_REMOVE) {
18455                        Slog.d(TAG, "    user " + userId + " => " + installed);
18456                    }
18457                    if (installed != ps.getInstalled(userId)) {
18458                        installedStateChanged = true;
18459                    }
18460                    ps.setInstalled(installed, userId);
18461
18462                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18463                }
18464                // Regardless of writeSettings we need to ensure that this restriction
18465                // state propagation is persisted
18466                mSettings.writeAllUsersPackageRestrictionsLPr();
18467                if (installedStateChanged) {
18468                    mSettings.writeKernelMappingLPr(ps);
18469                }
18470            }
18471            // can downgrade to reader here
18472            if (writeSettings) {
18473                mSettings.writeLPr();
18474            }
18475        }
18476        return pkg;
18477    }
18478
18479    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18480            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18481            PackageRemovedInfo outInfo, boolean writeSettings,
18482            PackageParser.Package replacingPackage) {
18483        synchronized (mPackages) {
18484            if (outInfo != null) {
18485                outInfo.uid = ps.appId;
18486            }
18487
18488            if (outInfo != null && outInfo.removedChildPackages != null) {
18489                final int childCount = (ps.childPackageNames != null)
18490                        ? ps.childPackageNames.size() : 0;
18491                for (int i = 0; i < childCount; i++) {
18492                    String childPackageName = ps.childPackageNames.get(i);
18493                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18494                    if (childPs == null) {
18495                        return false;
18496                    }
18497                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18498                            childPackageName);
18499                    if (childInfo != null) {
18500                        childInfo.uid = childPs.appId;
18501                    }
18502                }
18503            }
18504        }
18505
18506        // Delete package data from internal structures and also remove data if flag is set
18507        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18508
18509        // Delete the child packages data
18510        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18511        for (int i = 0; i < childCount; i++) {
18512            PackageSetting childPs;
18513            synchronized (mPackages) {
18514                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18515            }
18516            if (childPs != null) {
18517                PackageRemovedInfo childOutInfo = (outInfo != null
18518                        && outInfo.removedChildPackages != null)
18519                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18520                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18521                        && (replacingPackage != null
18522                        && !replacingPackage.hasChildPackage(childPs.name))
18523                        ? flags & ~DELETE_KEEP_DATA : flags;
18524                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18525                        deleteFlags, writeSettings);
18526            }
18527        }
18528
18529        // Delete application code and resources only for parent packages
18530        if (ps.parentPackageName == null) {
18531            if (deleteCodeAndResources && (outInfo != null)) {
18532                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18533                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18534                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18535            }
18536        }
18537
18538        return true;
18539    }
18540
18541    @Override
18542    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18543            int userId) {
18544        mContext.enforceCallingOrSelfPermission(
18545                android.Manifest.permission.DELETE_PACKAGES, null);
18546        synchronized (mPackages) {
18547            // Cannot block uninstall of static shared libs as they are
18548            // considered a part of the using app (emulating static linking).
18549            // Also static libs are installed always on internal storage.
18550            PackageParser.Package pkg = mPackages.get(packageName);
18551            if (pkg != null && pkg.staticSharedLibName != null) {
18552                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18553                        + " providing static shared library: " + pkg.staticSharedLibName);
18554                return false;
18555            }
18556            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18557            mSettings.writePackageRestrictionsLPr(userId);
18558        }
18559        return true;
18560    }
18561
18562    @Override
18563    public boolean getBlockUninstallForUser(String packageName, int userId) {
18564        synchronized (mPackages) {
18565            final PackageSetting ps = mSettings.mPackages.get(packageName);
18566            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18567                return false;
18568            }
18569            return mSettings.getBlockUninstallLPr(userId, packageName);
18570        }
18571    }
18572
18573    @Override
18574    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18575        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18576        synchronized (mPackages) {
18577            PackageSetting ps = mSettings.mPackages.get(packageName);
18578            if (ps == null) {
18579                Log.w(TAG, "Package doesn't exist: " + packageName);
18580                return false;
18581            }
18582            if (systemUserApp) {
18583                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18584            } else {
18585                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18586            }
18587            mSettings.writeLPr();
18588        }
18589        return true;
18590    }
18591
18592    /*
18593     * This method handles package deletion in general
18594     */
18595    private boolean deletePackageLIF(String packageName, UserHandle user,
18596            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18597            PackageRemovedInfo outInfo, boolean writeSettings,
18598            PackageParser.Package replacingPackage) {
18599        if (packageName == null) {
18600            Slog.w(TAG, "Attempt to delete null packageName.");
18601            return false;
18602        }
18603
18604        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18605
18606        PackageSetting ps;
18607        synchronized (mPackages) {
18608            ps = mSettings.mPackages.get(packageName);
18609            if (ps == null) {
18610                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18611                return false;
18612            }
18613
18614            if (ps.parentPackageName != null && (!isSystemApp(ps)
18615                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18616                if (DEBUG_REMOVE) {
18617                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18618                            + ((user == null) ? UserHandle.USER_ALL : user));
18619                }
18620                final int removedUserId = (user != null) ? user.getIdentifier()
18621                        : UserHandle.USER_ALL;
18622                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18623                    return false;
18624                }
18625                markPackageUninstalledForUserLPw(ps, user);
18626                scheduleWritePackageRestrictionsLocked(user);
18627                return true;
18628            }
18629        }
18630
18631        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18632                && user.getIdentifier() != UserHandle.USER_ALL)) {
18633            // The caller is asking that the package only be deleted for a single
18634            // user.  To do this, we just mark its uninstalled state and delete
18635            // its data. If this is a system app, we only allow this to happen if
18636            // they have set the special DELETE_SYSTEM_APP which requests different
18637            // semantics than normal for uninstalling system apps.
18638            markPackageUninstalledForUserLPw(ps, user);
18639
18640            if (!isSystemApp(ps)) {
18641                // Do not uninstall the APK if an app should be cached
18642                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18643                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18644                    // Other user still have this package installed, so all
18645                    // we need to do is clear this user's data and save that
18646                    // it is uninstalled.
18647                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18648                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18649                        return false;
18650                    }
18651                    scheduleWritePackageRestrictionsLocked(user);
18652                    return true;
18653                } else {
18654                    // We need to set it back to 'installed' so the uninstall
18655                    // broadcasts will be sent correctly.
18656                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18657                    ps.setInstalled(true, user.getIdentifier());
18658                    mSettings.writeKernelMappingLPr(ps);
18659                }
18660            } else {
18661                // This is a system app, so we assume that the
18662                // other users still have this package installed, so all
18663                // we need to do is clear this user's data and save that
18664                // it is uninstalled.
18665                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18666                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18667                    return false;
18668                }
18669                scheduleWritePackageRestrictionsLocked(user);
18670                return true;
18671            }
18672        }
18673
18674        // If we are deleting a composite package for all users, keep track
18675        // of result for each child.
18676        if (ps.childPackageNames != null && outInfo != null) {
18677            synchronized (mPackages) {
18678                final int childCount = ps.childPackageNames.size();
18679                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18680                for (int i = 0; i < childCount; i++) {
18681                    String childPackageName = ps.childPackageNames.get(i);
18682                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18683                    childInfo.removedPackage = childPackageName;
18684                    childInfo.installerPackageName = ps.installerPackageName;
18685                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18686                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18687                    if (childPs != null) {
18688                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18689                    }
18690                }
18691            }
18692        }
18693
18694        boolean ret = false;
18695        if (isSystemApp(ps)) {
18696            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18697            // When an updated system application is deleted we delete the existing resources
18698            // as well and fall back to existing code in system partition
18699            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18700        } else {
18701            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18702            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18703                    outInfo, writeSettings, replacingPackage);
18704        }
18705
18706        // Take a note whether we deleted the package for all users
18707        if (outInfo != null) {
18708            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18709            if (outInfo.removedChildPackages != null) {
18710                synchronized (mPackages) {
18711                    final int childCount = outInfo.removedChildPackages.size();
18712                    for (int i = 0; i < childCount; i++) {
18713                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18714                        if (childInfo != null) {
18715                            childInfo.removedForAllUsers = mPackages.get(
18716                                    childInfo.removedPackage) == null;
18717                        }
18718                    }
18719                }
18720            }
18721            // If we uninstalled an update to a system app there may be some
18722            // child packages that appeared as they are declared in the system
18723            // app but were not declared in the update.
18724            if (isSystemApp(ps)) {
18725                synchronized (mPackages) {
18726                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18727                    final int childCount = (updatedPs.childPackageNames != null)
18728                            ? updatedPs.childPackageNames.size() : 0;
18729                    for (int i = 0; i < childCount; i++) {
18730                        String childPackageName = updatedPs.childPackageNames.get(i);
18731                        if (outInfo.removedChildPackages == null
18732                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18733                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18734                            if (childPs == null) {
18735                                continue;
18736                            }
18737                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18738                            installRes.name = childPackageName;
18739                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18740                            installRes.pkg = mPackages.get(childPackageName);
18741                            installRes.uid = childPs.pkg.applicationInfo.uid;
18742                            if (outInfo.appearedChildPackages == null) {
18743                                outInfo.appearedChildPackages = new ArrayMap<>();
18744                            }
18745                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18746                        }
18747                    }
18748                }
18749            }
18750        }
18751
18752        return ret;
18753    }
18754
18755    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18756        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18757                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18758        for (int nextUserId : userIds) {
18759            if (DEBUG_REMOVE) {
18760                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18761            }
18762            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18763                    false /*installed*/,
18764                    true /*stopped*/,
18765                    true /*notLaunched*/,
18766                    false /*hidden*/,
18767                    false /*suspended*/,
18768                    false /*instantApp*/,
18769                    false /*virtualPreload*/,
18770                    null /*lastDisableAppCaller*/,
18771                    null /*enabledComponents*/,
18772                    null /*disabledComponents*/,
18773                    ps.readUserState(nextUserId).domainVerificationStatus,
18774                    0, PackageManager.INSTALL_REASON_UNKNOWN,
18775                    null /*harmfulAppWarning*/);
18776        }
18777        mSettings.writeKernelMappingLPr(ps);
18778    }
18779
18780    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18781            PackageRemovedInfo outInfo) {
18782        final PackageParser.Package pkg;
18783        synchronized (mPackages) {
18784            pkg = mPackages.get(ps.name);
18785        }
18786
18787        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18788                : new int[] {userId};
18789        for (int nextUserId : userIds) {
18790            if (DEBUG_REMOVE) {
18791                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18792                        + nextUserId);
18793            }
18794
18795            destroyAppDataLIF(pkg, userId,
18796                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18797            destroyAppProfilesLIF(pkg, userId);
18798            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18799            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18800            schedulePackageCleaning(ps.name, nextUserId, false);
18801            synchronized (mPackages) {
18802                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18803                    scheduleWritePackageRestrictionsLocked(nextUserId);
18804                }
18805                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18806            }
18807        }
18808
18809        if (outInfo != null) {
18810            outInfo.removedPackage = ps.name;
18811            outInfo.installerPackageName = ps.installerPackageName;
18812            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18813            outInfo.removedAppId = ps.appId;
18814            outInfo.removedUsers = userIds;
18815            outInfo.broadcastUsers = userIds;
18816        }
18817
18818        return true;
18819    }
18820
18821    private static final class ClearStorageConnection implements ServiceConnection {
18822        IMediaContainerService mContainerService;
18823
18824        @Override
18825        public void onServiceConnected(ComponentName name, IBinder service) {
18826            synchronized (this) {
18827                mContainerService = IMediaContainerService.Stub
18828                        .asInterface(Binder.allowBlocking(service));
18829                notifyAll();
18830            }
18831        }
18832
18833        @Override
18834        public void onServiceDisconnected(ComponentName name) {
18835        }
18836    }
18837
18838    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18839        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18840
18841        final boolean mounted;
18842        if (Environment.isExternalStorageEmulated()) {
18843            mounted = true;
18844        } else {
18845            final String status = Environment.getExternalStorageState();
18846
18847            mounted = status.equals(Environment.MEDIA_MOUNTED)
18848                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18849        }
18850
18851        if (!mounted) {
18852            return;
18853        }
18854
18855        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18856        int[] users;
18857        if (userId == UserHandle.USER_ALL) {
18858            users = sUserManager.getUserIds();
18859        } else {
18860            users = new int[] { userId };
18861        }
18862        final ClearStorageConnection conn = new ClearStorageConnection();
18863        if (mContext.bindServiceAsUser(
18864                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18865            try {
18866                for (int curUser : users) {
18867                    long timeout = SystemClock.uptimeMillis() + 5000;
18868                    synchronized (conn) {
18869                        long now;
18870                        while (conn.mContainerService == null &&
18871                                (now = SystemClock.uptimeMillis()) < timeout) {
18872                            try {
18873                                conn.wait(timeout - now);
18874                            } catch (InterruptedException e) {
18875                            }
18876                        }
18877                    }
18878                    if (conn.mContainerService == null) {
18879                        return;
18880                    }
18881
18882                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18883                    clearDirectory(conn.mContainerService,
18884                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18885                    if (allData) {
18886                        clearDirectory(conn.mContainerService,
18887                                userEnv.buildExternalStorageAppDataDirs(packageName));
18888                        clearDirectory(conn.mContainerService,
18889                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18890                    }
18891                }
18892            } finally {
18893                mContext.unbindService(conn);
18894            }
18895        }
18896    }
18897
18898    @Override
18899    public void clearApplicationProfileData(String packageName) {
18900        enforceSystemOrRoot("Only the system can clear all profile data");
18901
18902        final PackageParser.Package pkg;
18903        synchronized (mPackages) {
18904            pkg = mPackages.get(packageName);
18905        }
18906
18907        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18908            synchronized (mInstallLock) {
18909                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18910            }
18911        }
18912    }
18913
18914    @Override
18915    public void clearApplicationUserData(final String packageName,
18916            final IPackageDataObserver observer, final int userId) {
18917        mContext.enforceCallingOrSelfPermission(
18918                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18919
18920        final int callingUid = Binder.getCallingUid();
18921        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18922                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18923
18924        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18925        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18926        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18927            throw new SecurityException("Cannot clear data for a protected package: "
18928                    + packageName);
18929        }
18930        // Queue up an async operation since the package deletion may take a little while.
18931        mHandler.post(new Runnable() {
18932            public void run() {
18933                mHandler.removeCallbacks(this);
18934                final boolean succeeded;
18935                if (!filterApp) {
18936                    try (PackageFreezer freezer = freezePackage(packageName,
18937                            "clearApplicationUserData")) {
18938                        synchronized (mInstallLock) {
18939                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18940                        }
18941                        clearExternalStorageDataSync(packageName, userId, true);
18942                        synchronized (mPackages) {
18943                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18944                                    packageName, userId);
18945                        }
18946                    }
18947                    if (succeeded) {
18948                        // invoke DeviceStorageMonitor's update method to clear any notifications
18949                        DeviceStorageMonitorInternal dsm = LocalServices
18950                                .getService(DeviceStorageMonitorInternal.class);
18951                        if (dsm != null) {
18952                            dsm.checkMemory();
18953                        }
18954                    }
18955                } else {
18956                    succeeded = false;
18957                }
18958                if (observer != null) {
18959                    try {
18960                        observer.onRemoveCompleted(packageName, succeeded);
18961                    } catch (RemoteException e) {
18962                        Log.i(TAG, "Observer no longer exists.");
18963                    }
18964                } //end if observer
18965            } //end run
18966        });
18967    }
18968
18969    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18970        if (packageName == null) {
18971            Slog.w(TAG, "Attempt to delete null packageName.");
18972            return false;
18973        }
18974
18975        // Try finding details about the requested package
18976        PackageParser.Package pkg;
18977        synchronized (mPackages) {
18978            pkg = mPackages.get(packageName);
18979            if (pkg == null) {
18980                final PackageSetting ps = mSettings.mPackages.get(packageName);
18981                if (ps != null) {
18982                    pkg = ps.pkg;
18983                }
18984            }
18985
18986            if (pkg == null) {
18987                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18988                return false;
18989            }
18990
18991            PackageSetting ps = (PackageSetting) pkg.mExtras;
18992            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18993        }
18994
18995        clearAppDataLIF(pkg, userId,
18996                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18997
18998        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18999        removeKeystoreDataIfNeeded(userId, appId);
19000
19001        UserManagerInternal umInternal = getUserManagerInternal();
19002        final int flags;
19003        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19004            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19005        } else if (umInternal.isUserRunning(userId)) {
19006            flags = StorageManager.FLAG_STORAGE_DE;
19007        } else {
19008            flags = 0;
19009        }
19010        prepareAppDataContentsLIF(pkg, userId, flags);
19011
19012        return true;
19013    }
19014
19015    /**
19016     * Reverts user permission state changes (permissions and flags) in
19017     * all packages for a given user.
19018     *
19019     * @param userId The device user for which to do a reset.
19020     */
19021    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19022        final int packageCount = mPackages.size();
19023        for (int i = 0; i < packageCount; i++) {
19024            PackageParser.Package pkg = mPackages.valueAt(i);
19025            PackageSetting ps = (PackageSetting) pkg.mExtras;
19026            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19027        }
19028    }
19029
19030    private void resetNetworkPolicies(int userId) {
19031        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19032    }
19033
19034    /**
19035     * Reverts user permission state changes (permissions and flags).
19036     *
19037     * @param ps The package for which to reset.
19038     * @param userId The device user for which to do a reset.
19039     */
19040    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19041            final PackageSetting ps, final int userId) {
19042        if (ps.pkg == null) {
19043            return;
19044        }
19045
19046        // These are flags that can change base on user actions.
19047        final int userSettableMask = FLAG_PERMISSION_USER_SET
19048                | FLAG_PERMISSION_USER_FIXED
19049                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19050                | FLAG_PERMISSION_REVIEW_REQUIRED;
19051
19052        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19053                | FLAG_PERMISSION_POLICY_FIXED;
19054
19055        boolean writeInstallPermissions = false;
19056        boolean writeRuntimePermissions = false;
19057
19058        final int permissionCount = ps.pkg.requestedPermissions.size();
19059        for (int i = 0; i < permissionCount; i++) {
19060            final String permName = ps.pkg.requestedPermissions.get(i);
19061            final BasePermission bp =
19062                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19063            if (bp == null) {
19064                continue;
19065            }
19066
19067            // If shared user we just reset the state to which only this app contributed.
19068            if (ps.sharedUser != null) {
19069                boolean used = false;
19070                final int packageCount = ps.sharedUser.packages.size();
19071                for (int j = 0; j < packageCount; j++) {
19072                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19073                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19074                            && pkg.pkg.requestedPermissions.contains(permName)) {
19075                        used = true;
19076                        break;
19077                    }
19078                }
19079                if (used) {
19080                    continue;
19081                }
19082            }
19083
19084            final PermissionsState permissionsState = ps.getPermissionsState();
19085
19086            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
19087
19088            // Always clear the user settable flags.
19089            final boolean hasInstallState =
19090                    permissionsState.getInstallPermissionState(permName) != null;
19091            // If permission review is enabled and this is a legacy app, mark the
19092            // permission as requiring a review as this is the initial state.
19093            int flags = 0;
19094            if (mSettings.mPermissions.mPermissionReviewRequired
19095                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19096                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19097            }
19098            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19099                if (hasInstallState) {
19100                    writeInstallPermissions = true;
19101                } else {
19102                    writeRuntimePermissions = true;
19103                }
19104            }
19105
19106            // Below is only runtime permission handling.
19107            if (!bp.isRuntime()) {
19108                continue;
19109            }
19110
19111            // Never clobber system or policy.
19112            if ((oldFlags & policyOrSystemFlags) != 0) {
19113                continue;
19114            }
19115
19116            // If this permission was granted by default, make sure it is.
19117            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19118                if (permissionsState.grantRuntimePermission(bp, userId)
19119                        != PERMISSION_OPERATION_FAILURE) {
19120                    writeRuntimePermissions = true;
19121                }
19122            // If permission review is enabled the permissions for a legacy apps
19123            // are represented as constantly granted runtime ones, so don't revoke.
19124            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19125                // Otherwise, reset the permission.
19126                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19127                switch (revokeResult) {
19128                    case PERMISSION_OPERATION_SUCCESS:
19129                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19130                        writeRuntimePermissions = true;
19131                        final int appId = ps.appId;
19132                        mHandler.post(new Runnable() {
19133                            @Override
19134                            public void run() {
19135                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19136                            }
19137                        });
19138                    } break;
19139                }
19140            }
19141        }
19142
19143        // Synchronously write as we are taking permissions away.
19144        if (writeRuntimePermissions) {
19145            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19146        }
19147
19148        // Synchronously write as we are taking permissions away.
19149        if (writeInstallPermissions) {
19150            mSettings.writeLPr();
19151        }
19152    }
19153
19154    /**
19155     * Remove entries from the keystore daemon. Will only remove it if the
19156     * {@code appId} is valid.
19157     */
19158    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19159        if (appId < 0) {
19160            return;
19161        }
19162
19163        final KeyStore keyStore = KeyStore.getInstance();
19164        if (keyStore != null) {
19165            if (userId == UserHandle.USER_ALL) {
19166                for (final int individual : sUserManager.getUserIds()) {
19167                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19168                }
19169            } else {
19170                keyStore.clearUid(UserHandle.getUid(userId, appId));
19171            }
19172        } else {
19173            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19174        }
19175    }
19176
19177    @Override
19178    public void deleteApplicationCacheFiles(final String packageName,
19179            final IPackageDataObserver observer) {
19180        final int userId = UserHandle.getCallingUserId();
19181        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19182    }
19183
19184    @Override
19185    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19186            final IPackageDataObserver observer) {
19187        final int callingUid = Binder.getCallingUid();
19188        if (mContext.checkCallingOrSelfPermission(
19189                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
19190                != PackageManager.PERMISSION_GRANTED) {
19191            // If the caller has the old delete cache permission, silently ignore.  Else throw.
19192            if (mContext.checkCallingOrSelfPermission(
19193                    android.Manifest.permission.DELETE_CACHE_FILES)
19194                    == PackageManager.PERMISSION_GRANTED) {
19195                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
19196                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
19197                        ", silently ignoring");
19198                return;
19199            }
19200            mContext.enforceCallingOrSelfPermission(
19201                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
19202        }
19203        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19204                /* requireFullPermission= */ true, /* checkShell= */ false,
19205                "delete application cache files");
19206        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19207                android.Manifest.permission.ACCESS_INSTANT_APPS);
19208
19209        final PackageParser.Package pkg;
19210        synchronized (mPackages) {
19211            pkg = mPackages.get(packageName);
19212        }
19213
19214        // Queue up an async operation since the package deletion may take a little while.
19215        mHandler.post(new Runnable() {
19216            public void run() {
19217                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
19218                boolean doClearData = true;
19219                if (ps != null) {
19220                    final boolean targetIsInstantApp =
19221                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19222                    doClearData = !targetIsInstantApp
19223                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
19224                }
19225                if (doClearData) {
19226                    synchronized (mInstallLock) {
19227                        final int flags = StorageManager.FLAG_STORAGE_DE
19228                                | StorageManager.FLAG_STORAGE_CE;
19229                        // We're only clearing cache files, so we don't care if the
19230                        // app is unfrozen and still able to run
19231                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19232                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19233                    }
19234                    clearExternalStorageDataSync(packageName, userId, false);
19235                }
19236                if (observer != null) {
19237                    try {
19238                        observer.onRemoveCompleted(packageName, true);
19239                    } catch (RemoteException e) {
19240                        Log.i(TAG, "Observer no longer exists.");
19241                    }
19242                }
19243            }
19244        });
19245    }
19246
19247    @Override
19248    public void getPackageSizeInfo(final String packageName, int userHandle,
19249            final IPackageStatsObserver observer) {
19250        throw new UnsupportedOperationException(
19251                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19252    }
19253
19254    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19255        final PackageSetting ps;
19256        synchronized (mPackages) {
19257            ps = mSettings.mPackages.get(packageName);
19258            if (ps == null) {
19259                Slog.w(TAG, "Failed to find settings for " + packageName);
19260                return false;
19261            }
19262        }
19263
19264        final String[] packageNames = { packageName };
19265        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19266        final String[] codePaths = { ps.codePathString };
19267
19268        try {
19269            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19270                    ps.appId, ceDataInodes, codePaths, stats);
19271
19272            // For now, ignore code size of packages on system partition
19273            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19274                stats.codeSize = 0;
19275            }
19276
19277            // External clients expect these to be tracked separately
19278            stats.dataSize -= stats.cacheSize;
19279
19280        } catch (InstallerException e) {
19281            Slog.w(TAG, String.valueOf(e));
19282            return false;
19283        }
19284
19285        return true;
19286    }
19287
19288    private int getUidTargetSdkVersionLockedLPr(int uid) {
19289        Object obj = mSettings.getUserIdLPr(uid);
19290        if (obj instanceof SharedUserSetting) {
19291            final SharedUserSetting sus = (SharedUserSetting) obj;
19292            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19293            final Iterator<PackageSetting> it = sus.packages.iterator();
19294            while (it.hasNext()) {
19295                final PackageSetting ps = it.next();
19296                if (ps.pkg != null) {
19297                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19298                    if (v < vers) vers = v;
19299                }
19300            }
19301            return vers;
19302        } else if (obj instanceof PackageSetting) {
19303            final PackageSetting ps = (PackageSetting) obj;
19304            if (ps.pkg != null) {
19305                return ps.pkg.applicationInfo.targetSdkVersion;
19306            }
19307        }
19308        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19309    }
19310
19311    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
19312        final PackageParser.Package p = mPackages.get(packageName);
19313        if (p != null) {
19314            return p.applicationInfo.targetSdkVersion;
19315        }
19316        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19317    }
19318
19319    @Override
19320    public void addPreferredActivity(IntentFilter filter, int match,
19321            ComponentName[] set, ComponentName activity, int userId) {
19322        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19323                "Adding preferred");
19324    }
19325
19326    private void addPreferredActivityInternal(IntentFilter filter, int match,
19327            ComponentName[] set, ComponentName activity, boolean always, int userId,
19328            String opname) {
19329        // writer
19330        int callingUid = Binder.getCallingUid();
19331        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19332                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19333        if (filter.countActions() == 0) {
19334            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19335            return;
19336        }
19337        synchronized (mPackages) {
19338            if (mContext.checkCallingOrSelfPermission(
19339                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19340                    != PackageManager.PERMISSION_GRANTED) {
19341                if (getUidTargetSdkVersionLockedLPr(callingUid)
19342                        < Build.VERSION_CODES.FROYO) {
19343                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19344                            + callingUid);
19345                    return;
19346                }
19347                mContext.enforceCallingOrSelfPermission(
19348                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19349            }
19350
19351            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19352            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19353                    + userId + ":");
19354            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19355            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19356            scheduleWritePackageRestrictionsLocked(userId);
19357            postPreferredActivityChangedBroadcast(userId);
19358        }
19359    }
19360
19361    private void postPreferredActivityChangedBroadcast(int userId) {
19362        mHandler.post(() -> {
19363            final IActivityManager am = ActivityManager.getService();
19364            if (am == null) {
19365                return;
19366            }
19367
19368            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19369            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19370            try {
19371                am.broadcastIntent(null, intent, null, null,
19372                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19373                        null, false, false, userId);
19374            } catch (RemoteException e) {
19375            }
19376        });
19377    }
19378
19379    @Override
19380    public void replacePreferredActivity(IntentFilter filter, int match,
19381            ComponentName[] set, ComponentName activity, int userId) {
19382        if (filter.countActions() != 1) {
19383            throw new IllegalArgumentException(
19384                    "replacePreferredActivity expects filter to have only 1 action.");
19385        }
19386        if (filter.countDataAuthorities() != 0
19387                || filter.countDataPaths() != 0
19388                || filter.countDataSchemes() > 1
19389                || filter.countDataTypes() != 0) {
19390            throw new IllegalArgumentException(
19391                    "replacePreferredActivity expects filter to have no data authorities, " +
19392                    "paths, or types; and at most one scheme.");
19393        }
19394
19395        final int callingUid = Binder.getCallingUid();
19396        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19397                true /* requireFullPermission */, false /* checkShell */,
19398                "replace preferred activity");
19399        synchronized (mPackages) {
19400            if (mContext.checkCallingOrSelfPermission(
19401                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19402                    != PackageManager.PERMISSION_GRANTED) {
19403                if (getUidTargetSdkVersionLockedLPr(callingUid)
19404                        < Build.VERSION_CODES.FROYO) {
19405                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19406                            + Binder.getCallingUid());
19407                    return;
19408                }
19409                mContext.enforceCallingOrSelfPermission(
19410                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19411            }
19412
19413            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19414            if (pir != null) {
19415                // Get all of the existing entries that exactly match this filter.
19416                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19417                if (existing != null && existing.size() == 1) {
19418                    PreferredActivity cur = existing.get(0);
19419                    if (DEBUG_PREFERRED) {
19420                        Slog.i(TAG, "Checking replace of preferred:");
19421                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19422                        if (!cur.mPref.mAlways) {
19423                            Slog.i(TAG, "  -- CUR; not mAlways!");
19424                        } else {
19425                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19426                            Slog.i(TAG, "  -- CUR: mSet="
19427                                    + Arrays.toString(cur.mPref.mSetComponents));
19428                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19429                            Slog.i(TAG, "  -- NEW: mMatch="
19430                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19431                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19432                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19433                        }
19434                    }
19435                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19436                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19437                            && cur.mPref.sameSet(set)) {
19438                        // Setting the preferred activity to what it happens to be already
19439                        if (DEBUG_PREFERRED) {
19440                            Slog.i(TAG, "Replacing with same preferred activity "
19441                                    + cur.mPref.mShortComponent + " for user "
19442                                    + userId + ":");
19443                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19444                        }
19445                        return;
19446                    }
19447                }
19448
19449                if (existing != null) {
19450                    if (DEBUG_PREFERRED) {
19451                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19452                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19453                    }
19454                    for (int i = 0; i < existing.size(); i++) {
19455                        PreferredActivity pa = existing.get(i);
19456                        if (DEBUG_PREFERRED) {
19457                            Slog.i(TAG, "Removing existing preferred activity "
19458                                    + pa.mPref.mComponent + ":");
19459                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19460                        }
19461                        pir.removeFilter(pa);
19462                    }
19463                }
19464            }
19465            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19466                    "Replacing preferred");
19467        }
19468    }
19469
19470    @Override
19471    public void clearPackagePreferredActivities(String packageName) {
19472        final int callingUid = Binder.getCallingUid();
19473        if (getInstantAppPackageName(callingUid) != null) {
19474            return;
19475        }
19476        // writer
19477        synchronized (mPackages) {
19478            PackageParser.Package pkg = mPackages.get(packageName);
19479            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19480                if (mContext.checkCallingOrSelfPermission(
19481                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19482                        != PackageManager.PERMISSION_GRANTED) {
19483                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19484                            < Build.VERSION_CODES.FROYO) {
19485                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19486                                + callingUid);
19487                        return;
19488                    }
19489                    mContext.enforceCallingOrSelfPermission(
19490                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19491                }
19492            }
19493            final PackageSetting ps = mSettings.getPackageLPr(packageName);
19494            if (ps != null
19495                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19496                return;
19497            }
19498            int user = UserHandle.getCallingUserId();
19499            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19500                scheduleWritePackageRestrictionsLocked(user);
19501            }
19502        }
19503    }
19504
19505    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19506    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19507        ArrayList<PreferredActivity> removed = null;
19508        boolean changed = false;
19509        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19510            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19511            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19512            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19513                continue;
19514            }
19515            Iterator<PreferredActivity> it = pir.filterIterator();
19516            while (it.hasNext()) {
19517                PreferredActivity pa = it.next();
19518                // Mark entry for removal only if it matches the package name
19519                // and the entry is of type "always".
19520                if (packageName == null ||
19521                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19522                                && pa.mPref.mAlways)) {
19523                    if (removed == null) {
19524                        removed = new ArrayList<PreferredActivity>();
19525                    }
19526                    removed.add(pa);
19527                }
19528            }
19529            if (removed != null) {
19530                for (int j=0; j<removed.size(); j++) {
19531                    PreferredActivity pa = removed.get(j);
19532                    pir.removeFilter(pa);
19533                }
19534                changed = true;
19535            }
19536        }
19537        if (changed) {
19538            postPreferredActivityChangedBroadcast(userId);
19539        }
19540        return changed;
19541    }
19542
19543    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19544    private void clearIntentFilterVerificationsLPw(int userId) {
19545        final int packageCount = mPackages.size();
19546        for (int i = 0; i < packageCount; i++) {
19547            PackageParser.Package pkg = mPackages.valueAt(i);
19548            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19549        }
19550    }
19551
19552    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19553    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19554        if (userId == UserHandle.USER_ALL) {
19555            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19556                    sUserManager.getUserIds())) {
19557                for (int oneUserId : sUserManager.getUserIds()) {
19558                    scheduleWritePackageRestrictionsLocked(oneUserId);
19559                }
19560            }
19561        } else {
19562            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19563                scheduleWritePackageRestrictionsLocked(userId);
19564            }
19565        }
19566    }
19567
19568    /** Clears state for all users, and touches intent filter verification policy */
19569    void clearDefaultBrowserIfNeeded(String packageName) {
19570        for (int oneUserId : sUserManager.getUserIds()) {
19571            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19572        }
19573    }
19574
19575    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19576        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19577        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19578            if (packageName.equals(defaultBrowserPackageName)) {
19579                setDefaultBrowserPackageName(null, userId);
19580            }
19581        }
19582    }
19583
19584    @Override
19585    public void resetApplicationPreferences(int userId) {
19586        mContext.enforceCallingOrSelfPermission(
19587                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19588        final long identity = Binder.clearCallingIdentity();
19589        // writer
19590        try {
19591            synchronized (mPackages) {
19592                clearPackagePreferredActivitiesLPw(null, userId);
19593                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19594                // TODO: We have to reset the default SMS and Phone. This requires
19595                // significant refactoring to keep all default apps in the package
19596                // manager (cleaner but more work) or have the services provide
19597                // callbacks to the package manager to request a default app reset.
19598                applyFactoryDefaultBrowserLPw(userId);
19599                clearIntentFilterVerificationsLPw(userId);
19600                primeDomainVerificationsLPw(userId);
19601                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19602                scheduleWritePackageRestrictionsLocked(userId);
19603            }
19604            resetNetworkPolicies(userId);
19605        } finally {
19606            Binder.restoreCallingIdentity(identity);
19607        }
19608    }
19609
19610    @Override
19611    public int getPreferredActivities(List<IntentFilter> outFilters,
19612            List<ComponentName> outActivities, String packageName) {
19613        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19614            return 0;
19615        }
19616        int num = 0;
19617        final int userId = UserHandle.getCallingUserId();
19618        // reader
19619        synchronized (mPackages) {
19620            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19621            if (pir != null) {
19622                final Iterator<PreferredActivity> it = pir.filterIterator();
19623                while (it.hasNext()) {
19624                    final PreferredActivity pa = it.next();
19625                    if (packageName == null
19626                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19627                                    && pa.mPref.mAlways)) {
19628                        if (outFilters != null) {
19629                            outFilters.add(new IntentFilter(pa));
19630                        }
19631                        if (outActivities != null) {
19632                            outActivities.add(pa.mPref.mComponent);
19633                        }
19634                    }
19635                }
19636            }
19637        }
19638
19639        return num;
19640    }
19641
19642    @Override
19643    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19644            int userId) {
19645        int callingUid = Binder.getCallingUid();
19646        if (callingUid != Process.SYSTEM_UID) {
19647            throw new SecurityException(
19648                    "addPersistentPreferredActivity can only be run by the system");
19649        }
19650        if (filter.countActions() == 0) {
19651            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19652            return;
19653        }
19654        synchronized (mPackages) {
19655            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19656                    ":");
19657            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19658            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19659                    new PersistentPreferredActivity(filter, activity));
19660            scheduleWritePackageRestrictionsLocked(userId);
19661            postPreferredActivityChangedBroadcast(userId);
19662        }
19663    }
19664
19665    @Override
19666    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19667        int callingUid = Binder.getCallingUid();
19668        if (callingUid != Process.SYSTEM_UID) {
19669            throw new SecurityException(
19670                    "clearPackagePersistentPreferredActivities can only be run by the system");
19671        }
19672        ArrayList<PersistentPreferredActivity> removed = null;
19673        boolean changed = false;
19674        synchronized (mPackages) {
19675            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19676                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19677                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19678                        .valueAt(i);
19679                if (userId != thisUserId) {
19680                    continue;
19681                }
19682                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19683                while (it.hasNext()) {
19684                    PersistentPreferredActivity ppa = it.next();
19685                    // Mark entry for removal only if it matches the package name.
19686                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19687                        if (removed == null) {
19688                            removed = new ArrayList<PersistentPreferredActivity>();
19689                        }
19690                        removed.add(ppa);
19691                    }
19692                }
19693                if (removed != null) {
19694                    for (int j=0; j<removed.size(); j++) {
19695                        PersistentPreferredActivity ppa = removed.get(j);
19696                        ppir.removeFilter(ppa);
19697                    }
19698                    changed = true;
19699                }
19700            }
19701
19702            if (changed) {
19703                scheduleWritePackageRestrictionsLocked(userId);
19704                postPreferredActivityChangedBroadcast(userId);
19705            }
19706        }
19707    }
19708
19709    /**
19710     * Common machinery for picking apart a restored XML blob and passing
19711     * it to a caller-supplied functor to be applied to the running system.
19712     */
19713    private void restoreFromXml(XmlPullParser parser, int userId,
19714            String expectedStartTag, BlobXmlRestorer functor)
19715            throws IOException, XmlPullParserException {
19716        int type;
19717        while ((type = parser.next()) != XmlPullParser.START_TAG
19718                && type != XmlPullParser.END_DOCUMENT) {
19719        }
19720        if (type != XmlPullParser.START_TAG) {
19721            // oops didn't find a start tag?!
19722            if (DEBUG_BACKUP) {
19723                Slog.e(TAG, "Didn't find start tag during restore");
19724            }
19725            return;
19726        }
19727Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19728        // this is supposed to be TAG_PREFERRED_BACKUP
19729        if (!expectedStartTag.equals(parser.getName())) {
19730            if (DEBUG_BACKUP) {
19731                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19732            }
19733            return;
19734        }
19735
19736        // skip interfering stuff, then we're aligned with the backing implementation
19737        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19738Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19739        functor.apply(parser, userId);
19740    }
19741
19742    private interface BlobXmlRestorer {
19743        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19744    }
19745
19746    /**
19747     * Non-Binder method, support for the backup/restore mechanism: write the
19748     * full set of preferred activities in its canonical XML format.  Returns the
19749     * XML output as a byte array, or null if there is none.
19750     */
19751    @Override
19752    public byte[] getPreferredActivityBackup(int userId) {
19753        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19754            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19755        }
19756
19757        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19758        try {
19759            final XmlSerializer serializer = new FastXmlSerializer();
19760            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19761            serializer.startDocument(null, true);
19762            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19763
19764            synchronized (mPackages) {
19765                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19766            }
19767
19768            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19769            serializer.endDocument();
19770            serializer.flush();
19771        } catch (Exception e) {
19772            if (DEBUG_BACKUP) {
19773                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19774            }
19775            return null;
19776        }
19777
19778        return dataStream.toByteArray();
19779    }
19780
19781    @Override
19782    public void restorePreferredActivities(byte[] backup, int userId) {
19783        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19784            throw new SecurityException("Only the system may call restorePreferredActivities()");
19785        }
19786
19787        try {
19788            final XmlPullParser parser = Xml.newPullParser();
19789            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19790            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19791                    new BlobXmlRestorer() {
19792                        @Override
19793                        public void apply(XmlPullParser parser, int userId)
19794                                throws XmlPullParserException, IOException {
19795                            synchronized (mPackages) {
19796                                mSettings.readPreferredActivitiesLPw(parser, userId);
19797                            }
19798                        }
19799                    } );
19800        } catch (Exception e) {
19801            if (DEBUG_BACKUP) {
19802                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19803            }
19804        }
19805    }
19806
19807    /**
19808     * Non-Binder method, support for the backup/restore mechanism: write the
19809     * default browser (etc) settings in its canonical XML format.  Returns the default
19810     * browser XML representation as a byte array, or null if there is none.
19811     */
19812    @Override
19813    public byte[] getDefaultAppsBackup(int userId) {
19814        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19815            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19816        }
19817
19818        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19819        try {
19820            final XmlSerializer serializer = new FastXmlSerializer();
19821            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19822            serializer.startDocument(null, true);
19823            serializer.startTag(null, TAG_DEFAULT_APPS);
19824
19825            synchronized (mPackages) {
19826                mSettings.writeDefaultAppsLPr(serializer, userId);
19827            }
19828
19829            serializer.endTag(null, TAG_DEFAULT_APPS);
19830            serializer.endDocument();
19831            serializer.flush();
19832        } catch (Exception e) {
19833            if (DEBUG_BACKUP) {
19834                Slog.e(TAG, "Unable to write default apps for backup", e);
19835            }
19836            return null;
19837        }
19838
19839        return dataStream.toByteArray();
19840    }
19841
19842    @Override
19843    public void restoreDefaultApps(byte[] backup, int userId) {
19844        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19845            throw new SecurityException("Only the system may call restoreDefaultApps()");
19846        }
19847
19848        try {
19849            final XmlPullParser parser = Xml.newPullParser();
19850            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19851            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19852                    new BlobXmlRestorer() {
19853                        @Override
19854                        public void apply(XmlPullParser parser, int userId)
19855                                throws XmlPullParserException, IOException {
19856                            synchronized (mPackages) {
19857                                mSettings.readDefaultAppsLPw(parser, userId);
19858                            }
19859                        }
19860                    } );
19861        } catch (Exception e) {
19862            if (DEBUG_BACKUP) {
19863                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19864            }
19865        }
19866    }
19867
19868    @Override
19869    public byte[] getIntentFilterVerificationBackup(int userId) {
19870        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19871            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19872        }
19873
19874        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19875        try {
19876            final XmlSerializer serializer = new FastXmlSerializer();
19877            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19878            serializer.startDocument(null, true);
19879            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19880
19881            synchronized (mPackages) {
19882                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19883            }
19884
19885            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19886            serializer.endDocument();
19887            serializer.flush();
19888        } catch (Exception e) {
19889            if (DEBUG_BACKUP) {
19890                Slog.e(TAG, "Unable to write default apps for backup", e);
19891            }
19892            return null;
19893        }
19894
19895        return dataStream.toByteArray();
19896    }
19897
19898    @Override
19899    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19900        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19901            throw new SecurityException("Only the system may call restorePreferredActivities()");
19902        }
19903
19904        try {
19905            final XmlPullParser parser = Xml.newPullParser();
19906            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19907            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19908                    new BlobXmlRestorer() {
19909                        @Override
19910                        public void apply(XmlPullParser parser, int userId)
19911                                throws XmlPullParserException, IOException {
19912                            synchronized (mPackages) {
19913                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19914                                mSettings.writeLPr();
19915                            }
19916                        }
19917                    } );
19918        } catch (Exception e) {
19919            if (DEBUG_BACKUP) {
19920                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19921            }
19922        }
19923    }
19924
19925    @Override
19926    public byte[] getPermissionGrantBackup(int userId) {
19927        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19928            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19929        }
19930
19931        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19932        try {
19933            final XmlSerializer serializer = new FastXmlSerializer();
19934            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19935            serializer.startDocument(null, true);
19936            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19937
19938            synchronized (mPackages) {
19939                serializeRuntimePermissionGrantsLPr(serializer, userId);
19940            }
19941
19942            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19943            serializer.endDocument();
19944            serializer.flush();
19945        } catch (Exception e) {
19946            if (DEBUG_BACKUP) {
19947                Slog.e(TAG, "Unable to write default apps for backup", e);
19948            }
19949            return null;
19950        }
19951
19952        return dataStream.toByteArray();
19953    }
19954
19955    @Override
19956    public void restorePermissionGrants(byte[] backup, int userId) {
19957        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19958            throw new SecurityException("Only the system may call restorePermissionGrants()");
19959        }
19960
19961        try {
19962            final XmlPullParser parser = Xml.newPullParser();
19963            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19964            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19965                    new BlobXmlRestorer() {
19966                        @Override
19967                        public void apply(XmlPullParser parser, int userId)
19968                                throws XmlPullParserException, IOException {
19969                            synchronized (mPackages) {
19970                                processRestoredPermissionGrantsLPr(parser, userId);
19971                            }
19972                        }
19973                    } );
19974        } catch (Exception e) {
19975            if (DEBUG_BACKUP) {
19976                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19977            }
19978        }
19979    }
19980
19981    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19982            throws IOException {
19983        serializer.startTag(null, TAG_ALL_GRANTS);
19984
19985        final int N = mSettings.mPackages.size();
19986        for (int i = 0; i < N; i++) {
19987            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19988            boolean pkgGrantsKnown = false;
19989
19990            PermissionsState packagePerms = ps.getPermissionsState();
19991
19992            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19993                final int grantFlags = state.getFlags();
19994                // only look at grants that are not system/policy fixed
19995                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19996                    final boolean isGranted = state.isGranted();
19997                    // And only back up the user-twiddled state bits
19998                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19999                        final String packageName = mSettings.mPackages.keyAt(i);
20000                        if (!pkgGrantsKnown) {
20001                            serializer.startTag(null, TAG_GRANT);
20002                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20003                            pkgGrantsKnown = true;
20004                        }
20005
20006                        final boolean userSet =
20007                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20008                        final boolean userFixed =
20009                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20010                        final boolean revoke =
20011                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20012
20013                        serializer.startTag(null, TAG_PERMISSION);
20014                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20015                        if (isGranted) {
20016                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20017                        }
20018                        if (userSet) {
20019                            serializer.attribute(null, ATTR_USER_SET, "true");
20020                        }
20021                        if (userFixed) {
20022                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20023                        }
20024                        if (revoke) {
20025                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20026                        }
20027                        serializer.endTag(null, TAG_PERMISSION);
20028                    }
20029                }
20030            }
20031
20032            if (pkgGrantsKnown) {
20033                serializer.endTag(null, TAG_GRANT);
20034            }
20035        }
20036
20037        serializer.endTag(null, TAG_ALL_GRANTS);
20038    }
20039
20040    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20041            throws XmlPullParserException, IOException {
20042        String pkgName = null;
20043        int outerDepth = parser.getDepth();
20044        int type;
20045        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20046                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20047            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20048                continue;
20049            }
20050
20051            final String tagName = parser.getName();
20052            if (tagName.equals(TAG_GRANT)) {
20053                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20054                if (DEBUG_BACKUP) {
20055                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20056                }
20057            } else if (tagName.equals(TAG_PERMISSION)) {
20058
20059                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20060                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20061
20062                int newFlagSet = 0;
20063                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20064                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20065                }
20066                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20067                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20068                }
20069                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20070                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20071                }
20072                if (DEBUG_BACKUP) {
20073                    Slog.v(TAG, "  + Restoring grant:"
20074                            + " pkg=" + pkgName
20075                            + " perm=" + permName
20076                            + " granted=" + isGranted
20077                            + " bits=0x" + Integer.toHexString(newFlagSet));
20078                }
20079                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20080                if (ps != null) {
20081                    // Already installed so we apply the grant immediately
20082                    if (DEBUG_BACKUP) {
20083                        Slog.v(TAG, "        + already installed; applying");
20084                    }
20085                    PermissionsState perms = ps.getPermissionsState();
20086                    BasePermission bp =
20087                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
20088                    if (bp != null) {
20089                        if (isGranted) {
20090                            perms.grantRuntimePermission(bp, userId);
20091                        }
20092                        if (newFlagSet != 0) {
20093                            perms.updatePermissionFlags(
20094                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20095                        }
20096                    }
20097                } else {
20098                    // Need to wait for post-restore install to apply the grant
20099                    if (DEBUG_BACKUP) {
20100                        Slog.v(TAG, "        - not yet installed; saving for later");
20101                    }
20102                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20103                            isGranted, newFlagSet, userId);
20104                }
20105            } else {
20106                PackageManagerService.reportSettingsProblem(Log.WARN,
20107                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20108                XmlUtils.skipCurrentTag(parser);
20109            }
20110        }
20111
20112        scheduleWriteSettingsLocked();
20113        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20114    }
20115
20116    @Override
20117    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20118            int sourceUserId, int targetUserId, int flags) {
20119        mContext.enforceCallingOrSelfPermission(
20120                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20121        int callingUid = Binder.getCallingUid();
20122        enforceOwnerRights(ownerPackage, callingUid);
20123        PackageManagerServiceUtils.enforceShellRestriction(
20124                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20125        if (intentFilter.countActions() == 0) {
20126            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20127            return;
20128        }
20129        synchronized (mPackages) {
20130            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20131                    ownerPackage, targetUserId, flags);
20132            CrossProfileIntentResolver resolver =
20133                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20134            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20135            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20136            if (existing != null) {
20137                int size = existing.size();
20138                for (int i = 0; i < size; i++) {
20139                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20140                        return;
20141                    }
20142                }
20143            }
20144            resolver.addFilter(newFilter);
20145            scheduleWritePackageRestrictionsLocked(sourceUserId);
20146        }
20147    }
20148
20149    @Override
20150    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20151        mContext.enforceCallingOrSelfPermission(
20152                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20153        final int callingUid = Binder.getCallingUid();
20154        enforceOwnerRights(ownerPackage, callingUid);
20155        PackageManagerServiceUtils.enforceShellRestriction(
20156                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20157        synchronized (mPackages) {
20158            CrossProfileIntentResolver resolver =
20159                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20160            ArraySet<CrossProfileIntentFilter> set =
20161                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20162            for (CrossProfileIntentFilter filter : set) {
20163                if (filter.getOwnerPackage().equals(ownerPackage)) {
20164                    resolver.removeFilter(filter);
20165                }
20166            }
20167            scheduleWritePackageRestrictionsLocked(sourceUserId);
20168        }
20169    }
20170
20171    // Enforcing that callingUid is owning pkg on userId
20172    private void enforceOwnerRights(String pkg, int callingUid) {
20173        // The system owns everything.
20174        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20175            return;
20176        }
20177        final int callingUserId = UserHandle.getUserId(callingUid);
20178        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20179        if (pi == null) {
20180            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20181                    + callingUserId);
20182        }
20183        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20184            throw new SecurityException("Calling uid " + callingUid
20185                    + " does not own package " + pkg);
20186        }
20187    }
20188
20189    @Override
20190    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20191        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20192            return null;
20193        }
20194        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20195    }
20196
20197    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20198        UserManagerService ums = UserManagerService.getInstance();
20199        if (ums != null) {
20200            final UserInfo parent = ums.getProfileParent(userId);
20201            final int launcherUid = (parent != null) ? parent.id : userId;
20202            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20203            if (launcherComponent != null) {
20204                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20205                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20206                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20207                        .setPackage(launcherComponent.getPackageName());
20208                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20209            }
20210        }
20211    }
20212
20213    /**
20214     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20215     * then reports the most likely home activity or null if there are more than one.
20216     */
20217    private ComponentName getDefaultHomeActivity(int userId) {
20218        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20219        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20220        if (cn != null) {
20221            return cn;
20222        }
20223
20224        // Find the launcher with the highest priority and return that component if there are no
20225        // other home activity with the same priority.
20226        int lastPriority = Integer.MIN_VALUE;
20227        ComponentName lastComponent = null;
20228        final int size = allHomeCandidates.size();
20229        for (int i = 0; i < size; i++) {
20230            final ResolveInfo ri = allHomeCandidates.get(i);
20231            if (ri.priority > lastPriority) {
20232                lastComponent = ri.activityInfo.getComponentName();
20233                lastPriority = ri.priority;
20234            } else if (ri.priority == lastPriority) {
20235                // Two components found with same priority.
20236                lastComponent = null;
20237            }
20238        }
20239        return lastComponent;
20240    }
20241
20242    private Intent getHomeIntent() {
20243        Intent intent = new Intent(Intent.ACTION_MAIN);
20244        intent.addCategory(Intent.CATEGORY_HOME);
20245        intent.addCategory(Intent.CATEGORY_DEFAULT);
20246        return intent;
20247    }
20248
20249    private IntentFilter getHomeFilter() {
20250        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20251        filter.addCategory(Intent.CATEGORY_HOME);
20252        filter.addCategory(Intent.CATEGORY_DEFAULT);
20253        return filter;
20254    }
20255
20256    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20257            int userId) {
20258        Intent intent  = getHomeIntent();
20259        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20260                PackageManager.GET_META_DATA, userId);
20261        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20262                true, false, false, userId);
20263
20264        allHomeCandidates.clear();
20265        if (list != null) {
20266            for (ResolveInfo ri : list) {
20267                allHomeCandidates.add(ri);
20268            }
20269        }
20270        return (preferred == null || preferred.activityInfo == null)
20271                ? null
20272                : new ComponentName(preferred.activityInfo.packageName,
20273                        preferred.activityInfo.name);
20274    }
20275
20276    @Override
20277    public void setHomeActivity(ComponentName comp, int userId) {
20278        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20279            return;
20280        }
20281        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20282        getHomeActivitiesAsUser(homeActivities, userId);
20283
20284        boolean found = false;
20285
20286        final int size = homeActivities.size();
20287        final ComponentName[] set = new ComponentName[size];
20288        for (int i = 0; i < size; i++) {
20289            final ResolveInfo candidate = homeActivities.get(i);
20290            final ActivityInfo info = candidate.activityInfo;
20291            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20292            set[i] = activityName;
20293            if (!found && activityName.equals(comp)) {
20294                found = true;
20295            }
20296        }
20297        if (!found) {
20298            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20299                    + userId);
20300        }
20301        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20302                set, comp, userId);
20303    }
20304
20305    private @Nullable String getSetupWizardPackageName() {
20306        final Intent intent = new Intent(Intent.ACTION_MAIN);
20307        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20308
20309        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20310                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20311                        | MATCH_DISABLED_COMPONENTS,
20312                UserHandle.myUserId());
20313        if (matches.size() == 1) {
20314            return matches.get(0).getComponentInfo().packageName;
20315        } else {
20316            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20317                    + ": matches=" + matches);
20318            return null;
20319        }
20320    }
20321
20322    private @Nullable String getStorageManagerPackageName() {
20323        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20324
20325        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20326                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20327                        | MATCH_DISABLED_COMPONENTS,
20328                UserHandle.myUserId());
20329        if (matches.size() == 1) {
20330            return matches.get(0).getComponentInfo().packageName;
20331        } else {
20332            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20333                    + matches.size() + ": matches=" + matches);
20334            return null;
20335        }
20336    }
20337
20338    @Override
20339    public String getSystemTextClassifierPackageName() {
20340        return mContext.getString(R.string.config_defaultTextClassifierPackage);
20341    }
20342
20343    @Override
20344    public void setApplicationEnabledSetting(String appPackageName,
20345            int newState, int flags, int userId, String callingPackage) {
20346        if (!sUserManager.exists(userId)) return;
20347        if (callingPackage == null) {
20348            callingPackage = Integer.toString(Binder.getCallingUid());
20349        }
20350        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20351    }
20352
20353    @Override
20354    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20355        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20356        synchronized (mPackages) {
20357            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20358            if (pkgSetting != null) {
20359                pkgSetting.setUpdateAvailable(updateAvailable);
20360            }
20361        }
20362    }
20363
20364    @Override
20365    public void setComponentEnabledSetting(ComponentName componentName,
20366            int newState, int flags, int userId) {
20367        if (!sUserManager.exists(userId)) return;
20368        setEnabledSetting(componentName.getPackageName(),
20369                componentName.getClassName(), newState, flags, userId, null);
20370    }
20371
20372    private void setEnabledSetting(final String packageName, String className, int newState,
20373            final int flags, int userId, String callingPackage) {
20374        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20375              || newState == COMPONENT_ENABLED_STATE_ENABLED
20376              || newState == COMPONENT_ENABLED_STATE_DISABLED
20377              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20378              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20379            throw new IllegalArgumentException("Invalid new component state: "
20380                    + newState);
20381        }
20382        PackageSetting pkgSetting;
20383        final int callingUid = Binder.getCallingUid();
20384        final int permission;
20385        if (callingUid == Process.SYSTEM_UID) {
20386            permission = PackageManager.PERMISSION_GRANTED;
20387        } else {
20388            permission = mContext.checkCallingOrSelfPermission(
20389                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20390        }
20391        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20392                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20393        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20394        boolean sendNow = false;
20395        boolean isApp = (className == null);
20396        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20397        String componentName = isApp ? packageName : className;
20398        int packageUid = -1;
20399        ArrayList<String> components;
20400
20401        // reader
20402        synchronized (mPackages) {
20403            pkgSetting = mSettings.mPackages.get(packageName);
20404            if (pkgSetting == null) {
20405                if (!isCallerInstantApp) {
20406                    if (className == null) {
20407                        throw new IllegalArgumentException("Unknown package: " + packageName);
20408                    }
20409                    throw new IllegalArgumentException(
20410                            "Unknown component: " + packageName + "/" + className);
20411                } else {
20412                    // throw SecurityException to prevent leaking package information
20413                    throw new SecurityException(
20414                            "Attempt to change component state; "
20415                            + "pid=" + Binder.getCallingPid()
20416                            + ", uid=" + callingUid
20417                            + (className == null
20418                                    ? ", package=" + packageName
20419                                    : ", component=" + packageName + "/" + className));
20420                }
20421            }
20422        }
20423
20424        // Limit who can change which apps
20425        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20426            // Don't allow apps that don't have permission to modify other apps
20427            if (!allowedByPermission
20428                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20429                throw new SecurityException(
20430                        "Attempt to change component state; "
20431                        + "pid=" + Binder.getCallingPid()
20432                        + ", uid=" + callingUid
20433                        + (className == null
20434                                ? ", package=" + packageName
20435                                : ", component=" + packageName + "/" + className));
20436            }
20437            // Don't allow changing protected packages.
20438            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20439                throw new SecurityException("Cannot disable a protected package: " + packageName);
20440            }
20441        }
20442
20443        synchronized (mPackages) {
20444            if (callingUid == Process.SHELL_UID
20445                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20446                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20447                // unless it is a test package.
20448                int oldState = pkgSetting.getEnabled(userId);
20449                if (className == null
20450                        &&
20451                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20452                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20453                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20454                        &&
20455                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20456                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
20457                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20458                    // ok
20459                } else {
20460                    throw new SecurityException(
20461                            "Shell cannot change component state for " + packageName + "/"
20462                                    + className + " to " + newState);
20463                }
20464            }
20465        }
20466        if (className == null) {
20467            // We're dealing with an application/package level state change
20468            synchronized (mPackages) {
20469                if (pkgSetting.getEnabled(userId) == newState) {
20470                    // Nothing to do
20471                    return;
20472                }
20473            }
20474            // If we're enabling a system stub, there's a little more work to do.
20475            // Prior to enabling the package, we need to decompress the APK(s) to the
20476            // data partition and then replace the version on the system partition.
20477            final PackageParser.Package deletedPkg = pkgSetting.pkg;
20478            final boolean isSystemStub = deletedPkg.isStub
20479                    && deletedPkg.isSystem();
20480            if (isSystemStub
20481                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20482                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20483                final File codePath = decompressPackage(deletedPkg);
20484                if (codePath == null) {
20485                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20486                    return;
20487                }
20488                // TODO remove direct parsing of the package object during internal cleanup
20489                // of scan package
20490                // We need to call parse directly here for no other reason than we need
20491                // the new package in order to disable the old one [we use the information
20492                // for some internal optimization to optionally create a new package setting
20493                // object on replace]. However, we can't get the package from the scan
20494                // because the scan modifies live structures and we need to remove the
20495                // old [system] package from the system before a scan can be attempted.
20496                // Once scan is indempotent we can remove this parse and use the package
20497                // object we scanned, prior to adding it to package settings.
20498                final PackageParser pp = new PackageParser();
20499                pp.setSeparateProcesses(mSeparateProcesses);
20500                pp.setDisplayMetrics(mMetrics);
20501                pp.setCallback(mPackageParserCallback);
20502                final PackageParser.Package tmpPkg;
20503                try {
20504                    final @ParseFlags int parseFlags = mDefParseFlags
20505                            | PackageParser.PARSE_MUST_BE_APK
20506                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20507                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20508                } catch (PackageParserException e) {
20509                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20510                    return;
20511                }
20512                synchronized (mInstallLock) {
20513                    // Disable the stub and remove any package entries
20514                    removePackageLI(deletedPkg, true);
20515                    synchronized (mPackages) {
20516                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20517                    }
20518                    final PackageParser.Package pkg;
20519                    try (PackageFreezer freezer =
20520                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20521                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20522                                | PackageParser.PARSE_ENFORCE_CODE;
20523                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20524                                0 /*currentTime*/, null /*user*/);
20525                        prepareAppDataAfterInstallLIF(pkg);
20526                        synchronized (mPackages) {
20527                            try {
20528                                updateSharedLibrariesLPr(pkg, null);
20529                            } catch (PackageManagerException e) {
20530                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20531                            }
20532                            mPermissionManager.updatePermissions(
20533                                    pkg.packageName, pkg, true, mPackages.values(),
20534                                    mPermissionCallback);
20535                            mSettings.writeLPr();
20536                        }
20537                    } catch (PackageManagerException e) {
20538                        // Whoops! Something went wrong; try to roll back to the stub
20539                        Slog.w(TAG, "Failed to install compressed system package:"
20540                                + pkgSetting.name, e);
20541                        // Remove the failed install
20542                        removeCodePathLI(codePath);
20543
20544                        // Install the system package
20545                        try (PackageFreezer freezer =
20546                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20547                            synchronized (mPackages) {
20548                                // NOTE: The system package always needs to be enabled; even
20549                                // if it's for a compressed stub. If we don't, installing the
20550                                // system package fails during scan [scanning checks the disabled
20551                                // packages]. We will reverse this later, after we've "installed"
20552                                // the stub.
20553                                // This leaves us in a fragile state; the stub should never be
20554                                // enabled, so, cross your fingers and hope nothing goes wrong
20555                                // until we can disable the package later.
20556                                enableSystemPackageLPw(deletedPkg);
20557                            }
20558                            installPackageFromSystemLIF(deletedPkg.codePath,
20559                                    false /*isPrivileged*/, null /*allUserHandles*/,
20560                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20561                                    true /*writeSettings*/);
20562                        } catch (PackageManagerException pme) {
20563                            Slog.w(TAG, "Failed to restore system package:"
20564                                    + deletedPkg.packageName, pme);
20565                        } finally {
20566                            synchronized (mPackages) {
20567                                mSettings.disableSystemPackageLPw(
20568                                        deletedPkg.packageName, true /*replaced*/);
20569                                mSettings.writeLPr();
20570                            }
20571                        }
20572                        return;
20573                    }
20574                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20575                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20576                    mDexManager.notifyPackageUpdated(pkg.packageName,
20577                            pkg.baseCodePath, pkg.splitCodePaths);
20578                }
20579            }
20580            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20581                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20582                // Don't care about who enables an app.
20583                callingPackage = null;
20584            }
20585            synchronized (mPackages) {
20586                pkgSetting.setEnabled(newState, userId, callingPackage);
20587            }
20588        } else {
20589            synchronized (mPackages) {
20590                // We're dealing with a component level state change
20591                // First, verify that this is a valid class name.
20592                PackageParser.Package pkg = pkgSetting.pkg;
20593                if (pkg == null || !pkg.hasComponentClassName(className)) {
20594                    if (pkg != null &&
20595                            pkg.applicationInfo.targetSdkVersion >=
20596                                    Build.VERSION_CODES.JELLY_BEAN) {
20597                        throw new IllegalArgumentException("Component class " + className
20598                                + " does not exist in " + packageName);
20599                    } else {
20600                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20601                                + className + " does not exist in " + packageName);
20602                    }
20603                }
20604                switch (newState) {
20605                    case COMPONENT_ENABLED_STATE_ENABLED:
20606                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20607                            return;
20608                        }
20609                        break;
20610                    case COMPONENT_ENABLED_STATE_DISABLED:
20611                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20612                            return;
20613                        }
20614                        break;
20615                    case COMPONENT_ENABLED_STATE_DEFAULT:
20616                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20617                            return;
20618                        }
20619                        break;
20620                    default:
20621                        Slog.e(TAG, "Invalid new component state: " + newState);
20622                        return;
20623                }
20624            }
20625        }
20626        synchronized (mPackages) {
20627            scheduleWritePackageRestrictionsLocked(userId);
20628            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20629            final long callingId = Binder.clearCallingIdentity();
20630            try {
20631                updateInstantAppInstallerLocked(packageName);
20632            } finally {
20633                Binder.restoreCallingIdentity(callingId);
20634            }
20635            components = mPendingBroadcasts.get(userId, packageName);
20636            final boolean newPackage = components == null;
20637            if (newPackage) {
20638                components = new ArrayList<String>();
20639            }
20640            if (!components.contains(componentName)) {
20641                components.add(componentName);
20642            }
20643            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20644                sendNow = true;
20645                // Purge entry from pending broadcast list if another one exists already
20646                // since we are sending one right away.
20647                mPendingBroadcasts.remove(userId, packageName);
20648            } else {
20649                if (newPackage) {
20650                    mPendingBroadcasts.put(userId, packageName, components);
20651                }
20652                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20653                    // Schedule a message
20654                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20655                }
20656            }
20657        }
20658
20659        long callingId = Binder.clearCallingIdentity();
20660        try {
20661            if (sendNow) {
20662                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20663                sendPackageChangedBroadcast(packageName,
20664                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20665            }
20666        } finally {
20667            Binder.restoreCallingIdentity(callingId);
20668        }
20669    }
20670
20671    @Override
20672    public void flushPackageRestrictionsAsUser(int userId) {
20673        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20674            return;
20675        }
20676        if (!sUserManager.exists(userId)) {
20677            return;
20678        }
20679        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20680                false /* checkShell */, "flushPackageRestrictions");
20681        synchronized (mPackages) {
20682            mSettings.writePackageRestrictionsLPr(userId);
20683            mDirtyUsers.remove(userId);
20684            if (mDirtyUsers.isEmpty()) {
20685                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20686            }
20687        }
20688    }
20689
20690    private void sendPackageChangedBroadcast(String packageName,
20691            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20692        if (DEBUG_INSTALL)
20693            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20694                    + componentNames);
20695        Bundle extras = new Bundle(4);
20696        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20697        String nameList[] = new String[componentNames.size()];
20698        componentNames.toArray(nameList);
20699        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20700        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20701        extras.putInt(Intent.EXTRA_UID, packageUid);
20702        // If this is not reporting a change of the overall package, then only send it
20703        // to registered receivers.  We don't want to launch a swath of apps for every
20704        // little component state change.
20705        final int flags = !componentNames.contains(packageName)
20706                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20707        final int userId = UserHandle.getUserId(packageUid);
20708        final boolean isInstantApp = isInstantApp(packageName, userId);
20709        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20710        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20711        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20712                userIds, instantUserIds);
20713    }
20714
20715    @Override
20716    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20717        if (!sUserManager.exists(userId)) return;
20718        final int callingUid = Binder.getCallingUid();
20719        if (getInstantAppPackageName(callingUid) != null) {
20720            return;
20721        }
20722        final int permission = mContext.checkCallingOrSelfPermission(
20723                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20724        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20725        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20726                true /* requireFullPermission */, true /* checkShell */, "stop package");
20727        // writer
20728        synchronized (mPackages) {
20729            final PackageSetting ps = mSettings.mPackages.get(packageName);
20730            if (!filterAppAccessLPr(ps, callingUid, userId)
20731                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20732                            allowedByPermission, callingUid, userId)) {
20733                scheduleWritePackageRestrictionsLocked(userId);
20734            }
20735        }
20736    }
20737
20738    @Override
20739    public String getInstallerPackageName(String packageName) {
20740        final int callingUid = Binder.getCallingUid();
20741        synchronized (mPackages) {
20742            final PackageSetting ps = mSettings.mPackages.get(packageName);
20743            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20744                return null;
20745            }
20746            return mSettings.getInstallerPackageNameLPr(packageName);
20747        }
20748    }
20749
20750    public boolean isOrphaned(String packageName) {
20751        // reader
20752        synchronized (mPackages) {
20753            return mSettings.isOrphaned(packageName);
20754        }
20755    }
20756
20757    @Override
20758    public int getApplicationEnabledSetting(String packageName, int userId) {
20759        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20760        int callingUid = Binder.getCallingUid();
20761        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20762                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20763        // reader
20764        synchronized (mPackages) {
20765            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20766                return COMPONENT_ENABLED_STATE_DISABLED;
20767            }
20768            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20769        }
20770    }
20771
20772    @Override
20773    public int getComponentEnabledSetting(ComponentName component, int userId) {
20774        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20775        int callingUid = Binder.getCallingUid();
20776        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20777                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20778        synchronized (mPackages) {
20779            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20780                    component, TYPE_UNKNOWN, userId)) {
20781                return COMPONENT_ENABLED_STATE_DISABLED;
20782            }
20783            return mSettings.getComponentEnabledSettingLPr(component, userId);
20784        }
20785    }
20786
20787    @Override
20788    public void enterSafeMode() {
20789        enforceSystemOrRoot("Only the system can request entering safe mode");
20790
20791        if (!mSystemReady) {
20792            mSafeMode = true;
20793        }
20794    }
20795
20796    @Override
20797    public void systemReady() {
20798        enforceSystemOrRoot("Only the system can claim the system is ready");
20799
20800        mSystemReady = true;
20801        final ContentResolver resolver = mContext.getContentResolver();
20802        ContentObserver co = new ContentObserver(mHandler) {
20803            @Override
20804            public void onChange(boolean selfChange) {
20805                mWebInstantAppsDisabled =
20806                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20807                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20808            }
20809        };
20810        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20811                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20812                false, co, UserHandle.USER_SYSTEM);
20813        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20814                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20815        co.onChange(true);
20816
20817        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20818        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20819        // it is done.
20820        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20821            @Override
20822            public void onChange(boolean selfChange) {
20823                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20824                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20825                        oobEnabled == 1 ? "true" : "false");
20826            }
20827        };
20828        mContext.getContentResolver().registerContentObserver(
20829                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20830                UserHandle.USER_SYSTEM);
20831        // At boot, restore the value from the setting, which persists across reboot.
20832        privAppOobObserver.onChange(true);
20833
20834        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20835        // disabled after already being started.
20836        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20837                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20838
20839        // Read the compatibilty setting when the system is ready.
20840        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20841                mContext.getContentResolver(),
20842                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20843        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20844        if (DEBUG_SETTINGS) {
20845            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20846        }
20847
20848        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20849
20850        synchronized (mPackages) {
20851            // Verify that all of the preferred activity components actually
20852            // exist.  It is possible for applications to be updated and at
20853            // that point remove a previously declared activity component that
20854            // had been set as a preferred activity.  We try to clean this up
20855            // the next time we encounter that preferred activity, but it is
20856            // possible for the user flow to never be able to return to that
20857            // situation so here we do a sanity check to make sure we haven't
20858            // left any junk around.
20859            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20860            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20861                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20862                removed.clear();
20863                for (PreferredActivity pa : pir.filterSet()) {
20864                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20865                        removed.add(pa);
20866                    }
20867                }
20868                if (removed.size() > 0) {
20869                    for (int r=0; r<removed.size(); r++) {
20870                        PreferredActivity pa = removed.get(r);
20871                        Slog.w(TAG, "Removing dangling preferred activity: "
20872                                + pa.mPref.mComponent);
20873                        pir.removeFilter(pa);
20874                    }
20875                    mSettings.writePackageRestrictionsLPr(
20876                            mSettings.mPreferredActivities.keyAt(i));
20877                }
20878            }
20879
20880            for (int userId : UserManagerService.getInstance().getUserIds()) {
20881                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20882                    grantPermissionsUserIds = ArrayUtils.appendInt(
20883                            grantPermissionsUserIds, userId);
20884                }
20885            }
20886        }
20887        sUserManager.systemReady();
20888        // If we upgraded grant all default permissions before kicking off.
20889        for (int userId : grantPermissionsUserIds) {
20890            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20891        }
20892
20893        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20894            // If we did not grant default permissions, we preload from this the
20895            // default permission exceptions lazily to ensure we don't hit the
20896            // disk on a new user creation.
20897            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20898        }
20899
20900        // Now that we've scanned all packages, and granted any default
20901        // permissions, ensure permissions are updated. Beware of dragons if you
20902        // try optimizing this.
20903        synchronized (mPackages) {
20904            mPermissionManager.updateAllPermissions(
20905                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20906                    mPermissionCallback);
20907        }
20908
20909        // Kick off any messages waiting for system ready
20910        if (mPostSystemReadyMessages != null) {
20911            for (Message msg : mPostSystemReadyMessages) {
20912                msg.sendToTarget();
20913            }
20914            mPostSystemReadyMessages = null;
20915        }
20916
20917        // Watch for external volumes that come and go over time
20918        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20919        storage.registerListener(mStorageListener);
20920
20921        mInstallerService.systemReady();
20922        mPackageDexOptimizer.systemReady();
20923
20924        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20925                StorageManagerInternal.class);
20926        StorageManagerInternal.addExternalStoragePolicy(
20927                new StorageManagerInternal.ExternalStorageMountPolicy() {
20928            @Override
20929            public int getMountMode(int uid, String packageName) {
20930                if (Process.isIsolated(uid)) {
20931                    return Zygote.MOUNT_EXTERNAL_NONE;
20932                }
20933                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20934                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20935                }
20936                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20937                    return Zygote.MOUNT_EXTERNAL_READ;
20938                }
20939                return Zygote.MOUNT_EXTERNAL_WRITE;
20940            }
20941
20942            @Override
20943            public boolean hasExternalStorage(int uid, String packageName) {
20944                return true;
20945            }
20946        });
20947
20948        // Now that we're mostly running, clean up stale users and apps
20949        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20950        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20951
20952        mPermissionManager.systemReady();
20953
20954        if (mInstantAppResolverConnection != null) {
20955            mContext.registerReceiver(new BroadcastReceiver() {
20956                @Override
20957                public void onReceive(Context context, Intent intent) {
20958                    mInstantAppResolverConnection.optimisticBind();
20959                    mContext.unregisterReceiver(this);
20960                }
20961            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20962        }
20963    }
20964
20965    public void waitForAppDataPrepared() {
20966        if (mPrepareAppDataFuture == null) {
20967            return;
20968        }
20969        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20970        mPrepareAppDataFuture = null;
20971    }
20972
20973    @Override
20974    public boolean isSafeMode() {
20975        // allow instant applications
20976        return mSafeMode;
20977    }
20978
20979    @Override
20980    public boolean hasSystemUidErrors() {
20981        // allow instant applications
20982        return mHasSystemUidErrors;
20983    }
20984
20985    static String arrayToString(int[] array) {
20986        StringBuffer buf = new StringBuffer(128);
20987        buf.append('[');
20988        if (array != null) {
20989            for (int i=0; i<array.length; i++) {
20990                if (i > 0) buf.append(", ");
20991                buf.append(array[i]);
20992            }
20993        }
20994        buf.append(']');
20995        return buf.toString();
20996    }
20997
20998    @Override
20999    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21000            FileDescriptor err, String[] args, ShellCallback callback,
21001            ResultReceiver resultReceiver) {
21002        (new PackageManagerShellCommand(this)).exec(
21003                this, in, out, err, args, callback, resultReceiver);
21004    }
21005
21006    @Override
21007    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21008        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21009
21010        DumpState dumpState = new DumpState();
21011        boolean fullPreferred = false;
21012        boolean checkin = false;
21013
21014        String packageName = null;
21015        ArraySet<String> permissionNames = null;
21016
21017        int opti = 0;
21018        while (opti < args.length) {
21019            String opt = args[opti];
21020            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21021                break;
21022            }
21023            opti++;
21024
21025            if ("-a".equals(opt)) {
21026                // Right now we only know how to print all.
21027            } else if ("-h".equals(opt)) {
21028                pw.println("Package manager dump options:");
21029                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21030                pw.println("    --checkin: dump for a checkin");
21031                pw.println("    -f: print details of intent filters");
21032                pw.println("    -h: print this help");
21033                pw.println("  cmd may be one of:");
21034                pw.println("    l[ibraries]: list known shared libraries");
21035                pw.println("    f[eatures]: list device features");
21036                pw.println("    k[eysets]: print known keysets");
21037                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21038                pw.println("    perm[issions]: dump permissions");
21039                pw.println("    permission [name ...]: dump declaration and use of given permission");
21040                pw.println("    pref[erred]: print preferred package settings");
21041                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21042                pw.println("    prov[iders]: dump content providers");
21043                pw.println("    p[ackages]: dump installed packages");
21044                pw.println("    s[hared-users]: dump shared user IDs");
21045                pw.println("    m[essages]: print collected runtime messages");
21046                pw.println("    v[erifiers]: print package verifier info");
21047                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21048                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21049                pw.println("    version: print database version info");
21050                pw.println("    write: write current settings now");
21051                pw.println("    installs: details about install sessions");
21052                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21053                pw.println("    dexopt: dump dexopt state");
21054                pw.println("    compiler-stats: dump compiler statistics");
21055                pw.println("    service-permissions: dump permissions required by services");
21056                pw.println("    <package.name>: info about given package");
21057                return;
21058            } else if ("--checkin".equals(opt)) {
21059                checkin = true;
21060            } else if ("-f".equals(opt)) {
21061                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21062            } else if ("--proto".equals(opt)) {
21063                dumpProto(fd);
21064                return;
21065            } else {
21066                pw.println("Unknown argument: " + opt + "; use -h for help");
21067            }
21068        }
21069
21070        // Is the caller requesting to dump a particular piece of data?
21071        if (opti < args.length) {
21072            String cmd = args[opti];
21073            opti++;
21074            // Is this a package name?
21075            if ("android".equals(cmd) || cmd.contains(".")) {
21076                packageName = cmd;
21077                // When dumping a single package, we always dump all of its
21078                // filter information since the amount of data will be reasonable.
21079                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21080            } else if ("check-permission".equals(cmd)) {
21081                if (opti >= args.length) {
21082                    pw.println("Error: check-permission missing permission argument");
21083                    return;
21084                }
21085                String perm = args[opti];
21086                opti++;
21087                if (opti >= args.length) {
21088                    pw.println("Error: check-permission missing package argument");
21089                    return;
21090                }
21091
21092                String pkg = args[opti];
21093                opti++;
21094                int user = UserHandle.getUserId(Binder.getCallingUid());
21095                if (opti < args.length) {
21096                    try {
21097                        user = Integer.parseInt(args[opti]);
21098                    } catch (NumberFormatException e) {
21099                        pw.println("Error: check-permission user argument is not a number: "
21100                                + args[opti]);
21101                        return;
21102                    }
21103                }
21104
21105                // Normalize package name to handle renamed packages and static libs
21106                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21107
21108                pw.println(checkPermission(perm, pkg, user));
21109                return;
21110            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21111                dumpState.setDump(DumpState.DUMP_LIBS);
21112            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21113                dumpState.setDump(DumpState.DUMP_FEATURES);
21114            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21115                if (opti >= args.length) {
21116                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21117                            | DumpState.DUMP_SERVICE_RESOLVERS
21118                            | DumpState.DUMP_RECEIVER_RESOLVERS
21119                            | DumpState.DUMP_CONTENT_RESOLVERS);
21120                } else {
21121                    while (opti < args.length) {
21122                        String name = args[opti];
21123                        if ("a".equals(name) || "activity".equals(name)) {
21124                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21125                        } else if ("s".equals(name) || "service".equals(name)) {
21126                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21127                        } else if ("r".equals(name) || "receiver".equals(name)) {
21128                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21129                        } else if ("c".equals(name) || "content".equals(name)) {
21130                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21131                        } else {
21132                            pw.println("Error: unknown resolver table type: " + name);
21133                            return;
21134                        }
21135                        opti++;
21136                    }
21137                }
21138            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21139                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21140            } else if ("permission".equals(cmd)) {
21141                if (opti >= args.length) {
21142                    pw.println("Error: permission requires permission name");
21143                    return;
21144                }
21145                permissionNames = new ArraySet<>();
21146                while (opti < args.length) {
21147                    permissionNames.add(args[opti]);
21148                    opti++;
21149                }
21150                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21151                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21152            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21153                dumpState.setDump(DumpState.DUMP_PREFERRED);
21154            } else if ("preferred-xml".equals(cmd)) {
21155                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21156                if (opti < args.length && "--full".equals(args[opti])) {
21157                    fullPreferred = true;
21158                    opti++;
21159                }
21160            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21161                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21162            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21163                dumpState.setDump(DumpState.DUMP_PACKAGES);
21164            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21165                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21166            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21167                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21168            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21169                dumpState.setDump(DumpState.DUMP_MESSAGES);
21170            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21171                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21172            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21173                    || "intent-filter-verifiers".equals(cmd)) {
21174                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21175            } else if ("version".equals(cmd)) {
21176                dumpState.setDump(DumpState.DUMP_VERSION);
21177            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21178                dumpState.setDump(DumpState.DUMP_KEYSETS);
21179            } else if ("installs".equals(cmd)) {
21180                dumpState.setDump(DumpState.DUMP_INSTALLS);
21181            } else if ("frozen".equals(cmd)) {
21182                dumpState.setDump(DumpState.DUMP_FROZEN);
21183            } else if ("volumes".equals(cmd)) {
21184                dumpState.setDump(DumpState.DUMP_VOLUMES);
21185            } else if ("dexopt".equals(cmd)) {
21186                dumpState.setDump(DumpState.DUMP_DEXOPT);
21187            } else if ("compiler-stats".equals(cmd)) {
21188                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21189            } else if ("changes".equals(cmd)) {
21190                dumpState.setDump(DumpState.DUMP_CHANGES);
21191            } else if ("service-permissions".equals(cmd)) {
21192                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21193            } else if ("write".equals(cmd)) {
21194                synchronized (mPackages) {
21195                    mSettings.writeLPr();
21196                    pw.println("Settings written.");
21197                    return;
21198                }
21199            }
21200        }
21201
21202        if (checkin) {
21203            pw.println("vers,1");
21204        }
21205
21206        // reader
21207        synchronized (mPackages) {
21208            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21209                if (!checkin) {
21210                    if (dumpState.onTitlePrinted())
21211                        pw.println();
21212                    pw.println("Database versions:");
21213                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21214                }
21215            }
21216
21217            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21218                if (!checkin) {
21219                    if (dumpState.onTitlePrinted())
21220                        pw.println();
21221                    pw.println("Verifiers:");
21222                    pw.print("  Required: ");
21223                    pw.print(mRequiredVerifierPackage);
21224                    pw.print(" (uid=");
21225                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21226                            UserHandle.USER_SYSTEM));
21227                    pw.println(")");
21228                } else if (mRequiredVerifierPackage != null) {
21229                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21230                    pw.print(",");
21231                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21232                            UserHandle.USER_SYSTEM));
21233                }
21234            }
21235
21236            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21237                    packageName == null) {
21238                if (mIntentFilterVerifierComponent != null) {
21239                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21240                    if (!checkin) {
21241                        if (dumpState.onTitlePrinted())
21242                            pw.println();
21243                        pw.println("Intent Filter Verifier:");
21244                        pw.print("  Using: ");
21245                        pw.print(verifierPackageName);
21246                        pw.print(" (uid=");
21247                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21248                                UserHandle.USER_SYSTEM));
21249                        pw.println(")");
21250                    } else if (verifierPackageName != null) {
21251                        pw.print("ifv,"); pw.print(verifierPackageName);
21252                        pw.print(",");
21253                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21254                                UserHandle.USER_SYSTEM));
21255                    }
21256                } else {
21257                    pw.println();
21258                    pw.println("No Intent Filter Verifier available!");
21259                }
21260            }
21261
21262            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21263                boolean printedHeader = false;
21264                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21265                while (it.hasNext()) {
21266                    String libName = it.next();
21267                    LongSparseArray<SharedLibraryEntry> versionedLib
21268                            = mSharedLibraries.get(libName);
21269                    if (versionedLib == null) {
21270                        continue;
21271                    }
21272                    final int versionCount = versionedLib.size();
21273                    for (int i = 0; i < versionCount; i++) {
21274                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21275                        if (!checkin) {
21276                            if (!printedHeader) {
21277                                if (dumpState.onTitlePrinted())
21278                                    pw.println();
21279                                pw.println("Libraries:");
21280                                printedHeader = true;
21281                            }
21282                            pw.print("  ");
21283                        } else {
21284                            pw.print("lib,");
21285                        }
21286                        pw.print(libEntry.info.getName());
21287                        if (libEntry.info.isStatic()) {
21288                            pw.print(" version=" + libEntry.info.getLongVersion());
21289                        }
21290                        if (!checkin) {
21291                            pw.print(" -> ");
21292                        }
21293                        if (libEntry.path != null) {
21294                            pw.print(" (jar) ");
21295                            pw.print(libEntry.path);
21296                        } else {
21297                            pw.print(" (apk) ");
21298                            pw.print(libEntry.apk);
21299                        }
21300                        pw.println();
21301                    }
21302                }
21303            }
21304
21305            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21306                if (dumpState.onTitlePrinted())
21307                    pw.println();
21308                if (!checkin) {
21309                    pw.println("Features:");
21310                }
21311
21312                synchronized (mAvailableFeatures) {
21313                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21314                        if (checkin) {
21315                            pw.print("feat,");
21316                            pw.print(feat.name);
21317                            pw.print(",");
21318                            pw.println(feat.version);
21319                        } else {
21320                            pw.print("  ");
21321                            pw.print(feat.name);
21322                            if (feat.version > 0) {
21323                                pw.print(" version=");
21324                                pw.print(feat.version);
21325                            }
21326                            pw.println();
21327                        }
21328                    }
21329                }
21330            }
21331
21332            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21333                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21334                        : "Activity Resolver Table:", "  ", packageName,
21335                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21336                    dumpState.setTitlePrinted(true);
21337                }
21338            }
21339            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21340                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21341                        : "Receiver Resolver Table:", "  ", packageName,
21342                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21343                    dumpState.setTitlePrinted(true);
21344                }
21345            }
21346            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21347                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21348                        : "Service Resolver Table:", "  ", packageName,
21349                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21350                    dumpState.setTitlePrinted(true);
21351                }
21352            }
21353            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21354                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21355                        : "Provider Resolver Table:", "  ", packageName,
21356                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21357                    dumpState.setTitlePrinted(true);
21358                }
21359            }
21360
21361            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21362                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21363                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21364                    int user = mSettings.mPreferredActivities.keyAt(i);
21365                    if (pir.dump(pw,
21366                            dumpState.getTitlePrinted()
21367                                ? "\nPreferred Activities User " + user + ":"
21368                                : "Preferred Activities User " + user + ":", "  ",
21369                            packageName, true, false)) {
21370                        dumpState.setTitlePrinted(true);
21371                    }
21372                }
21373            }
21374
21375            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21376                pw.flush();
21377                FileOutputStream fout = new FileOutputStream(fd);
21378                BufferedOutputStream str = new BufferedOutputStream(fout);
21379                XmlSerializer serializer = new FastXmlSerializer();
21380                try {
21381                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21382                    serializer.startDocument(null, true);
21383                    serializer.setFeature(
21384                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21385                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21386                    serializer.endDocument();
21387                    serializer.flush();
21388                } catch (IllegalArgumentException e) {
21389                    pw.println("Failed writing: " + e);
21390                } catch (IllegalStateException e) {
21391                    pw.println("Failed writing: " + e);
21392                } catch (IOException e) {
21393                    pw.println("Failed writing: " + e);
21394                }
21395            }
21396
21397            if (!checkin
21398                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21399                    && packageName == null) {
21400                pw.println();
21401                int count = mSettings.mPackages.size();
21402                if (count == 0) {
21403                    pw.println("No applications!");
21404                    pw.println();
21405                } else {
21406                    final String prefix = "  ";
21407                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21408                    if (allPackageSettings.size() == 0) {
21409                        pw.println("No domain preferred apps!");
21410                        pw.println();
21411                    } else {
21412                        pw.println("App verification status:");
21413                        pw.println();
21414                        count = 0;
21415                        for (PackageSetting ps : allPackageSettings) {
21416                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21417                            if (ivi == null || ivi.getPackageName() == null) continue;
21418                            pw.println(prefix + "Package: " + ivi.getPackageName());
21419                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21420                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21421                            pw.println();
21422                            count++;
21423                        }
21424                        if (count == 0) {
21425                            pw.println(prefix + "No app verification established.");
21426                            pw.println();
21427                        }
21428                        for (int userId : sUserManager.getUserIds()) {
21429                            pw.println("App linkages for user " + userId + ":");
21430                            pw.println();
21431                            count = 0;
21432                            for (PackageSetting ps : allPackageSettings) {
21433                                final long status = ps.getDomainVerificationStatusForUser(userId);
21434                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21435                                        && !DEBUG_DOMAIN_VERIFICATION) {
21436                                    continue;
21437                                }
21438                                pw.println(prefix + "Package: " + ps.name);
21439                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21440                                String statusStr = IntentFilterVerificationInfo.
21441                                        getStatusStringFromValue(status);
21442                                pw.println(prefix + "Status:  " + statusStr);
21443                                pw.println();
21444                                count++;
21445                            }
21446                            if (count == 0) {
21447                                pw.println(prefix + "No configured app linkages.");
21448                                pw.println();
21449                            }
21450                        }
21451                    }
21452                }
21453            }
21454
21455            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21456                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21457            }
21458
21459            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21460                boolean printedSomething = false;
21461                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21462                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21463                        continue;
21464                    }
21465                    if (!printedSomething) {
21466                        if (dumpState.onTitlePrinted())
21467                            pw.println();
21468                        pw.println("Registered ContentProviders:");
21469                        printedSomething = true;
21470                    }
21471                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21472                    pw.print("    "); pw.println(p.toString());
21473                }
21474                printedSomething = false;
21475                for (Map.Entry<String, PackageParser.Provider> entry :
21476                        mProvidersByAuthority.entrySet()) {
21477                    PackageParser.Provider p = entry.getValue();
21478                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21479                        continue;
21480                    }
21481                    if (!printedSomething) {
21482                        if (dumpState.onTitlePrinted())
21483                            pw.println();
21484                        pw.println("ContentProvider Authorities:");
21485                        printedSomething = true;
21486                    }
21487                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21488                    pw.print("    "); pw.println(p.toString());
21489                    if (p.info != null && p.info.applicationInfo != null) {
21490                        final String appInfo = p.info.applicationInfo.toString();
21491                        pw.print("      applicationInfo="); pw.println(appInfo);
21492                    }
21493                }
21494            }
21495
21496            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21497                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21498            }
21499
21500            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21501                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21502            }
21503
21504            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21505                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21506            }
21507
21508            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21509                if (dumpState.onTitlePrinted()) pw.println();
21510                pw.println("Package Changes:");
21511                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21512                final int K = mChangedPackages.size();
21513                for (int i = 0; i < K; i++) {
21514                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21515                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21516                    final int N = changes.size();
21517                    if (N == 0) {
21518                        pw.print("    "); pw.println("No packages changed");
21519                    } else {
21520                        for (int j = 0; j < N; j++) {
21521                            final String pkgName = changes.valueAt(j);
21522                            final int sequenceNumber = changes.keyAt(j);
21523                            pw.print("    ");
21524                            pw.print("seq=");
21525                            pw.print(sequenceNumber);
21526                            pw.print(", package=");
21527                            pw.println(pkgName);
21528                        }
21529                    }
21530                }
21531            }
21532
21533            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21534                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21535            }
21536
21537            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21538                // XXX should handle packageName != null by dumping only install data that
21539                // the given package is involved with.
21540                if (dumpState.onTitlePrinted()) pw.println();
21541
21542                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21543                    ipw.println();
21544                    ipw.println("Frozen packages:");
21545                    ipw.increaseIndent();
21546                    if (mFrozenPackages.size() == 0) {
21547                        ipw.println("(none)");
21548                    } else {
21549                        for (int i = 0; i < mFrozenPackages.size(); i++) {
21550                            ipw.println(mFrozenPackages.valueAt(i));
21551                        }
21552                    }
21553                    ipw.decreaseIndent();
21554                }
21555            }
21556
21557            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21558                if (dumpState.onTitlePrinted()) pw.println();
21559
21560                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21561                    ipw.println();
21562                    ipw.println("Loaded volumes:");
21563                    ipw.increaseIndent();
21564                    if (mLoadedVolumes.size() == 0) {
21565                        ipw.println("(none)");
21566                    } else {
21567                        for (int i = 0; i < mLoadedVolumes.size(); i++) {
21568                            ipw.println(mLoadedVolumes.valueAt(i));
21569                        }
21570                    }
21571                    ipw.decreaseIndent();
21572                }
21573            }
21574
21575            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21576                    && packageName == null) {
21577                if (dumpState.onTitlePrinted()) pw.println();
21578                pw.println("Service permissions:");
21579
21580                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
21581                while (filterIterator.hasNext()) {
21582                    final ServiceIntentInfo info = filterIterator.next();
21583                    final ServiceInfo serviceInfo = info.service.info;
21584                    final String permission = serviceInfo.permission;
21585                    if (permission != null) {
21586                        pw.print("    ");
21587                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21588                        pw.print(": ");
21589                        pw.println(permission);
21590                    }
21591                }
21592            }
21593
21594            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21595                if (dumpState.onTitlePrinted()) pw.println();
21596                dumpDexoptStateLPr(pw, packageName);
21597            }
21598
21599            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21600                if (dumpState.onTitlePrinted()) pw.println();
21601                dumpCompilerStatsLPr(pw, packageName);
21602            }
21603
21604            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21605                if (dumpState.onTitlePrinted()) pw.println();
21606                mSettings.dumpReadMessagesLPr(pw, dumpState);
21607
21608                pw.println();
21609                pw.println("Package warning messages:");
21610                dumpCriticalInfo(pw, null);
21611            }
21612
21613            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21614                dumpCriticalInfo(pw, "msg,");
21615            }
21616        }
21617
21618        // PackageInstaller should be called outside of mPackages lock
21619        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21620            // XXX should handle packageName != null by dumping only install data that
21621            // the given package is involved with.
21622            if (dumpState.onTitlePrinted()) pw.println();
21623            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21624        }
21625    }
21626
21627    private void dumpProto(FileDescriptor fd) {
21628        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21629
21630        synchronized (mPackages) {
21631            final long requiredVerifierPackageToken =
21632                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21633            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21634            proto.write(
21635                    PackageServiceDumpProto.PackageShortProto.UID,
21636                    getPackageUid(
21637                            mRequiredVerifierPackage,
21638                            MATCH_DEBUG_TRIAGED_MISSING,
21639                            UserHandle.USER_SYSTEM));
21640            proto.end(requiredVerifierPackageToken);
21641
21642            if (mIntentFilterVerifierComponent != null) {
21643                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21644                final long verifierPackageToken =
21645                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21646                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21647                proto.write(
21648                        PackageServiceDumpProto.PackageShortProto.UID,
21649                        getPackageUid(
21650                                verifierPackageName,
21651                                MATCH_DEBUG_TRIAGED_MISSING,
21652                                UserHandle.USER_SYSTEM));
21653                proto.end(verifierPackageToken);
21654            }
21655
21656            dumpSharedLibrariesProto(proto);
21657            dumpFeaturesProto(proto);
21658            mSettings.dumpPackagesProto(proto);
21659            mSettings.dumpSharedUsersProto(proto);
21660            dumpCriticalInfo(proto);
21661        }
21662        proto.flush();
21663    }
21664
21665    private void dumpFeaturesProto(ProtoOutputStream proto) {
21666        synchronized (mAvailableFeatures) {
21667            final int count = mAvailableFeatures.size();
21668            for (int i = 0; i < count; i++) {
21669                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21670            }
21671        }
21672    }
21673
21674    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21675        final int count = mSharedLibraries.size();
21676        for (int i = 0; i < count; i++) {
21677            final String libName = mSharedLibraries.keyAt(i);
21678            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21679            if (versionedLib == null) {
21680                continue;
21681            }
21682            final int versionCount = versionedLib.size();
21683            for (int j = 0; j < versionCount; j++) {
21684                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21685                final long sharedLibraryToken =
21686                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21687                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21688                final boolean isJar = (libEntry.path != null);
21689                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21690                if (isJar) {
21691                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21692                } else {
21693                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21694                }
21695                proto.end(sharedLibraryToken);
21696            }
21697        }
21698    }
21699
21700    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21701        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21702            ipw.println();
21703            ipw.println("Dexopt state:");
21704            ipw.increaseIndent();
21705            Collection<PackageParser.Package> packages = null;
21706            if (packageName != null) {
21707                PackageParser.Package targetPackage = mPackages.get(packageName);
21708                if (targetPackage != null) {
21709                    packages = Collections.singletonList(targetPackage);
21710                } else {
21711                    ipw.println("Unable to find package: " + packageName);
21712                    return;
21713                }
21714            } else {
21715                packages = mPackages.values();
21716            }
21717
21718            for (PackageParser.Package pkg : packages) {
21719                ipw.println("[" + pkg.packageName + "]");
21720                ipw.increaseIndent();
21721                mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21722                        mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21723                ipw.decreaseIndent();
21724            }
21725        }
21726    }
21727
21728    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21729        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21730            ipw.println();
21731            ipw.println("Compiler stats:");
21732            ipw.increaseIndent();
21733            Collection<PackageParser.Package> packages = null;
21734            if (packageName != null) {
21735                PackageParser.Package targetPackage = mPackages.get(packageName);
21736                if (targetPackage != null) {
21737                    packages = Collections.singletonList(targetPackage);
21738                } else {
21739                    ipw.println("Unable to find package: " + packageName);
21740                    return;
21741                }
21742            } else {
21743                packages = mPackages.values();
21744            }
21745
21746            for (PackageParser.Package pkg : packages) {
21747                ipw.println("[" + pkg.packageName + "]");
21748                ipw.increaseIndent();
21749
21750                CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21751                if (stats == null) {
21752                    ipw.println("(No recorded stats)");
21753                } else {
21754                    stats.dump(ipw);
21755                }
21756                ipw.decreaseIndent();
21757            }
21758        }
21759    }
21760
21761    private String dumpDomainString(String packageName) {
21762        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21763                .getList();
21764        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21765
21766        ArraySet<String> result = new ArraySet<>();
21767        if (iviList.size() > 0) {
21768            for (IntentFilterVerificationInfo ivi : iviList) {
21769                for (String host : ivi.getDomains()) {
21770                    result.add(host);
21771                }
21772            }
21773        }
21774        if (filters != null && filters.size() > 0) {
21775            for (IntentFilter filter : filters) {
21776                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21777                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21778                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21779                    result.addAll(filter.getHostsList());
21780                }
21781            }
21782        }
21783
21784        StringBuilder sb = new StringBuilder(result.size() * 16);
21785        for (String domain : result) {
21786            if (sb.length() > 0) sb.append(" ");
21787            sb.append(domain);
21788        }
21789        return sb.toString();
21790    }
21791
21792    // ------- apps on sdcard specific code -------
21793    static final boolean DEBUG_SD_INSTALL = false;
21794
21795    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21796
21797    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21798
21799    private boolean mMediaMounted = false;
21800
21801    static String getEncryptKey() {
21802        try {
21803            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21804                    SD_ENCRYPTION_KEYSTORE_NAME);
21805            if (sdEncKey == null) {
21806                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21807                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21808                if (sdEncKey == null) {
21809                    Slog.e(TAG, "Failed to create encryption keys");
21810                    return null;
21811                }
21812            }
21813            return sdEncKey;
21814        } catch (NoSuchAlgorithmException nsae) {
21815            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21816            return null;
21817        } catch (IOException ioe) {
21818            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21819            return null;
21820        }
21821    }
21822
21823    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21824            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21825        final int size = infos.size();
21826        final String[] packageNames = new String[size];
21827        final int[] packageUids = new int[size];
21828        for (int i = 0; i < size; i++) {
21829            final ApplicationInfo info = infos.get(i);
21830            packageNames[i] = info.packageName;
21831            packageUids[i] = info.uid;
21832        }
21833        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21834                finishedReceiver);
21835    }
21836
21837    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21838            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21839        sendResourcesChangedBroadcast(mediaStatus, replacing,
21840                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21841    }
21842
21843    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21844            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21845        int size = pkgList.length;
21846        if (size > 0) {
21847            // Send broadcasts here
21848            Bundle extras = new Bundle();
21849            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21850            if (uidArr != null) {
21851                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21852            }
21853            if (replacing) {
21854                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21855            }
21856            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21857                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21858            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21859        }
21860    }
21861
21862    private void loadPrivatePackages(final VolumeInfo vol) {
21863        mHandler.post(new Runnable() {
21864            @Override
21865            public void run() {
21866                loadPrivatePackagesInner(vol);
21867            }
21868        });
21869    }
21870
21871    private void loadPrivatePackagesInner(VolumeInfo vol) {
21872        final String volumeUuid = vol.fsUuid;
21873        if (TextUtils.isEmpty(volumeUuid)) {
21874            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21875            return;
21876        }
21877
21878        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21879        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21880        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21881
21882        final VersionInfo ver;
21883        final List<PackageSetting> packages;
21884        synchronized (mPackages) {
21885            ver = mSettings.findOrCreateVersion(volumeUuid);
21886            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21887        }
21888
21889        for (PackageSetting ps : packages) {
21890            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21891            synchronized (mInstallLock) {
21892                final PackageParser.Package pkg;
21893                try {
21894                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21895                    loaded.add(pkg.applicationInfo);
21896
21897                } catch (PackageManagerException e) {
21898                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21899                }
21900
21901                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21902                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21903                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21904                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21905                }
21906            }
21907        }
21908
21909        // Reconcile app data for all started/unlocked users
21910        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21911        final UserManager um = mContext.getSystemService(UserManager.class);
21912        UserManagerInternal umInternal = getUserManagerInternal();
21913        for (UserInfo user : um.getUsers()) {
21914            final int flags;
21915            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21916                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21917            } else if (umInternal.isUserRunning(user.id)) {
21918                flags = StorageManager.FLAG_STORAGE_DE;
21919            } else {
21920                continue;
21921            }
21922
21923            try {
21924                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21925                synchronized (mInstallLock) {
21926                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21927                }
21928            } catch (IllegalStateException e) {
21929                // Device was probably ejected, and we'll process that event momentarily
21930                Slog.w(TAG, "Failed to prepare storage: " + e);
21931            }
21932        }
21933
21934        synchronized (mPackages) {
21935            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21936            if (sdkUpdated) {
21937                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21938                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21939            }
21940            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21941                    mPermissionCallback);
21942
21943            // Yay, everything is now upgraded
21944            ver.forceCurrent();
21945
21946            mSettings.writeLPr();
21947        }
21948
21949        for (PackageFreezer freezer : freezers) {
21950            freezer.close();
21951        }
21952
21953        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21954        sendResourcesChangedBroadcast(true, false, loaded, null);
21955        mLoadedVolumes.add(vol.getId());
21956    }
21957
21958    private void unloadPrivatePackages(final VolumeInfo vol) {
21959        mHandler.post(new Runnable() {
21960            @Override
21961            public void run() {
21962                unloadPrivatePackagesInner(vol);
21963            }
21964        });
21965    }
21966
21967    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21968        final String volumeUuid = vol.fsUuid;
21969        if (TextUtils.isEmpty(volumeUuid)) {
21970            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21971            return;
21972        }
21973
21974        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21975        synchronized (mInstallLock) {
21976        synchronized (mPackages) {
21977            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21978            for (PackageSetting ps : packages) {
21979                if (ps.pkg == null) continue;
21980
21981                final ApplicationInfo info = ps.pkg.applicationInfo;
21982                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21983                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21984
21985                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21986                        "unloadPrivatePackagesInner")) {
21987                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21988                            false, null)) {
21989                        unloaded.add(info);
21990                    } else {
21991                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21992                    }
21993                }
21994
21995                // Try very hard to release any references to this package
21996                // so we don't risk the system server being killed due to
21997                // open FDs
21998                AttributeCache.instance().removePackage(ps.name);
21999            }
22000
22001            mSettings.writeLPr();
22002        }
22003        }
22004
22005        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22006        sendResourcesChangedBroadcast(false, false, unloaded, null);
22007        mLoadedVolumes.remove(vol.getId());
22008
22009        // Try very hard to release any references to this path so we don't risk
22010        // the system server being killed due to open FDs
22011        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22012
22013        for (int i = 0; i < 3; i++) {
22014            System.gc();
22015            System.runFinalization();
22016        }
22017    }
22018
22019    private void assertPackageKnown(String volumeUuid, String packageName)
22020            throws PackageManagerException {
22021        synchronized (mPackages) {
22022            // Normalize package name to handle renamed packages
22023            packageName = normalizePackageNameLPr(packageName);
22024
22025            final PackageSetting ps = mSettings.mPackages.get(packageName);
22026            if (ps == null) {
22027                throw new PackageManagerException("Package " + packageName + " is unknown");
22028            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22029                throw new PackageManagerException(
22030                        "Package " + packageName + " found on unknown volume " + volumeUuid
22031                                + "; expected volume " + ps.volumeUuid);
22032            }
22033        }
22034    }
22035
22036    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22037            throws PackageManagerException {
22038        synchronized (mPackages) {
22039            // Normalize package name to handle renamed packages
22040            packageName = normalizePackageNameLPr(packageName);
22041
22042            final PackageSetting ps = mSettings.mPackages.get(packageName);
22043            if (ps == null) {
22044                throw new PackageManagerException("Package " + packageName + " is unknown");
22045            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22046                throw new PackageManagerException(
22047                        "Package " + packageName + " found on unknown volume " + volumeUuid
22048                                + "; expected volume " + ps.volumeUuid);
22049            } else if (!ps.getInstalled(userId)) {
22050                throw new PackageManagerException(
22051                        "Package " + packageName + " not installed for user " + userId);
22052            }
22053        }
22054    }
22055
22056    private List<String> collectAbsoluteCodePaths() {
22057        synchronized (mPackages) {
22058            List<String> codePaths = new ArrayList<>();
22059            final int packageCount = mSettings.mPackages.size();
22060            for (int i = 0; i < packageCount; i++) {
22061                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22062                codePaths.add(ps.codePath.getAbsolutePath());
22063            }
22064            return codePaths;
22065        }
22066    }
22067
22068    /**
22069     * Examine all apps present on given mounted volume, and destroy apps that
22070     * aren't expected, either due to uninstallation or reinstallation on
22071     * another volume.
22072     */
22073    private void reconcileApps(String volumeUuid) {
22074        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22075        List<File> filesToDelete = null;
22076
22077        final File[] files = FileUtils.listFilesOrEmpty(
22078                Environment.getDataAppDirectory(volumeUuid));
22079        for (File file : files) {
22080            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22081                    && !PackageInstallerService.isStageName(file.getName());
22082            if (!isPackage) {
22083                // Ignore entries which are not packages
22084                continue;
22085            }
22086
22087            String absolutePath = file.getAbsolutePath();
22088
22089            boolean pathValid = false;
22090            final int absoluteCodePathCount = absoluteCodePaths.size();
22091            for (int i = 0; i < absoluteCodePathCount; i++) {
22092                String absoluteCodePath = absoluteCodePaths.get(i);
22093                if (absolutePath.startsWith(absoluteCodePath)) {
22094                    pathValid = true;
22095                    break;
22096                }
22097            }
22098
22099            if (!pathValid) {
22100                if (filesToDelete == null) {
22101                    filesToDelete = new ArrayList<>();
22102                }
22103                filesToDelete.add(file);
22104            }
22105        }
22106
22107        if (filesToDelete != null) {
22108            final int fileToDeleteCount = filesToDelete.size();
22109            for (int i = 0; i < fileToDeleteCount; i++) {
22110                File fileToDelete = filesToDelete.get(i);
22111                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22112                synchronized (mInstallLock) {
22113                    removeCodePathLI(fileToDelete);
22114                }
22115            }
22116        }
22117    }
22118
22119    /**
22120     * Reconcile all app data for the given user.
22121     * <p>
22122     * Verifies that directories exist and that ownership and labeling is
22123     * correct for all installed apps on all mounted volumes.
22124     */
22125    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22126        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22127        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22128            final String volumeUuid = vol.getFsUuid();
22129            synchronized (mInstallLock) {
22130                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22131            }
22132        }
22133    }
22134
22135    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22136            boolean migrateAppData) {
22137        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22138    }
22139
22140    /**
22141     * Reconcile all app data on given mounted volume.
22142     * <p>
22143     * Destroys app data that isn't expected, either due to uninstallation or
22144     * reinstallation on another volume.
22145     * <p>
22146     * Verifies that directories exist and that ownership and labeling is
22147     * correct for all installed apps.
22148     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22149     */
22150    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22151            boolean migrateAppData, boolean onlyCoreApps) {
22152        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22153                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22154        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22155
22156        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22157        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22158
22159        // First look for stale data that doesn't belong, and check if things
22160        // have changed since we did our last restorecon
22161        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22162            if (StorageManager.isFileEncryptedNativeOrEmulated()
22163                    && !StorageManager.isUserKeyUnlocked(userId)) {
22164                throw new RuntimeException(
22165                        "Yikes, someone asked us to reconcile CE storage while " + userId
22166                                + " was still locked; this would have caused massive data loss!");
22167            }
22168
22169            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22170            for (File file : files) {
22171                final String packageName = file.getName();
22172                try {
22173                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22174                } catch (PackageManagerException e) {
22175                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22176                    try {
22177                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22178                                StorageManager.FLAG_STORAGE_CE, 0);
22179                    } catch (InstallerException e2) {
22180                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22181                    }
22182                }
22183            }
22184        }
22185        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22186            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22187            for (File file : files) {
22188                final String packageName = file.getName();
22189                try {
22190                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22191                } catch (PackageManagerException e) {
22192                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22193                    try {
22194                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22195                                StorageManager.FLAG_STORAGE_DE, 0);
22196                    } catch (InstallerException e2) {
22197                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22198                    }
22199                }
22200            }
22201        }
22202
22203        // Ensure that data directories are ready to roll for all packages
22204        // installed for this volume and user
22205        final List<PackageSetting> packages;
22206        synchronized (mPackages) {
22207            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22208        }
22209        int preparedCount = 0;
22210        for (PackageSetting ps : packages) {
22211            final String packageName = ps.name;
22212            if (ps.pkg == null) {
22213                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22214                // TODO: might be due to legacy ASEC apps; we should circle back
22215                // and reconcile again once they're scanned
22216                continue;
22217            }
22218            // Skip non-core apps if requested
22219            if (onlyCoreApps && !ps.pkg.coreApp) {
22220                result.add(packageName);
22221                continue;
22222            }
22223
22224            if (ps.getInstalled(userId)) {
22225                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22226                preparedCount++;
22227            }
22228        }
22229
22230        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22231        return result;
22232    }
22233
22234    /**
22235     * Prepare app data for the given app just after it was installed or
22236     * upgraded. This method carefully only touches users that it's installed
22237     * for, and it forces a restorecon to handle any seinfo changes.
22238     * <p>
22239     * Verifies that directories exist and that ownership and labeling is
22240     * correct for all installed apps. If there is an ownership mismatch, it
22241     * will try recovering system apps by wiping data; third-party app data is
22242     * left intact.
22243     * <p>
22244     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22245     */
22246    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22247        final PackageSetting ps;
22248        synchronized (mPackages) {
22249            ps = mSettings.mPackages.get(pkg.packageName);
22250            mSettings.writeKernelMappingLPr(ps);
22251        }
22252
22253        final UserManager um = mContext.getSystemService(UserManager.class);
22254        UserManagerInternal umInternal = getUserManagerInternal();
22255        for (UserInfo user : um.getUsers()) {
22256            final int flags;
22257            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22258                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22259            } else if (umInternal.isUserRunning(user.id)) {
22260                flags = StorageManager.FLAG_STORAGE_DE;
22261            } else {
22262                continue;
22263            }
22264
22265            if (ps.getInstalled(user.id)) {
22266                // TODO: when user data is locked, mark that we're still dirty
22267                prepareAppDataLIF(pkg, user.id, flags);
22268            }
22269        }
22270    }
22271
22272    /**
22273     * Prepare app data for the given app.
22274     * <p>
22275     * Verifies that directories exist and that ownership and labeling is
22276     * correct for all installed apps. If there is an ownership mismatch, this
22277     * will try recovering system apps by wiping data; third-party app data is
22278     * left intact.
22279     */
22280    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22281        if (pkg == null) {
22282            Slog.wtf(TAG, "Package was null!", new Throwable());
22283            return;
22284        }
22285        prepareAppDataLeafLIF(pkg, userId, flags);
22286        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22287        for (int i = 0; i < childCount; i++) {
22288            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22289        }
22290    }
22291
22292    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22293            boolean maybeMigrateAppData) {
22294        prepareAppDataLIF(pkg, userId, flags);
22295
22296        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22297            // We may have just shuffled around app data directories, so
22298            // prepare them one more time
22299            prepareAppDataLIF(pkg, userId, flags);
22300        }
22301    }
22302
22303    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22304        if (DEBUG_APP_DATA) {
22305            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22306                    + Integer.toHexString(flags));
22307        }
22308
22309        final PackageSetting ps;
22310        synchronized (mPackages) {
22311            ps = mSettings.mPackages.get(pkg.packageName);
22312        }
22313        final String volumeUuid = pkg.volumeUuid;
22314        final String packageName = pkg.packageName;
22315        final ApplicationInfo app = (ps == null)
22316                ? pkg.applicationInfo
22317                : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
22318
22319        final int appId = UserHandle.getAppId(app.uid);
22320
22321        Preconditions.checkNotNull(app.seInfo);
22322
22323        final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : "");
22324        long ceDataInode = -1;
22325        try {
22326            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22327                    appId, seInfo, app.targetSdkVersion);
22328        } catch (InstallerException e) {
22329            if (app.isSystemApp()) {
22330                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22331                        + ", but trying to recover: " + e);
22332                destroyAppDataLeafLIF(pkg, userId, flags);
22333                try {
22334                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22335                            appId, seInfo, app.targetSdkVersion);
22336                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22337                } catch (InstallerException e2) {
22338                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22339                }
22340            } else {
22341                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22342            }
22343        }
22344        // Prepare the application profiles only for upgrades and first boot (so that we don't
22345        // repeat the same operation at each boot).
22346        // We only have to cover the upgrade and first boot here because for app installs we
22347        // prepare the profiles before invoking dexopt (in installPackageLI).
22348        //
22349        // We also have to cover non system users because we do not call the usual install package
22350        // methods for them.
22351        if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22352            mArtManagerService.prepareAppProfiles(pkg, userId);
22353        }
22354
22355        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22356            // TODO: mark this structure as dirty so we persist it!
22357            synchronized (mPackages) {
22358                if (ps != null) {
22359                    ps.setCeDataInode(ceDataInode, userId);
22360                }
22361            }
22362        }
22363
22364        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22365    }
22366
22367    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22368        if (pkg == null) {
22369            Slog.wtf(TAG, "Package was null!", new Throwable());
22370            return;
22371        }
22372        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22373        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22374        for (int i = 0; i < childCount; i++) {
22375            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22376        }
22377    }
22378
22379    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22380        final String volumeUuid = pkg.volumeUuid;
22381        final String packageName = pkg.packageName;
22382        final ApplicationInfo app = pkg.applicationInfo;
22383
22384        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22385            // Create a native library symlink only if we have native libraries
22386            // and if the native libraries are 32 bit libraries. We do not provide
22387            // this symlink for 64 bit libraries.
22388            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22389                final String nativeLibPath = app.nativeLibraryDir;
22390                try {
22391                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22392                            nativeLibPath, userId);
22393                } catch (InstallerException e) {
22394                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22395                }
22396            }
22397        }
22398    }
22399
22400    /**
22401     * For system apps on non-FBE devices, this method migrates any existing
22402     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22403     * requested by the app.
22404     */
22405    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22406        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22407                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22408            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22409                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22410            try {
22411                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22412                        storageTarget);
22413            } catch (InstallerException e) {
22414                logCriticalInfo(Log.WARN,
22415                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22416            }
22417            return true;
22418        } else {
22419            return false;
22420        }
22421    }
22422
22423    public PackageFreezer freezePackage(String packageName, String killReason) {
22424        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22425    }
22426
22427    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22428        return new PackageFreezer(packageName, userId, killReason);
22429    }
22430
22431    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22432            String killReason) {
22433        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22434    }
22435
22436    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22437            String killReason) {
22438        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22439            return new PackageFreezer();
22440        } else {
22441            return freezePackage(packageName, userId, killReason);
22442        }
22443    }
22444
22445    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22446            String killReason) {
22447        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22448    }
22449
22450    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22451            String killReason) {
22452        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22453            return new PackageFreezer();
22454        } else {
22455            return freezePackage(packageName, userId, killReason);
22456        }
22457    }
22458
22459    /**
22460     * Class that freezes and kills the given package upon creation, and
22461     * unfreezes it upon closing. This is typically used when doing surgery on
22462     * app code/data to prevent the app from running while you're working.
22463     */
22464    private class PackageFreezer implements AutoCloseable {
22465        private final String mPackageName;
22466        private final PackageFreezer[] mChildren;
22467
22468        private final boolean mWeFroze;
22469
22470        private final AtomicBoolean mClosed = new AtomicBoolean();
22471        private final CloseGuard mCloseGuard = CloseGuard.get();
22472
22473        /**
22474         * Create and return a stub freezer that doesn't actually do anything,
22475         * typically used when someone requested
22476         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22477         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22478         */
22479        public PackageFreezer() {
22480            mPackageName = null;
22481            mChildren = null;
22482            mWeFroze = false;
22483            mCloseGuard.open("close");
22484        }
22485
22486        public PackageFreezer(String packageName, int userId, String killReason) {
22487            synchronized (mPackages) {
22488                mPackageName = packageName;
22489                mWeFroze = mFrozenPackages.add(mPackageName);
22490
22491                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22492                if (ps != null) {
22493                    killApplication(ps.name, ps.appId, userId, killReason);
22494                }
22495
22496                final PackageParser.Package p = mPackages.get(packageName);
22497                if (p != null && p.childPackages != null) {
22498                    final int N = p.childPackages.size();
22499                    mChildren = new PackageFreezer[N];
22500                    for (int i = 0; i < N; i++) {
22501                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22502                                userId, killReason);
22503                    }
22504                } else {
22505                    mChildren = null;
22506                }
22507            }
22508            mCloseGuard.open("close");
22509        }
22510
22511        @Override
22512        protected void finalize() throws Throwable {
22513            try {
22514                if (mCloseGuard != null) {
22515                    mCloseGuard.warnIfOpen();
22516                }
22517
22518                close();
22519            } finally {
22520                super.finalize();
22521            }
22522        }
22523
22524        @Override
22525        public void close() {
22526            mCloseGuard.close();
22527            if (mClosed.compareAndSet(false, true)) {
22528                synchronized (mPackages) {
22529                    if (mWeFroze) {
22530                        mFrozenPackages.remove(mPackageName);
22531                    }
22532
22533                    if (mChildren != null) {
22534                        for (PackageFreezer freezer : mChildren) {
22535                            freezer.close();
22536                        }
22537                    }
22538                }
22539            }
22540        }
22541    }
22542
22543    /**
22544     * Verify that given package is currently frozen.
22545     */
22546    private void checkPackageFrozen(String packageName) {
22547        synchronized (mPackages) {
22548            if (!mFrozenPackages.contains(packageName)) {
22549                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22550            }
22551        }
22552    }
22553
22554    @Override
22555    public int movePackage(final String packageName, final String volumeUuid) {
22556        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22557
22558        final int callingUid = Binder.getCallingUid();
22559        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22560        final int moveId = mNextMoveId.getAndIncrement();
22561        mHandler.post(new Runnable() {
22562            @Override
22563            public void run() {
22564                try {
22565                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22566                } catch (PackageManagerException e) {
22567                    Slog.w(TAG, "Failed to move " + packageName, e);
22568                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22569                }
22570            }
22571        });
22572        return moveId;
22573    }
22574
22575    private void movePackageInternal(final String packageName, final String volumeUuid,
22576            final int moveId, final int callingUid, UserHandle user)
22577                    throws PackageManagerException {
22578        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22579        final PackageManager pm = mContext.getPackageManager();
22580
22581        final boolean currentAsec;
22582        final String currentVolumeUuid;
22583        final File codeFile;
22584        final String installerPackageName;
22585        final String packageAbiOverride;
22586        final int appId;
22587        final String seinfo;
22588        final String label;
22589        final int targetSdkVersion;
22590        final PackageFreezer freezer;
22591        final int[] installedUserIds;
22592
22593        // reader
22594        synchronized (mPackages) {
22595            final PackageParser.Package pkg = mPackages.get(packageName);
22596            final PackageSetting ps = mSettings.mPackages.get(packageName);
22597            if (pkg == null
22598                    || ps == null
22599                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22600                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22601            }
22602            if (pkg.applicationInfo.isSystemApp()) {
22603                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22604                        "Cannot move system application");
22605            }
22606
22607            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22608            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22609                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22610            if (isInternalStorage && !allow3rdPartyOnInternal) {
22611                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22612                        "3rd party apps are not allowed on internal storage");
22613            }
22614
22615            if (pkg.applicationInfo.isExternalAsec()) {
22616                currentAsec = true;
22617                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22618            } else if (pkg.applicationInfo.isForwardLocked()) {
22619                currentAsec = true;
22620                currentVolumeUuid = "forward_locked";
22621            } else {
22622                currentAsec = false;
22623                currentVolumeUuid = ps.volumeUuid;
22624
22625                final File probe = new File(pkg.codePath);
22626                final File probeOat = new File(probe, "oat");
22627                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22628                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22629                            "Move only supported for modern cluster style installs");
22630                }
22631            }
22632
22633            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22634                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22635                        "Package already moved to " + volumeUuid);
22636            }
22637            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22638                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22639                        "Device admin cannot be moved");
22640            }
22641
22642            if (mFrozenPackages.contains(packageName)) {
22643                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22644                        "Failed to move already frozen package");
22645            }
22646
22647            codeFile = new File(pkg.codePath);
22648            installerPackageName = ps.installerPackageName;
22649            packageAbiOverride = ps.cpuAbiOverrideString;
22650            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22651            seinfo = pkg.applicationInfo.seInfo;
22652            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22653            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22654            freezer = freezePackage(packageName, "movePackageInternal");
22655            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22656        }
22657
22658        final Bundle extras = new Bundle();
22659        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22660        extras.putString(Intent.EXTRA_TITLE, label);
22661        mMoveCallbacks.notifyCreated(moveId, extras);
22662
22663        int installFlags;
22664        final boolean moveCompleteApp;
22665        final File measurePath;
22666
22667        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22668            installFlags = INSTALL_INTERNAL;
22669            moveCompleteApp = !currentAsec;
22670            measurePath = Environment.getDataAppDirectory(volumeUuid);
22671        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22672            installFlags = INSTALL_EXTERNAL;
22673            moveCompleteApp = false;
22674            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22675        } else {
22676            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22677            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22678                    || !volume.isMountedWritable()) {
22679                freezer.close();
22680                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22681                        "Move location not mounted private volume");
22682            }
22683
22684            Preconditions.checkState(!currentAsec);
22685
22686            installFlags = INSTALL_INTERNAL;
22687            moveCompleteApp = true;
22688            measurePath = Environment.getDataAppDirectory(volumeUuid);
22689        }
22690
22691        // If we're moving app data around, we need all the users unlocked
22692        if (moveCompleteApp) {
22693            for (int userId : installedUserIds) {
22694                if (StorageManager.isFileEncryptedNativeOrEmulated()
22695                        && !StorageManager.isUserKeyUnlocked(userId)) {
22696                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22697                            "User " + userId + " must be unlocked");
22698                }
22699            }
22700        }
22701
22702        final PackageStats stats = new PackageStats(null, -1);
22703        synchronized (mInstaller) {
22704            for (int userId : installedUserIds) {
22705                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22706                    freezer.close();
22707                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22708                            "Failed to measure package size");
22709                }
22710            }
22711        }
22712
22713        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22714                + stats.dataSize);
22715
22716        final long startFreeBytes = measurePath.getUsableSpace();
22717        final long sizeBytes;
22718        if (moveCompleteApp) {
22719            sizeBytes = stats.codeSize + stats.dataSize;
22720        } else {
22721            sizeBytes = stats.codeSize;
22722        }
22723
22724        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22725            freezer.close();
22726            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22727                    "Not enough free space to move");
22728        }
22729
22730        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22731
22732        final CountDownLatch installedLatch = new CountDownLatch(1);
22733        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22734            @Override
22735            public void onUserActionRequired(Intent intent) throws RemoteException {
22736                throw new IllegalStateException();
22737            }
22738
22739            @Override
22740            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22741                    Bundle extras) throws RemoteException {
22742                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22743                        + PackageManager.installStatusToString(returnCode, msg));
22744
22745                installedLatch.countDown();
22746                freezer.close();
22747
22748                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22749                switch (status) {
22750                    case PackageInstaller.STATUS_SUCCESS:
22751                        mMoveCallbacks.notifyStatusChanged(moveId,
22752                                PackageManager.MOVE_SUCCEEDED);
22753                        break;
22754                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22755                        mMoveCallbacks.notifyStatusChanged(moveId,
22756                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22757                        break;
22758                    default:
22759                        mMoveCallbacks.notifyStatusChanged(moveId,
22760                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22761                        break;
22762                }
22763            }
22764        };
22765
22766        final MoveInfo move;
22767        if (moveCompleteApp) {
22768            // Kick off a thread to report progress estimates
22769            new Thread() {
22770                @Override
22771                public void run() {
22772                    while (true) {
22773                        try {
22774                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22775                                break;
22776                            }
22777                        } catch (InterruptedException ignored) {
22778                        }
22779
22780                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22781                        final int progress = 10 + (int) MathUtils.constrain(
22782                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22783                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22784                    }
22785                }
22786            }.start();
22787
22788            final String dataAppName = codeFile.getName();
22789            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22790                    dataAppName, appId, seinfo, targetSdkVersion);
22791        } else {
22792            move = null;
22793        }
22794
22795        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22796
22797        final Message msg = mHandler.obtainMessage(INIT_COPY);
22798        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22799        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22800                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22801                packageAbiOverride, null /*grantedPermissions*/,
22802                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
22803        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22804        msg.obj = params;
22805
22806        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22807                System.identityHashCode(msg.obj));
22808        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22809                System.identityHashCode(msg.obj));
22810
22811        mHandler.sendMessage(msg);
22812    }
22813
22814    @Override
22815    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22816        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22817
22818        final int realMoveId = mNextMoveId.getAndIncrement();
22819        final Bundle extras = new Bundle();
22820        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22821        mMoveCallbacks.notifyCreated(realMoveId, extras);
22822
22823        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22824            @Override
22825            public void onCreated(int moveId, Bundle extras) {
22826                // Ignored
22827            }
22828
22829            @Override
22830            public void onStatusChanged(int moveId, int status, long estMillis) {
22831                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22832            }
22833        };
22834
22835        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22836        storage.setPrimaryStorageUuid(volumeUuid, callback);
22837        return realMoveId;
22838    }
22839
22840    @Override
22841    public int getMoveStatus(int moveId) {
22842        mContext.enforceCallingOrSelfPermission(
22843                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22844        return mMoveCallbacks.mLastStatus.get(moveId);
22845    }
22846
22847    @Override
22848    public void registerMoveCallback(IPackageMoveObserver callback) {
22849        mContext.enforceCallingOrSelfPermission(
22850                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22851        mMoveCallbacks.register(callback);
22852    }
22853
22854    @Override
22855    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22856        mContext.enforceCallingOrSelfPermission(
22857                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22858        mMoveCallbacks.unregister(callback);
22859    }
22860
22861    @Override
22862    public boolean setInstallLocation(int loc) {
22863        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22864                null);
22865        if (getInstallLocation() == loc) {
22866            return true;
22867        }
22868        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22869                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22870            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22871                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22872            return true;
22873        }
22874        return false;
22875   }
22876
22877    @Override
22878    public int getInstallLocation() {
22879        // allow instant app access
22880        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22881                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22882                PackageHelper.APP_INSTALL_AUTO);
22883    }
22884
22885    /** Called by UserManagerService */
22886    void cleanUpUser(UserManagerService userManager, int userHandle) {
22887        synchronized (mPackages) {
22888            mDirtyUsers.remove(userHandle);
22889            mUserNeedsBadging.delete(userHandle);
22890            mSettings.removeUserLPw(userHandle);
22891            mPendingBroadcasts.remove(userHandle);
22892            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22893            removeUnusedPackagesLPw(userManager, userHandle);
22894        }
22895    }
22896
22897    /**
22898     * We're removing userHandle and would like to remove any downloaded packages
22899     * that are no longer in use by any other user.
22900     * @param userHandle the user being removed
22901     */
22902    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22903        final boolean DEBUG_CLEAN_APKS = false;
22904        int [] users = userManager.getUserIds();
22905        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22906        while (psit.hasNext()) {
22907            PackageSetting ps = psit.next();
22908            if (ps.pkg == null) {
22909                continue;
22910            }
22911            final String packageName = ps.pkg.packageName;
22912            // Skip over if system app
22913            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22914                continue;
22915            }
22916            if (DEBUG_CLEAN_APKS) {
22917                Slog.i(TAG, "Checking package " + packageName);
22918            }
22919            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22920            if (keep) {
22921                if (DEBUG_CLEAN_APKS) {
22922                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22923                }
22924            } else {
22925                for (int i = 0; i < users.length; i++) {
22926                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22927                        keep = true;
22928                        if (DEBUG_CLEAN_APKS) {
22929                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22930                                    + users[i]);
22931                        }
22932                        break;
22933                    }
22934                }
22935            }
22936            if (!keep) {
22937                if (DEBUG_CLEAN_APKS) {
22938                    Slog.i(TAG, "  Removing package " + packageName);
22939                }
22940                mHandler.post(new Runnable() {
22941                    public void run() {
22942                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22943                                userHandle, 0);
22944                    } //end run
22945                });
22946            }
22947        }
22948    }
22949
22950    /** Called by UserManagerService */
22951    void createNewUser(int userId, String[] disallowedPackages) {
22952        synchronized (mInstallLock) {
22953            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22954        }
22955        synchronized (mPackages) {
22956            scheduleWritePackageRestrictionsLocked(userId);
22957            scheduleWritePackageListLocked(userId);
22958            applyFactoryDefaultBrowserLPw(userId);
22959            primeDomainVerificationsLPw(userId);
22960        }
22961    }
22962
22963    void onNewUserCreated(final int userId) {
22964        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22965        synchronized(mPackages) {
22966            // If permission review for legacy apps is required, we represent
22967            // dagerous permissions for such apps as always granted runtime
22968            // permissions to keep per user flag state whether review is needed.
22969            // Hence, if a new user is added we have to propagate dangerous
22970            // permission grants for these legacy apps.
22971            if (mSettings.mPermissions.mPermissionReviewRequired) {
22972// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22973                mPermissionManager.updateAllPermissions(
22974                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22975                        mPermissionCallback);
22976            }
22977        }
22978    }
22979
22980    @Override
22981    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22982        mContext.enforceCallingOrSelfPermission(
22983                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22984                "Only package verification agents can read the verifier device identity");
22985
22986        synchronized (mPackages) {
22987            return mSettings.getVerifierDeviceIdentityLPw();
22988        }
22989    }
22990
22991    @Override
22992    public void setPermissionEnforced(String permission, boolean enforced) {
22993        // TODO: Now that we no longer change GID for storage, this should to away.
22994        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22995                "setPermissionEnforced");
22996        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22997            synchronized (mPackages) {
22998                if (mSettings.mReadExternalStorageEnforced == null
22999                        || mSettings.mReadExternalStorageEnforced != enforced) {
23000                    mSettings.mReadExternalStorageEnforced =
23001                            enforced ? Boolean.TRUE : Boolean.FALSE;
23002                    mSettings.writeLPr();
23003                }
23004            }
23005            // kill any non-foreground processes so we restart them and
23006            // grant/revoke the GID.
23007            final IActivityManager am = ActivityManager.getService();
23008            if (am != null) {
23009                final long token = Binder.clearCallingIdentity();
23010                try {
23011                    am.killProcessesBelowForeground("setPermissionEnforcement");
23012                } catch (RemoteException e) {
23013                } finally {
23014                    Binder.restoreCallingIdentity(token);
23015                }
23016            }
23017        } else {
23018            throw new IllegalArgumentException("No selective enforcement for " + permission);
23019        }
23020    }
23021
23022    @Override
23023    @Deprecated
23024    public boolean isPermissionEnforced(String permission) {
23025        // allow instant applications
23026        return true;
23027    }
23028
23029    @Override
23030    public boolean isStorageLow() {
23031        // allow instant applications
23032        final long token = Binder.clearCallingIdentity();
23033        try {
23034            final DeviceStorageMonitorInternal
23035                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23036            if (dsm != null) {
23037                return dsm.isMemoryLow();
23038            } else {
23039                return false;
23040            }
23041        } finally {
23042            Binder.restoreCallingIdentity(token);
23043        }
23044    }
23045
23046    @Override
23047    public IPackageInstaller getPackageInstaller() {
23048        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23049            return null;
23050        }
23051        return mInstallerService;
23052    }
23053
23054    @Override
23055    public IArtManager getArtManager() {
23056        return mArtManagerService;
23057    }
23058
23059    private boolean userNeedsBadging(int userId) {
23060        int index = mUserNeedsBadging.indexOfKey(userId);
23061        if (index < 0) {
23062            final UserInfo userInfo;
23063            final long token = Binder.clearCallingIdentity();
23064            try {
23065                userInfo = sUserManager.getUserInfo(userId);
23066            } finally {
23067                Binder.restoreCallingIdentity(token);
23068            }
23069            final boolean b;
23070            if (userInfo != null && userInfo.isManagedProfile()) {
23071                b = true;
23072            } else {
23073                b = false;
23074            }
23075            mUserNeedsBadging.put(userId, b);
23076            return b;
23077        }
23078        return mUserNeedsBadging.valueAt(index);
23079    }
23080
23081    @Override
23082    public KeySet getKeySetByAlias(String packageName, String alias) {
23083        if (packageName == null || alias == null) {
23084            return null;
23085        }
23086        synchronized(mPackages) {
23087            final PackageParser.Package pkg = mPackages.get(packageName);
23088            if (pkg == null) {
23089                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23090                throw new IllegalArgumentException("Unknown package: " + packageName);
23091            }
23092            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23093            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23094                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23095                throw new IllegalArgumentException("Unknown package: " + packageName);
23096            }
23097            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23098            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23099        }
23100    }
23101
23102    @Override
23103    public KeySet getSigningKeySet(String packageName) {
23104        if (packageName == null) {
23105            return null;
23106        }
23107        synchronized(mPackages) {
23108            final int callingUid = Binder.getCallingUid();
23109            final int callingUserId = UserHandle.getUserId(callingUid);
23110            final PackageParser.Package pkg = mPackages.get(packageName);
23111            if (pkg == null) {
23112                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23113                throw new IllegalArgumentException("Unknown package: " + packageName);
23114            }
23115            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23116            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23117                // filter and pretend the package doesn't exist
23118                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23119                        + ", uid:" + callingUid);
23120                throw new IllegalArgumentException("Unknown package: " + packageName);
23121            }
23122            if (pkg.applicationInfo.uid != callingUid
23123                    && Process.SYSTEM_UID != callingUid) {
23124                throw new SecurityException("May not access signing KeySet of other apps.");
23125            }
23126            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23127            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23128        }
23129    }
23130
23131    @Override
23132    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23133        final int callingUid = Binder.getCallingUid();
23134        if (getInstantAppPackageName(callingUid) != null) {
23135            return false;
23136        }
23137        if (packageName == null || ks == null) {
23138            return false;
23139        }
23140        synchronized(mPackages) {
23141            final PackageParser.Package pkg = mPackages.get(packageName);
23142            if (pkg == null
23143                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23144                            UserHandle.getUserId(callingUid))) {
23145                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23146                throw new IllegalArgumentException("Unknown package: " + packageName);
23147            }
23148            IBinder ksh = ks.getToken();
23149            if (ksh instanceof KeySetHandle) {
23150                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23151                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23152            }
23153            return false;
23154        }
23155    }
23156
23157    @Override
23158    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23159        final int callingUid = Binder.getCallingUid();
23160        if (getInstantAppPackageName(callingUid) != null) {
23161            return false;
23162        }
23163        if (packageName == null || ks == null) {
23164            return false;
23165        }
23166        synchronized(mPackages) {
23167            final PackageParser.Package pkg = mPackages.get(packageName);
23168            if (pkg == null
23169                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23170                            UserHandle.getUserId(callingUid))) {
23171                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23172                throw new IllegalArgumentException("Unknown package: " + packageName);
23173            }
23174            IBinder ksh = ks.getToken();
23175            if (ksh instanceof KeySetHandle) {
23176                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23177                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23178            }
23179            return false;
23180        }
23181    }
23182
23183    private void deletePackageIfUnusedLPr(final String packageName) {
23184        PackageSetting ps = mSettings.mPackages.get(packageName);
23185        if (ps == null) {
23186            return;
23187        }
23188        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23189            // TODO Implement atomic delete if package is unused
23190            // It is currently possible that the package will be deleted even if it is installed
23191            // after this method returns.
23192            mHandler.post(new Runnable() {
23193                public void run() {
23194                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23195                            0, PackageManager.DELETE_ALL_USERS);
23196                }
23197            });
23198        }
23199    }
23200
23201    /**
23202     * Check and throw if the given before/after packages would be considered a
23203     * downgrade.
23204     */
23205    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23206            throws PackageManagerException {
23207        if (after.getLongVersionCode() < before.getLongVersionCode()) {
23208            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23209                    "Update version code " + after.versionCode + " is older than current "
23210                    + before.getLongVersionCode());
23211        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23212            if (after.baseRevisionCode < before.baseRevisionCode) {
23213                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23214                        "Update base revision code " + after.baseRevisionCode
23215                        + " is older than current " + before.baseRevisionCode);
23216            }
23217
23218            if (!ArrayUtils.isEmpty(after.splitNames)) {
23219                for (int i = 0; i < after.splitNames.length; i++) {
23220                    final String splitName = after.splitNames[i];
23221                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23222                    if (j != -1) {
23223                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23224                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23225                                    "Update split " + splitName + " revision code "
23226                                    + after.splitRevisionCodes[i] + " is older than current "
23227                                    + before.splitRevisionCodes[j]);
23228                        }
23229                    }
23230                }
23231            }
23232        }
23233    }
23234
23235    private static class MoveCallbacks extends Handler {
23236        private static final int MSG_CREATED = 1;
23237        private static final int MSG_STATUS_CHANGED = 2;
23238
23239        private final RemoteCallbackList<IPackageMoveObserver>
23240                mCallbacks = new RemoteCallbackList<>();
23241
23242        private final SparseIntArray mLastStatus = new SparseIntArray();
23243
23244        public MoveCallbacks(Looper looper) {
23245            super(looper);
23246        }
23247
23248        public void register(IPackageMoveObserver callback) {
23249            mCallbacks.register(callback);
23250        }
23251
23252        public void unregister(IPackageMoveObserver callback) {
23253            mCallbacks.unregister(callback);
23254        }
23255
23256        @Override
23257        public void handleMessage(Message msg) {
23258            final SomeArgs args = (SomeArgs) msg.obj;
23259            final int n = mCallbacks.beginBroadcast();
23260            for (int i = 0; i < n; i++) {
23261                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23262                try {
23263                    invokeCallback(callback, msg.what, args);
23264                } catch (RemoteException ignored) {
23265                }
23266            }
23267            mCallbacks.finishBroadcast();
23268            args.recycle();
23269        }
23270
23271        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23272                throws RemoteException {
23273            switch (what) {
23274                case MSG_CREATED: {
23275                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23276                    break;
23277                }
23278                case MSG_STATUS_CHANGED: {
23279                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23280                    break;
23281                }
23282            }
23283        }
23284
23285        private void notifyCreated(int moveId, Bundle extras) {
23286            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23287
23288            final SomeArgs args = SomeArgs.obtain();
23289            args.argi1 = moveId;
23290            args.arg2 = extras;
23291            obtainMessage(MSG_CREATED, args).sendToTarget();
23292        }
23293
23294        private void notifyStatusChanged(int moveId, int status) {
23295            notifyStatusChanged(moveId, status, -1);
23296        }
23297
23298        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23299            Slog.v(TAG, "Move " + moveId + " status " + status);
23300
23301            final SomeArgs args = SomeArgs.obtain();
23302            args.argi1 = moveId;
23303            args.argi2 = status;
23304            args.arg3 = estMillis;
23305            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23306
23307            synchronized (mLastStatus) {
23308                mLastStatus.put(moveId, status);
23309            }
23310        }
23311    }
23312
23313    private final static class OnPermissionChangeListeners extends Handler {
23314        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23315
23316        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23317                new RemoteCallbackList<>();
23318
23319        public OnPermissionChangeListeners(Looper looper) {
23320            super(looper);
23321        }
23322
23323        @Override
23324        public void handleMessage(Message msg) {
23325            switch (msg.what) {
23326                case MSG_ON_PERMISSIONS_CHANGED: {
23327                    final int uid = msg.arg1;
23328                    handleOnPermissionsChanged(uid);
23329                } break;
23330            }
23331        }
23332
23333        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23334            mPermissionListeners.register(listener);
23335
23336        }
23337
23338        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23339            mPermissionListeners.unregister(listener);
23340        }
23341
23342        public void onPermissionsChanged(int uid) {
23343            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23344                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23345            }
23346        }
23347
23348        private void handleOnPermissionsChanged(int uid) {
23349            final int count = mPermissionListeners.beginBroadcast();
23350            try {
23351                for (int i = 0; i < count; i++) {
23352                    IOnPermissionsChangeListener callback = mPermissionListeners
23353                            .getBroadcastItem(i);
23354                    try {
23355                        callback.onPermissionsChanged(uid);
23356                    } catch (RemoteException e) {
23357                        Log.e(TAG, "Permission listener is dead", e);
23358                    }
23359                }
23360            } finally {
23361                mPermissionListeners.finishBroadcast();
23362            }
23363        }
23364    }
23365
23366    private class PackageManagerNative extends IPackageManagerNative.Stub {
23367        @Override
23368        public String[] getNamesForUids(int[] uids) throws RemoteException {
23369            final String[] results = PackageManagerService.this.getNamesForUids(uids);
23370            // massage results so they can be parsed by the native binder
23371            for (int i = results.length - 1; i >= 0; --i) {
23372                if (results[i] == null) {
23373                    results[i] = "";
23374                }
23375            }
23376            return results;
23377        }
23378
23379        // NB: this differentiates between preloads and sideloads
23380        @Override
23381        public String getInstallerForPackage(String packageName) throws RemoteException {
23382            final String installerName = getInstallerPackageName(packageName);
23383            if (!TextUtils.isEmpty(installerName)) {
23384                return installerName;
23385            }
23386            // differentiate between preload and sideload
23387            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23388            ApplicationInfo appInfo = getApplicationInfo(packageName,
23389                                    /*flags*/ 0,
23390                                    /*userId*/ callingUser);
23391            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23392                return "preload";
23393            }
23394            return "";
23395        }
23396
23397        @Override
23398        public long getVersionCodeForPackage(String packageName) throws RemoteException {
23399            try {
23400                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23401                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
23402                if (pInfo != null) {
23403                    return pInfo.getLongVersionCode();
23404                }
23405            } catch (Exception e) {
23406            }
23407            return 0;
23408        }
23409    }
23410
23411    private class PackageManagerInternalImpl extends PackageManagerInternal {
23412        @Override
23413        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23414                int flagValues, int userId) {
23415            PackageManagerService.this.updatePermissionFlags(
23416                    permName, packageName, flagMask, flagValues, userId);
23417        }
23418
23419        @Override
23420        public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23421            SigningDetails sd = getSigningDetails(packageName);
23422            if (sd == null) {
23423                return false;
23424            }
23425            return sd.hasSha256Certificate(restoringFromSigHash,
23426                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23427        }
23428
23429        @Override
23430        public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23431            SigningDetails sd = getSigningDetails(packageName);
23432            if (sd == null) {
23433                return false;
23434            }
23435            return sd.hasCertificate(restoringFromSig,
23436                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23437        }
23438
23439        private SigningDetails getSigningDetails(@NonNull String packageName) {
23440            synchronized (mPackages) {
23441                PackageParser.Package p = mPackages.get(packageName);
23442                if (p == null) {
23443                    return null;
23444                }
23445                return p.mSigningDetails;
23446            }
23447        }
23448
23449        @Override
23450        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23451            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23452        }
23453
23454        @Override
23455        public boolean isInstantApp(String packageName, int userId) {
23456            return PackageManagerService.this.isInstantApp(packageName, userId);
23457        }
23458
23459        @Override
23460        public String getInstantAppPackageName(int uid) {
23461            return PackageManagerService.this.getInstantAppPackageName(uid);
23462        }
23463
23464        @Override
23465        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23466            synchronized (mPackages) {
23467                return PackageManagerService.this.filterAppAccessLPr(
23468                        (PackageSetting) pkg.mExtras, callingUid, userId);
23469            }
23470        }
23471
23472        @Override
23473        public PackageParser.Package getPackage(String packageName) {
23474            synchronized (mPackages) {
23475                packageName = resolveInternalPackageNameLPr(
23476                        packageName, PackageManager.VERSION_CODE_HIGHEST);
23477                return mPackages.get(packageName);
23478            }
23479        }
23480
23481        @Override
23482        public PackageList getPackageList(PackageListObserver observer) {
23483            synchronized (mPackages) {
23484                final int N = mPackages.size();
23485                final ArrayList<String> list = new ArrayList<>(N);
23486                for (int i = 0; i < N; i++) {
23487                    list.add(mPackages.keyAt(i));
23488                }
23489                final PackageList packageList = new PackageList(list, observer);
23490                if (observer != null) {
23491                    mPackageListObservers.add(packageList);
23492                }
23493                return packageList;
23494            }
23495        }
23496
23497        @Override
23498        public void removePackageListObserver(PackageListObserver observer) {
23499            synchronized (mPackages) {
23500                mPackageListObservers.remove(observer);
23501            }
23502        }
23503
23504        @Override
23505        public PackageParser.Package getDisabledPackage(String packageName) {
23506            synchronized (mPackages) {
23507                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
23508                return (ps != null) ? ps.pkg : null;
23509            }
23510        }
23511
23512        @Override
23513        public String getKnownPackageName(int knownPackage, int userId) {
23514            switch(knownPackage) {
23515                case PackageManagerInternal.PACKAGE_BROWSER:
23516                    return getDefaultBrowserPackageName(userId);
23517                case PackageManagerInternal.PACKAGE_INSTALLER:
23518                    return mRequiredInstallerPackage;
23519                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23520                    return mSetupWizardPackage;
23521                case PackageManagerInternal.PACKAGE_SYSTEM:
23522                    return "android";
23523                case PackageManagerInternal.PACKAGE_VERIFIER:
23524                    return mRequiredVerifierPackage;
23525                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23526                    return mSystemTextClassifierPackage;
23527            }
23528            return null;
23529        }
23530
23531        @Override
23532        public boolean isResolveActivityComponent(ComponentInfo component) {
23533            return mResolveActivity.packageName.equals(component.packageName)
23534                    && mResolveActivity.name.equals(component.name);
23535        }
23536
23537        @Override
23538        public void setLocationPackagesProvider(PackagesProvider provider) {
23539            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
23540        }
23541
23542        @Override
23543        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23544            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
23545        }
23546
23547        @Override
23548        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23549            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
23550        }
23551
23552        @Override
23553        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23554            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
23555        }
23556
23557        @Override
23558        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23559            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
23560        }
23561
23562        @Override
23563        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
23564            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
23565        }
23566
23567        @Override
23568        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23569            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
23570        }
23571
23572        @Override
23573        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23574            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
23575        }
23576
23577        @Override
23578        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23579            synchronized (mPackages) {
23580                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23581            }
23582            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
23583        }
23584
23585        @Override
23586        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23587            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
23588                    packageName, userId);
23589        }
23590
23591        @Override
23592        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
23593            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
23594                    packageName, userId);
23595        }
23596
23597        @Override
23598        public void setKeepUninstalledPackages(final List<String> packageList) {
23599            Preconditions.checkNotNull(packageList);
23600            List<String> removedFromList = null;
23601            synchronized (mPackages) {
23602                if (mKeepUninstalledPackages != null) {
23603                    final int packagesCount = mKeepUninstalledPackages.size();
23604                    for (int i = 0; i < packagesCount; i++) {
23605                        String oldPackage = mKeepUninstalledPackages.get(i);
23606                        if (packageList != null && packageList.contains(oldPackage)) {
23607                            continue;
23608                        }
23609                        if (removedFromList == null) {
23610                            removedFromList = new ArrayList<>();
23611                        }
23612                        removedFromList.add(oldPackage);
23613                    }
23614                }
23615                mKeepUninstalledPackages = new ArrayList<>(packageList);
23616                if (removedFromList != null) {
23617                    final int removedCount = removedFromList.size();
23618                    for (int i = 0; i < removedCount; i++) {
23619                        deletePackageIfUnusedLPr(removedFromList.get(i));
23620                    }
23621                }
23622            }
23623        }
23624
23625        @Override
23626        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23627            synchronized (mPackages) {
23628                return mPermissionManager.isPermissionsReviewRequired(
23629                        mPackages.get(packageName), userId);
23630            }
23631        }
23632
23633        @Override
23634        public PackageInfo getPackageInfo(
23635                String packageName, int flags, int filterCallingUid, int userId) {
23636            return PackageManagerService.this
23637                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23638                            flags, filterCallingUid, userId);
23639        }
23640
23641        @Override
23642        public int getPackageUid(String packageName, int flags, int userId) {
23643            return PackageManagerService.this
23644                    .getPackageUid(packageName, flags, userId);
23645        }
23646
23647        @Override
23648        public ApplicationInfo getApplicationInfo(
23649                String packageName, int flags, int filterCallingUid, int userId) {
23650            return PackageManagerService.this
23651                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23652        }
23653
23654        @Override
23655        public ActivityInfo getActivityInfo(
23656                ComponentName component, int flags, int filterCallingUid, int userId) {
23657            return PackageManagerService.this
23658                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23659        }
23660
23661        @Override
23662        public List<ResolveInfo> queryIntentActivities(
23663                Intent intent, int flags, int filterCallingUid, int userId) {
23664            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23665            return PackageManagerService.this
23666                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23667                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23668        }
23669
23670        @Override
23671        public List<ResolveInfo> queryIntentServices(
23672                Intent intent, int flags, int callingUid, int userId) {
23673            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23674            return PackageManagerService.this
23675                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23676                            false);
23677        }
23678
23679        @Override
23680        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23681                int userId) {
23682            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23683        }
23684
23685        @Override
23686        public ComponentName getDefaultHomeActivity(int userId) {
23687            return PackageManagerService.this.getDefaultHomeActivity(userId);
23688        }
23689
23690        @Override
23691        public void setDeviceAndProfileOwnerPackages(
23692                int deviceOwnerUserId, String deviceOwnerPackage,
23693                SparseArray<String> profileOwnerPackages) {
23694            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23695                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23696        }
23697
23698        @Override
23699        public boolean isPackageDataProtected(int userId, String packageName) {
23700            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23701        }
23702
23703        @Override
23704        public boolean isPackageEphemeral(int userId, String packageName) {
23705            synchronized (mPackages) {
23706                final PackageSetting ps = mSettings.mPackages.get(packageName);
23707                return ps != null ? ps.getInstantApp(userId) : false;
23708            }
23709        }
23710
23711        @Override
23712        public boolean wasPackageEverLaunched(String packageName, int userId) {
23713            synchronized (mPackages) {
23714                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23715            }
23716        }
23717
23718        @Override
23719        public void grantRuntimePermission(String packageName, String permName, int userId,
23720                boolean overridePolicy) {
23721            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23722                    permName, packageName, overridePolicy, getCallingUid(), userId,
23723                    mPermissionCallback);
23724        }
23725
23726        @Override
23727        public void revokeRuntimePermission(String packageName, String permName, int userId,
23728                boolean overridePolicy) {
23729            mPermissionManager.revokeRuntimePermission(
23730                    permName, packageName, overridePolicy, getCallingUid(), userId,
23731                    mPermissionCallback);
23732        }
23733
23734        @Override
23735        public String getNameForUid(int uid) {
23736            return PackageManagerService.this.getNameForUid(uid);
23737        }
23738
23739        @Override
23740        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23741                Intent origIntent, String resolvedType, String callingPackage,
23742                Bundle verificationBundle, int userId) {
23743            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23744                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23745                    userId);
23746        }
23747
23748        @Override
23749        public void grantEphemeralAccess(int userId, Intent intent,
23750                int targetAppId, int ephemeralAppId) {
23751            synchronized (mPackages) {
23752                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23753                        targetAppId, ephemeralAppId);
23754            }
23755        }
23756
23757        @Override
23758        public boolean isInstantAppInstallerComponent(ComponentName component) {
23759            synchronized (mPackages) {
23760                return mInstantAppInstallerActivity != null
23761                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23762            }
23763        }
23764
23765        @Override
23766        public void pruneInstantApps() {
23767            mInstantAppRegistry.pruneInstantApps();
23768        }
23769
23770        @Override
23771        public String getSetupWizardPackageName() {
23772            return mSetupWizardPackage;
23773        }
23774
23775        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23776            if (policy != null) {
23777                mExternalSourcesPolicy = policy;
23778            }
23779        }
23780
23781        @Override
23782        public boolean isPackagePersistent(String packageName) {
23783            synchronized (mPackages) {
23784                PackageParser.Package pkg = mPackages.get(packageName);
23785                return pkg != null
23786                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23787                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23788                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23789                        : false;
23790            }
23791        }
23792
23793        @Override
23794        public boolean isLegacySystemApp(Package pkg) {
23795            synchronized (mPackages) {
23796                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23797                return mPromoteSystemApps
23798                        && ps.isSystem()
23799                        && mExistingSystemPackages.contains(ps.name);
23800            }
23801        }
23802
23803        @Override
23804        public List<PackageInfo> getOverlayPackages(int userId) {
23805            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23806            synchronized (mPackages) {
23807                for (PackageParser.Package p : mPackages.values()) {
23808                    if (p.mOverlayTarget != null) {
23809                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23810                        if (pkg != null) {
23811                            overlayPackages.add(pkg);
23812                        }
23813                    }
23814                }
23815            }
23816            return overlayPackages;
23817        }
23818
23819        @Override
23820        public List<String> getTargetPackageNames(int userId) {
23821            List<String> targetPackages = new ArrayList<>();
23822            synchronized (mPackages) {
23823                for (PackageParser.Package p : mPackages.values()) {
23824                    if (p.mOverlayTarget == null) {
23825                        targetPackages.add(p.packageName);
23826                    }
23827                }
23828            }
23829            return targetPackages;
23830        }
23831
23832        @Override
23833        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23834                @Nullable List<String> overlayPackageNames) {
23835            synchronized (mPackages) {
23836                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23837                    Slog.e(TAG, "failed to find package " + targetPackageName);
23838                    return false;
23839                }
23840                ArrayList<String> overlayPaths = null;
23841                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23842                    final int N = overlayPackageNames.size();
23843                    overlayPaths = new ArrayList<>(N);
23844                    for (int i = 0; i < N; i++) {
23845                        final String packageName = overlayPackageNames.get(i);
23846                        final PackageParser.Package pkg = mPackages.get(packageName);
23847                        if (pkg == null) {
23848                            Slog.e(TAG, "failed to find package " + packageName);
23849                            return false;
23850                        }
23851                        overlayPaths.add(pkg.baseCodePath);
23852                    }
23853                }
23854
23855                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23856                ps.setOverlayPaths(overlayPaths, userId);
23857                return true;
23858            }
23859        }
23860
23861        @Override
23862        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23863                int flags, int userId, boolean resolveForStart) {
23864            return resolveIntentInternal(
23865                    intent, resolvedType, flags, userId, resolveForStart);
23866        }
23867
23868        @Override
23869        public ResolveInfo resolveService(Intent intent, String resolvedType,
23870                int flags, int userId, int callingUid) {
23871            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23872        }
23873
23874        @Override
23875        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23876            return PackageManagerService.this.resolveContentProviderInternal(
23877                    name, flags, userId);
23878        }
23879
23880        @Override
23881        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23882            synchronized (mPackages) {
23883                mIsolatedOwners.put(isolatedUid, ownerUid);
23884            }
23885        }
23886
23887        @Override
23888        public void removeIsolatedUid(int isolatedUid) {
23889            synchronized (mPackages) {
23890                mIsolatedOwners.delete(isolatedUid);
23891            }
23892        }
23893
23894        @Override
23895        public int getUidTargetSdkVersion(int uid) {
23896            synchronized (mPackages) {
23897                return getUidTargetSdkVersionLockedLPr(uid);
23898            }
23899        }
23900
23901        @Override
23902        public int getPackageTargetSdkVersion(String packageName) {
23903            synchronized (mPackages) {
23904                return getPackageTargetSdkVersionLockedLPr(packageName);
23905            }
23906        }
23907
23908        @Override
23909        public boolean canAccessInstantApps(int callingUid, int userId) {
23910            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23911        }
23912
23913        @Override
23914        public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
23915            synchronized (mPackages) {
23916                final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
23917                return !PackageManagerService.this.filterAppAccessLPr(
23918                        ps, callingUid, component, TYPE_UNKNOWN, userId);
23919            }
23920        }
23921
23922        @Override
23923        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23924            synchronized (mPackages) {
23925                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23926            }
23927        }
23928
23929        @Override
23930        public void notifyPackageUse(String packageName, int reason) {
23931            synchronized (mPackages) {
23932                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23933            }
23934        }
23935    }
23936
23937    @Override
23938    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23939        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23940        synchronized (mPackages) {
23941            final long identity = Binder.clearCallingIdentity();
23942            try {
23943                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23944                        packageNames, userId);
23945            } finally {
23946                Binder.restoreCallingIdentity(identity);
23947            }
23948        }
23949    }
23950
23951    @Override
23952    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23953        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23954        synchronized (mPackages) {
23955            final long identity = Binder.clearCallingIdentity();
23956            try {
23957                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23958                        packageNames, userId);
23959            } finally {
23960                Binder.restoreCallingIdentity(identity);
23961            }
23962        }
23963    }
23964
23965    private static void enforceSystemOrPhoneCaller(String tag) {
23966        int callingUid = Binder.getCallingUid();
23967        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23968            throw new SecurityException(
23969                    "Cannot call " + tag + " from UID " + callingUid);
23970        }
23971    }
23972
23973    boolean isHistoricalPackageUsageAvailable() {
23974        return mPackageUsage.isHistoricalPackageUsageAvailable();
23975    }
23976
23977    /**
23978     * Return a <b>copy</b> of the collection of packages known to the package manager.
23979     * @return A copy of the values of mPackages.
23980     */
23981    Collection<PackageParser.Package> getPackages() {
23982        synchronized (mPackages) {
23983            return new ArrayList<>(mPackages.values());
23984        }
23985    }
23986
23987    /**
23988     * Logs process start information (including base APK hash) to the security log.
23989     * @hide
23990     */
23991    @Override
23992    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23993            String apkFile, int pid) {
23994        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23995            return;
23996        }
23997        if (!SecurityLog.isLoggingEnabled()) {
23998            return;
23999        }
24000        Bundle data = new Bundle();
24001        data.putLong("startTimestamp", System.currentTimeMillis());
24002        data.putString("processName", processName);
24003        data.putInt("uid", uid);
24004        data.putString("seinfo", seinfo);
24005        data.putString("apkFile", apkFile);
24006        data.putInt("pid", pid);
24007        Message msg = mProcessLoggingHandler.obtainMessage(
24008                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24009        msg.setData(data);
24010        mProcessLoggingHandler.sendMessage(msg);
24011    }
24012
24013    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24014        return mCompilerStats.getPackageStats(pkgName);
24015    }
24016
24017    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24018        return getOrCreateCompilerPackageStats(pkg.packageName);
24019    }
24020
24021    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24022        return mCompilerStats.getOrCreatePackageStats(pkgName);
24023    }
24024
24025    public void deleteCompilerPackageStats(String pkgName) {
24026        mCompilerStats.deletePackageStats(pkgName);
24027    }
24028
24029    @Override
24030    public int getInstallReason(String packageName, int userId) {
24031        final int callingUid = Binder.getCallingUid();
24032        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24033                true /* requireFullPermission */, false /* checkShell */,
24034                "get install reason");
24035        synchronized (mPackages) {
24036            final PackageSetting ps = mSettings.mPackages.get(packageName);
24037            if (filterAppAccessLPr(ps, callingUid, userId)) {
24038                return PackageManager.INSTALL_REASON_UNKNOWN;
24039            }
24040            if (ps != null) {
24041                return ps.getInstallReason(userId);
24042            }
24043        }
24044        return PackageManager.INSTALL_REASON_UNKNOWN;
24045    }
24046
24047    @Override
24048    public boolean canRequestPackageInstalls(String packageName, int userId) {
24049        return canRequestPackageInstallsInternal(packageName, 0, userId,
24050                true /* throwIfPermNotDeclared*/);
24051    }
24052
24053    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24054            boolean throwIfPermNotDeclared) {
24055        int callingUid = Binder.getCallingUid();
24056        int uid = getPackageUid(packageName, 0, userId);
24057        if (callingUid != uid && callingUid != Process.ROOT_UID
24058                && callingUid != Process.SYSTEM_UID) {
24059            throw new SecurityException(
24060                    "Caller uid " + callingUid + " does not own package " + packageName);
24061        }
24062        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24063        if (info == null) {
24064            return false;
24065        }
24066        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24067            return false;
24068        }
24069        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24070        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24071        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24072            if (throwIfPermNotDeclared) {
24073                throw new SecurityException("Need to declare " + appOpPermission
24074                        + " to call this api");
24075            } else {
24076                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24077                return false;
24078            }
24079        }
24080        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24081            return false;
24082        }
24083        if (mExternalSourcesPolicy != null) {
24084            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24085            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24086                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24087            }
24088        }
24089        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24090    }
24091
24092    @Override
24093    public ComponentName getInstantAppResolverSettingsComponent() {
24094        return mInstantAppResolverSettingsComponent;
24095    }
24096
24097    @Override
24098    public ComponentName getInstantAppInstallerComponent() {
24099        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24100            return null;
24101        }
24102        return mInstantAppInstallerActivity == null
24103                ? null : mInstantAppInstallerActivity.getComponentName();
24104    }
24105
24106    @Override
24107    public String getInstantAppAndroidId(String packageName, int userId) {
24108        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24109                "getInstantAppAndroidId");
24110        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24111                true /* requireFullPermission */, false /* checkShell */,
24112                "getInstantAppAndroidId");
24113        // Make sure the target is an Instant App.
24114        if (!isInstantApp(packageName, userId)) {
24115            return null;
24116        }
24117        synchronized (mPackages) {
24118            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24119        }
24120    }
24121
24122    boolean canHaveOatDir(String packageName) {
24123        synchronized (mPackages) {
24124            PackageParser.Package p = mPackages.get(packageName);
24125            if (p == null) {
24126                return false;
24127            }
24128            return p.canHaveOatDir();
24129        }
24130    }
24131
24132    private String getOatDir(PackageParser.Package pkg) {
24133        if (!pkg.canHaveOatDir()) {
24134            return null;
24135        }
24136        File codePath = new File(pkg.codePath);
24137        if (codePath.isDirectory()) {
24138            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24139        }
24140        return null;
24141    }
24142
24143    void deleteOatArtifactsOfPackage(String packageName) {
24144        final String[] instructionSets;
24145        final List<String> codePaths;
24146        final String oatDir;
24147        final PackageParser.Package pkg;
24148        synchronized (mPackages) {
24149            pkg = mPackages.get(packageName);
24150        }
24151        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24152        codePaths = pkg.getAllCodePaths();
24153        oatDir = getOatDir(pkg);
24154
24155        for (String codePath : codePaths) {
24156            for (String isa : instructionSets) {
24157                try {
24158                    mInstaller.deleteOdex(codePath, isa, oatDir);
24159                } catch (InstallerException e) {
24160                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24161                }
24162            }
24163        }
24164    }
24165
24166    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24167        Set<String> unusedPackages = new HashSet<>();
24168        long currentTimeInMillis = System.currentTimeMillis();
24169        synchronized (mPackages) {
24170            for (PackageParser.Package pkg : mPackages.values()) {
24171                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
24172                if (ps == null) {
24173                    continue;
24174                }
24175                PackageDexUsage.PackageUseInfo packageUseInfo =
24176                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24177                if (PackageManagerServiceUtils
24178                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24179                                downgradeTimeThresholdMillis, packageUseInfo,
24180                                pkg.getLatestPackageUseTimeInMills(),
24181                                pkg.getLatestForegroundPackageUseTimeInMills())) {
24182                    unusedPackages.add(pkg.packageName);
24183                }
24184            }
24185        }
24186        return unusedPackages;
24187    }
24188
24189    @Override
24190    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24191            int userId) {
24192        final int callingUid = Binder.getCallingUid();
24193        final int callingAppId = UserHandle.getAppId(callingUid);
24194
24195        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24196                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24197
24198        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24199                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24200            throw new SecurityException("Caller must have the "
24201                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24202        }
24203
24204        synchronized(mPackages) {
24205            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24206            scheduleWritePackageRestrictionsLocked(userId);
24207        }
24208    }
24209
24210    @Nullable
24211    @Override
24212    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24213        final int callingUid = Binder.getCallingUid();
24214        final int callingAppId = UserHandle.getAppId(callingUid);
24215
24216        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24217                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24218
24219        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24220                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24221            throw new SecurityException("Caller must have the "
24222                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24223        }
24224
24225        synchronized(mPackages) {
24226            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24227        }
24228    }
24229}
24230
24231interface PackageSender {
24232    /**
24233     * @param userIds User IDs where the action occurred on a full application
24234     * @param instantUserIds User IDs where the action occurred on an instant application
24235     */
24236    void sendPackageBroadcast(final String action, final String pkg,
24237        final Bundle extras, final int flags, final String targetPkg,
24238        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24239    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24240        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24241    void notifyPackageAdded(String packageName);
24242    void notifyPackageRemoved(String packageName);
24243}
24244