PackageManagerService.java revision e839d709c2e53ae11e568fc5ae93030fc11a1a59
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.COMPONENT_ENABLED_STATE_DEFAULT;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
31import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
32import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
40import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
41import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
42import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
44import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
49import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
50import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
51import static android.content.pm.PackageManager.INSTALL_FAILED_NEWER_SDK;
52import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
53import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
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_USER_RESTRICTED;
59import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
60import static android.content.pm.PackageManager.INSTALL_INTERNAL;
61import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
66import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
67import static android.content.pm.PackageManager.MATCH_ALL;
68import static android.content.pm.PackageManager.MATCH_ANY_USER;
69import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
71import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
72import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
73import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
74import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
75import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
76import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
77import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
78import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
79import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
80import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
81import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
82import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
83import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
84import static android.content.pm.PackageManager.PERMISSION_DENIED;
85import static android.content.pm.PackageManager.PERMISSION_GRANTED;
86import static android.content.pm.PackageParser.isApkFile;
87import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
89import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
90import static android.system.OsConstants.O_CREAT;
91import static android.system.OsConstants.O_RDWR;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
93import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
94import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
95import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
96import static com.android.internal.util.ArrayUtils.appendInt;
97import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
99import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
100import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
101import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
103import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
104import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
105import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
106import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
107import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
108import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
109import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
110import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
111import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
112import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
114import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
115import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
116
117import android.Manifest;
118import android.annotation.IntDef;
119import android.annotation.NonNull;
120import android.annotation.Nullable;
121import android.app.ActivityManager;
122import android.app.ActivityManagerInternal;
123import android.app.AppOpsManager;
124import android.app.IActivityManager;
125import android.app.ResourcesManager;
126import android.app.admin.IDevicePolicyManager;
127import android.app.admin.SecurityLog;
128import android.app.backup.IBackupManager;
129import android.content.BroadcastReceiver;
130import android.content.ComponentName;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.IIntentReceiver;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.IntentSender.SendIntentException;
138import android.content.ServiceConnection;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.AppsQueryHelper;
142import android.content.pm.AuxiliaryResolveInfo;
143import android.content.pm.ChangedPackages;
144import android.content.pm.ComponentInfo;
145import android.content.pm.FallbackCategoryProvider;
146import android.content.pm.FeatureInfo;
147import android.content.pm.IDexModuleRegisterCallback;
148import android.content.pm.IOnPermissionsChangeListener;
149import android.content.pm.IPackageDataObserver;
150import android.content.pm.IPackageDeleteObserver;
151import android.content.pm.IPackageDeleteObserver2;
152import android.content.pm.IPackageInstallObserver2;
153import android.content.pm.IPackageInstaller;
154import android.content.pm.IPackageManager;
155import android.content.pm.IPackageManagerNative;
156import android.content.pm.IPackageMoveObserver;
157import android.content.pm.IPackageStatsObserver;
158import android.content.pm.InstantAppInfo;
159import android.content.pm.InstantAppRequest;
160import android.content.pm.InstantAppResolveInfo;
161import android.content.pm.InstrumentationInfo;
162import android.content.pm.IntentFilterVerificationInfo;
163import android.content.pm.KeySet;
164import android.content.pm.PackageCleanItem;
165import android.content.pm.PackageInfo;
166import android.content.pm.PackageInfoLite;
167import android.content.pm.PackageInstaller;
168import android.content.pm.PackageList;
169import android.content.pm.PackageManager;
170import android.content.pm.PackageManagerInternal;
171import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
172import android.content.pm.PackageManagerInternal.PackageListObserver;
173import android.content.pm.PackageParser;
174import android.content.pm.PackageParser.ActivityIntentInfo;
175import android.content.pm.PackageParser.Package;
176import android.content.pm.PackageParser.PackageLite;
177import android.content.pm.PackageParser.PackageParserException;
178import android.content.pm.PackageParser.ParseFlags;
179import android.content.pm.PackageParser.ServiceIntentInfo;
180import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
181import android.content.pm.PackageStats;
182import android.content.pm.PackageUserState;
183import android.content.pm.ParceledListSlice;
184import android.content.pm.PermissionGroupInfo;
185import android.content.pm.PermissionInfo;
186import android.content.pm.ProviderInfo;
187import android.content.pm.ResolveInfo;
188import android.content.pm.ServiceInfo;
189import android.content.pm.SharedLibraryInfo;
190import android.content.pm.Signature;
191import android.content.pm.UserInfo;
192import android.content.pm.VerifierDeviceIdentity;
193import android.content.pm.VerifierInfo;
194import android.content.pm.VersionedPackage;
195import android.content.pm.dex.DexMetadataHelper;
196import android.content.pm.dex.IArtManager;
197import android.content.res.Resources;
198import android.database.ContentObserver;
199import android.graphics.Bitmap;
200import android.hardware.display.DisplayManager;
201import android.net.Uri;
202import android.os.Binder;
203import android.os.Build;
204import android.os.Bundle;
205import android.os.Debug;
206import android.os.Environment;
207import android.os.Environment.UserEnvironment;
208import android.os.FileUtils;
209import android.os.Handler;
210import android.os.IBinder;
211import android.os.Looper;
212import android.os.Message;
213import android.os.Parcel;
214import android.os.ParcelFileDescriptor;
215import android.os.PatternMatcher;
216import android.os.Process;
217import android.os.RemoteCallbackList;
218import android.os.RemoteException;
219import android.os.ResultReceiver;
220import android.os.SELinux;
221import android.os.ServiceManager;
222import android.os.ShellCallback;
223import android.os.SystemClock;
224import android.os.SystemProperties;
225import android.os.Trace;
226import android.os.UserHandle;
227import android.os.UserManager;
228import android.os.UserManagerInternal;
229import android.os.storage.IStorageManager;
230import android.os.storage.StorageEventListener;
231import android.os.storage.StorageManager;
232import android.os.storage.StorageManagerInternal;
233import android.os.storage.VolumeInfo;
234import android.os.storage.VolumeRecord;
235import android.provider.Settings.Global;
236import android.provider.Settings.Secure;
237import android.security.KeyStore;
238import android.security.SystemKeyStore;
239import android.service.pm.PackageServiceDumpProto;
240import android.system.ErrnoException;
241import android.system.Os;
242import android.text.TextUtils;
243import android.text.format.DateUtils;
244import android.util.ArrayMap;
245import android.util.ArraySet;
246import android.util.Base64;
247import android.util.DisplayMetrics;
248import android.util.EventLog;
249import android.util.ExceptionUtils;
250import android.util.Log;
251import android.util.LogPrinter;
252import android.util.LongSparseArray;
253import android.util.LongSparseLongArray;
254import android.util.MathUtils;
255import android.util.PackageUtils;
256import android.util.Pair;
257import android.util.PrintStreamPrinter;
258import android.util.Slog;
259import android.util.SparseArray;
260import android.util.SparseBooleanArray;
261import android.util.SparseIntArray;
262import android.util.TimingsTraceLog;
263import android.util.Xml;
264import android.util.jar.StrictJarFile;
265import android.util.proto.ProtoOutputStream;
266import android.view.Display;
267
268import com.android.internal.R;
269import com.android.internal.annotations.GuardedBy;
270import com.android.internal.app.IMediaContainerService;
271import com.android.internal.app.ResolverActivity;
272import com.android.internal.content.NativeLibraryHelper;
273import com.android.internal.content.PackageHelper;
274import com.android.internal.logging.MetricsLogger;
275import com.android.internal.os.IParcelFileDescriptorFactory;
276import com.android.internal.os.SomeArgs;
277import com.android.internal.os.Zygote;
278import com.android.internal.telephony.CarrierAppUtils;
279import com.android.internal.util.ArrayUtils;
280import com.android.internal.util.ConcurrentUtils;
281import com.android.internal.util.DumpUtils;
282import com.android.internal.util.FastXmlSerializer;
283import com.android.internal.util.IndentingPrintWriter;
284import com.android.internal.util.Preconditions;
285import com.android.internal.util.XmlUtils;
286import com.android.server.AttributeCache;
287import com.android.server.DeviceIdleController;
288import com.android.server.EventLogTags;
289import com.android.server.FgThread;
290import com.android.server.IntentResolver;
291import com.android.server.LocalServices;
292import com.android.server.LockGuard;
293import com.android.server.ServiceThread;
294import com.android.server.SystemConfig;
295import com.android.server.SystemServerInitThreadPool;
296import com.android.server.Watchdog;
297import com.android.server.net.NetworkPolicyManagerInternal;
298import com.android.server.pm.Installer.InstallerException;
299import com.android.server.pm.Settings.DatabaseVersion;
300import com.android.server.pm.Settings.VersionInfo;
301import com.android.server.pm.dex.ArtManagerService;
302import com.android.server.pm.dex.DexLogger;
303import com.android.server.pm.dex.DexManager;
304import com.android.server.pm.dex.DexoptOptions;
305import com.android.server.pm.dex.PackageDexUsage;
306import com.android.server.pm.permission.BasePermission;
307import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
308import com.android.server.pm.permission.PermissionManagerService;
309import com.android.server.pm.permission.PermissionManagerInternal;
310import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
311import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
312import com.android.server.pm.permission.PermissionsState;
313import com.android.server.pm.permission.PermissionsState.PermissionState;
314import com.android.server.storage.DeviceStorageMonitorInternal;
315
316import dalvik.system.CloseGuard;
317import dalvik.system.VMRuntime;
318
319import libcore.io.IoUtils;
320
321import org.xmlpull.v1.XmlPullParser;
322import org.xmlpull.v1.XmlPullParserException;
323import org.xmlpull.v1.XmlSerializer;
324
325import java.io.BufferedOutputStream;
326import java.io.ByteArrayInputStream;
327import java.io.ByteArrayOutputStream;
328import java.io.File;
329import java.io.FileDescriptor;
330import java.io.FileInputStream;
331import java.io.FileOutputStream;
332import java.io.FilenameFilter;
333import java.io.IOException;
334import java.io.PrintWriter;
335import java.lang.annotation.Retention;
336import java.lang.annotation.RetentionPolicy;
337import java.nio.charset.StandardCharsets;
338import java.security.DigestInputStream;
339import java.security.MessageDigest;
340import java.security.NoSuchAlgorithmException;
341import java.security.PublicKey;
342import java.security.SecureRandom;
343import java.security.cert.CertificateException;
344import java.util.ArrayList;
345import java.util.Arrays;
346import java.util.Collection;
347import java.util.Collections;
348import java.util.Comparator;
349import java.util.HashMap;
350import java.util.HashSet;
351import java.util.Iterator;
352import java.util.LinkedHashSet;
353import java.util.List;
354import java.util.Map;
355import java.util.Objects;
356import java.util.Set;
357import java.util.concurrent.CountDownLatch;
358import java.util.concurrent.Future;
359import java.util.concurrent.TimeUnit;
360import java.util.concurrent.atomic.AtomicBoolean;
361import java.util.concurrent.atomic.AtomicInteger;
362
363/**
364 * Keep track of all those APKs everywhere.
365 * <p>
366 * Internally there are two important locks:
367 * <ul>
368 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
369 * and other related state. It is a fine-grained lock that should only be held
370 * momentarily, as it's one of the most contended locks in the system.
371 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
372 * operations typically involve heavy lifting of application data on disk. Since
373 * {@code installd} is single-threaded, and it's operations can often be slow,
374 * this lock should never be acquired while already holding {@link #mPackages}.
375 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
376 * holding {@link #mInstallLock}.
377 * </ul>
378 * Many internal methods rely on the caller to hold the appropriate locks, and
379 * this contract is expressed through method name suffixes:
380 * <ul>
381 * <li>fooLI(): the caller must hold {@link #mInstallLock}
382 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
383 * being modified must be frozen
384 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
385 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
386 * </ul>
387 * <p>
388 * Because this class is very central to the platform's security; please run all
389 * CTS and unit tests whenever making modifications:
390 *
391 * <pre>
392 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
393 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
394 * </pre>
395 */
396public class PackageManagerService extends IPackageManager.Stub
397        implements PackageSender {
398    static final String TAG = "PackageManager";
399    public static final boolean DEBUG_SETTINGS = false;
400    static final boolean DEBUG_PREFERRED = false;
401    static final boolean DEBUG_UPGRADE = false;
402    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
403    private static final boolean DEBUG_BACKUP = false;
404    public static final boolean DEBUG_INSTALL = false;
405    public static final boolean DEBUG_REMOVE = false;
406    private static final boolean DEBUG_BROADCASTS = false;
407    private static final boolean DEBUG_SHOW_INFO = false;
408    private static final boolean DEBUG_PACKAGE_INFO = false;
409    private static final boolean DEBUG_INTENT_MATCHING = false;
410    public static final boolean DEBUG_PACKAGE_SCANNING = false;
411    private static final boolean DEBUG_VERIFY = false;
412    private static final boolean DEBUG_FILTERS = false;
413    public static final boolean DEBUG_PERMISSIONS = false;
414    private static final boolean DEBUG_SHARED_LIBRARIES = false;
415    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
416
417    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
418    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
419    // user, but by default initialize to this.
420    public static final boolean DEBUG_DEXOPT = false;
421
422    private static final boolean DEBUG_ABI_SELECTION = false;
423    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
424    private static final boolean DEBUG_TRIAGED_MISSING = false;
425    private static final boolean DEBUG_APP_DATA = false;
426
427    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
428    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
429
430    private static final boolean HIDE_EPHEMERAL_APIS = false;
431
432    private static final boolean ENABLE_FREE_CACHE_V2 =
433            SystemProperties.getBoolean("fw.free_cache_v2", true);
434
435    private static final int RADIO_UID = Process.PHONE_UID;
436    private static final int LOG_UID = Process.LOG_UID;
437    private static final int NFC_UID = Process.NFC_UID;
438    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
439    private static final int SHELL_UID = Process.SHELL_UID;
440
441    // Suffix used during package installation when copying/moving
442    // package apks to install directory.
443    private static final String INSTALL_PACKAGE_SUFFIX = "-";
444
445    static final int SCAN_NO_DEX = 1<<0;
446    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
447    static final int SCAN_NEW_INSTALL = 1<<2;
448    static final int SCAN_UPDATE_TIME = 1<<3;
449    static final int SCAN_BOOTING = 1<<4;
450    static final int SCAN_TRUSTED_OVERLAY = 1<<5;
451    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
452    static final int SCAN_REQUIRE_KNOWN = 1<<7;
453    static final int SCAN_MOVE = 1<<8;
454    static final int SCAN_INITIAL = 1<<9;
455    static final int SCAN_CHECK_ONLY = 1<<10;
456    static final int SCAN_DONT_KILL_APP = 1<<11;
457    static final int SCAN_IGNORE_FROZEN = 1<<12;
458    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
459    static final int SCAN_AS_INSTANT_APP = 1<<14;
460    static final int SCAN_AS_FULL_APP = 1<<15;
461    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
462    static final int SCAN_AS_SYSTEM = 1<<17;
463    static final int SCAN_AS_PRIVILEGED = 1<<18;
464    static final int SCAN_AS_OEM = 1<<19;
465    static final int SCAN_AS_VENDOR = 1<<20;
466
467    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
468            SCAN_NO_DEX,
469            SCAN_UPDATE_SIGNATURE,
470            SCAN_NEW_INSTALL,
471            SCAN_UPDATE_TIME,
472            SCAN_BOOTING,
473            SCAN_TRUSTED_OVERLAY,
474            SCAN_DELETE_DATA_ON_FAILURES,
475            SCAN_REQUIRE_KNOWN,
476            SCAN_MOVE,
477            SCAN_INITIAL,
478            SCAN_CHECK_ONLY,
479            SCAN_DONT_KILL_APP,
480            SCAN_IGNORE_FROZEN,
481            SCAN_FIRST_BOOT_OR_UPGRADE,
482            SCAN_AS_INSTANT_APP,
483            SCAN_AS_FULL_APP,
484            SCAN_AS_VIRTUAL_PRELOAD,
485    })
486    @Retention(RetentionPolicy.SOURCE)
487    public @interface ScanFlags {}
488
489    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
490    /** Extension of the compressed packages */
491    public final static String COMPRESSED_EXTENSION = ".gz";
492    /** Suffix of stub packages on the system partition */
493    public final static String STUB_SUFFIX = "-Stub";
494
495    private static final int[] EMPTY_INT_ARRAY = new int[0];
496
497    private static final int TYPE_UNKNOWN = 0;
498    private static final int TYPE_ACTIVITY = 1;
499    private static final int TYPE_RECEIVER = 2;
500    private static final int TYPE_SERVICE = 3;
501    private static final int TYPE_PROVIDER = 4;
502    @IntDef(prefix = { "TYPE_" }, value = {
503            TYPE_UNKNOWN,
504            TYPE_ACTIVITY,
505            TYPE_RECEIVER,
506            TYPE_SERVICE,
507            TYPE_PROVIDER,
508    })
509    @Retention(RetentionPolicy.SOURCE)
510    public @interface ComponentType {}
511
512    /**
513     * Timeout (in milliseconds) after which the watchdog should declare that
514     * our handler thread is wedged.  The usual default for such things is one
515     * minute but we sometimes do very lengthy I/O operations on this thread,
516     * such as installing multi-gigabyte applications, so ours needs to be longer.
517     */
518    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
519
520    /**
521     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
522     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
523     * settings entry if available, otherwise we use the hardcoded default.  If it's been
524     * more than this long since the last fstrim, we force one during the boot sequence.
525     *
526     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
527     * one gets run at the next available charging+idle time.  This final mandatory
528     * no-fstrim check kicks in only of the other scheduling criteria is never met.
529     */
530    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
531
532    /**
533     * Whether verification is enabled by default.
534     */
535    private static final boolean DEFAULT_VERIFY_ENABLE = true;
536
537    /**
538     * The default maximum time to wait for the verification agent to return in
539     * milliseconds.
540     */
541    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
542
543    /**
544     * The default response for package verification timeout.
545     *
546     * This can be either PackageManager.VERIFICATION_ALLOW or
547     * PackageManager.VERIFICATION_REJECT.
548     */
549    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
550
551    public static final String PLATFORM_PACKAGE_NAME = "android";
552
553    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
554
555    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
556            DEFAULT_CONTAINER_PACKAGE,
557            "com.android.defcontainer.DefaultContainerService");
558
559    private static final String KILL_APP_REASON_GIDS_CHANGED =
560            "permission grant or revoke changed gids";
561
562    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
563            "permissions revoked";
564
565    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
566
567    private static final String PACKAGE_SCHEME = "package";
568
569    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
570
571    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
572
573    /** Canonical intent used to identify what counts as a "web browser" app */
574    private static final Intent sBrowserIntent;
575    static {
576        sBrowserIntent = new Intent();
577        sBrowserIntent.setAction(Intent.ACTION_VIEW);
578        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
579        sBrowserIntent.setData(Uri.parse("http:"));
580    }
581
582    /**
583     * The set of all protected actions [i.e. those actions for which a high priority
584     * intent filter is disallowed].
585     */
586    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
587    static {
588        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
589        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
590        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
591        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
592    }
593
594    // Compilation reasons.
595    public static final int REASON_FIRST_BOOT = 0;
596    public static final int REASON_BOOT = 1;
597    public static final int REASON_INSTALL = 2;
598    public static final int REASON_BACKGROUND_DEXOPT = 3;
599    public static final int REASON_AB_OTA = 4;
600    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
601    public static final int REASON_SHARED = 6;
602
603    public static final int REASON_LAST = REASON_SHARED;
604
605    /**
606     * Version number for the package parser cache. Increment this whenever the format or
607     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
608     */
609    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
610
611    /**
612     * Whether the package parser cache is enabled.
613     */
614    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
615
616    /**
617     * Permissions required in order to receive instant application lifecycle broadcasts.
618     */
619    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
620            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
621
622    final ServiceThread mHandlerThread;
623
624    final PackageHandler mHandler;
625
626    private final ProcessLoggingHandler mProcessLoggingHandler;
627
628    /**
629     * Messages for {@link #mHandler} that need to wait for system ready before
630     * being dispatched.
631     */
632    private ArrayList<Message> mPostSystemReadyMessages;
633
634    final int mSdkVersion = Build.VERSION.SDK_INT;
635
636    final Context mContext;
637    final boolean mFactoryTest;
638    final boolean mOnlyCore;
639    final DisplayMetrics mMetrics;
640    final int mDefParseFlags;
641    final String[] mSeparateProcesses;
642    final boolean mIsUpgrade;
643    final boolean mIsPreNUpgrade;
644    final boolean mIsPreNMR1Upgrade;
645
646    // Have we told the Activity Manager to whitelist the default container service by uid yet?
647    @GuardedBy("mPackages")
648    boolean mDefaultContainerWhitelisted = false;
649
650    @GuardedBy("mPackages")
651    private boolean mDexOptDialogShown;
652
653    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
654    // LOCK HELD.  Can be called with mInstallLock held.
655    @GuardedBy("mInstallLock")
656    final Installer mInstaller;
657
658    /** Directory where installed applications are stored */
659    private static final File sAppInstallDir =
660            new File(Environment.getDataDirectory(), "app");
661    /** Directory where installed application's 32-bit native libraries are copied. */
662    private static final File sAppLib32InstallDir =
663            new File(Environment.getDataDirectory(), "app-lib");
664    /** Directory where code and non-resource assets of forward-locked applications are stored */
665    private static final File sDrmAppPrivateInstallDir =
666            new File(Environment.getDataDirectory(), "app-private");
667
668    // ----------------------------------------------------------------
669
670    // Lock for state used when installing and doing other long running
671    // operations.  Methods that must be called with this lock held have
672    // the suffix "LI".
673    final Object mInstallLock = new Object();
674
675    // ----------------------------------------------------------------
676
677    // Keys are String (package name), values are Package.  This also serves
678    // as the lock for the global state.  Methods that must be called with
679    // this lock held have the prefix "LP".
680    @GuardedBy("mPackages")
681    final ArrayMap<String, PackageParser.Package> mPackages =
682            new ArrayMap<String, PackageParser.Package>();
683
684    final ArrayMap<String, Set<String>> mKnownCodebase =
685            new ArrayMap<String, Set<String>>();
686
687    // Keys are isolated uids and values are the uid of the application
688    // that created the isolated proccess.
689    @GuardedBy("mPackages")
690    final SparseIntArray mIsolatedOwners = new SparseIntArray();
691
692    /**
693     * Tracks new system packages [received in an OTA] that we expect to
694     * find updated user-installed versions. Keys are package name, values
695     * are package location.
696     */
697    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
698    /**
699     * Tracks high priority intent filters for protected actions. During boot, certain
700     * filter actions are protected and should never be allowed to have a high priority
701     * intent filter for them. However, there is one, and only one exception -- the
702     * setup wizard. It must be able to define a high priority intent filter for these
703     * actions to ensure there are no escapes from the wizard. We need to delay processing
704     * of these during boot as we need to look at all of the system packages in order
705     * to know which component is the setup wizard.
706     */
707    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
708    /**
709     * Whether or not processing protected filters should be deferred.
710     */
711    private boolean mDeferProtectedFilters = true;
712
713    /**
714     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
715     */
716    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
717    /**
718     * Whether or not system app permissions should be promoted from install to runtime.
719     */
720    boolean mPromoteSystemApps;
721
722    @GuardedBy("mPackages")
723    final Settings mSettings;
724
725    /**
726     * Set of package names that are currently "frozen", which means active
727     * surgery is being done on the code/data for that package. The platform
728     * will refuse to launch frozen packages to avoid race conditions.
729     *
730     * @see PackageFreezer
731     */
732    @GuardedBy("mPackages")
733    final ArraySet<String> mFrozenPackages = new ArraySet<>();
734
735    final ProtectedPackages mProtectedPackages;
736
737    @GuardedBy("mLoadedVolumes")
738    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
739
740    boolean mFirstBoot;
741
742    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
743
744    @GuardedBy("mAvailableFeatures")
745    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
746
747    private final InstantAppRegistry mInstantAppRegistry;
748
749    @GuardedBy("mPackages")
750    int mChangedPackagesSequenceNumber;
751    /**
752     * List of changed [installed, removed or updated] packages.
753     * mapping from user id -> sequence number -> package name
754     */
755    @GuardedBy("mPackages")
756    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
757    /**
758     * The sequence number of the last change to a package.
759     * mapping from user id -> package name -> sequence number
760     */
761    @GuardedBy("mPackages")
762    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
763
764    @GuardedBy("mPackages")
765    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
766
767    class PackageParserCallback implements PackageParser.Callback {
768        @Override public final boolean hasFeature(String feature) {
769            return PackageManagerService.this.hasSystemFeature(feature, 0);
770        }
771
772        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
773                Collection<PackageParser.Package> allPackages, String targetPackageName) {
774            List<PackageParser.Package> overlayPackages = null;
775            for (PackageParser.Package p : allPackages) {
776                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
777                    if (overlayPackages == null) {
778                        overlayPackages = new ArrayList<PackageParser.Package>();
779                    }
780                    overlayPackages.add(p);
781                }
782            }
783            if (overlayPackages != null) {
784                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
785                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
786                        return p1.mOverlayPriority - p2.mOverlayPriority;
787                    }
788                };
789                Collections.sort(overlayPackages, cmp);
790            }
791            return overlayPackages;
792        }
793
794        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
795                String targetPackageName, String targetPath) {
796            if ("android".equals(targetPackageName)) {
797                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
798                // native AssetManager.
799                return null;
800            }
801            List<PackageParser.Package> overlayPackages =
802                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
803            if (overlayPackages == null || overlayPackages.isEmpty()) {
804                return null;
805            }
806            List<String> overlayPathList = null;
807            for (PackageParser.Package overlayPackage : overlayPackages) {
808                if (targetPath == null) {
809                    if (overlayPathList == null) {
810                        overlayPathList = new ArrayList<String>();
811                    }
812                    overlayPathList.add(overlayPackage.baseCodePath);
813                    continue;
814                }
815
816                try {
817                    // Creates idmaps for system to parse correctly the Android manifest of the
818                    // target package.
819                    //
820                    // OverlayManagerService will update each of them with a correct gid from its
821                    // target package app id.
822                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
823                            UserHandle.getSharedAppGid(
824                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
825                    if (overlayPathList == null) {
826                        overlayPathList = new ArrayList<String>();
827                    }
828                    overlayPathList.add(overlayPackage.baseCodePath);
829                } catch (InstallerException e) {
830                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
831                            overlayPackage.baseCodePath);
832                }
833            }
834            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
835        }
836
837        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
838            synchronized (mPackages) {
839                return getStaticOverlayPathsLocked(
840                        mPackages.values(), targetPackageName, targetPath);
841            }
842        }
843
844        @Override public final String[] getOverlayApks(String targetPackageName) {
845            return getStaticOverlayPaths(targetPackageName, null);
846        }
847
848        @Override public final String[] getOverlayPaths(String targetPackageName,
849                String targetPath) {
850            return getStaticOverlayPaths(targetPackageName, targetPath);
851        }
852    }
853
854    class ParallelPackageParserCallback extends PackageParserCallback {
855        List<PackageParser.Package> mOverlayPackages = null;
856
857        void findStaticOverlayPackages() {
858            synchronized (mPackages) {
859                for (PackageParser.Package p : mPackages.values()) {
860                    if (p.mIsStaticOverlay) {
861                        if (mOverlayPackages == null) {
862                            mOverlayPackages = new ArrayList<PackageParser.Package>();
863                        }
864                        mOverlayPackages.add(p);
865                    }
866                }
867            }
868        }
869
870        @Override
871        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
872            // We can trust mOverlayPackages without holding mPackages because package uninstall
873            // can't happen while running parallel parsing.
874            // Moreover holding mPackages on each parsing thread causes dead-lock.
875            return mOverlayPackages == null ? null :
876                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
877        }
878    }
879
880    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
881    final ParallelPackageParserCallback mParallelPackageParserCallback =
882            new ParallelPackageParserCallback();
883
884    public static final class SharedLibraryEntry {
885        public final @Nullable String path;
886        public final @Nullable String apk;
887        public final @NonNull SharedLibraryInfo info;
888
889        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
890                String declaringPackageName, long declaringPackageVersionCode) {
891            path = _path;
892            apk = _apk;
893            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
894                    declaringPackageName, declaringPackageVersionCode), null);
895        }
896    }
897
898    // Currently known shared libraries.
899    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
900    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
901            new ArrayMap<>();
902
903    // All available activities, for your resolving pleasure.
904    final ActivityIntentResolver mActivities =
905            new ActivityIntentResolver();
906
907    // All available receivers, for your resolving pleasure.
908    final ActivityIntentResolver mReceivers =
909            new ActivityIntentResolver();
910
911    // All available services, for your resolving pleasure.
912    final ServiceIntentResolver mServices = new ServiceIntentResolver();
913
914    // All available providers, for your resolving pleasure.
915    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
916
917    // Mapping from provider base names (first directory in content URI codePath)
918    // to the provider information.
919    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
920            new ArrayMap<String, PackageParser.Provider>();
921
922    // Mapping from instrumentation class names to info about them.
923    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
924            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
925
926    // Packages whose data we have transfered into another package, thus
927    // should no longer exist.
928    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
929
930    // Broadcast actions that are only available to the system.
931    @GuardedBy("mProtectedBroadcasts")
932    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
933
934    /** List of packages waiting for verification. */
935    final SparseArray<PackageVerificationState> mPendingVerification
936            = new SparseArray<PackageVerificationState>();
937
938    final PackageInstallerService mInstallerService;
939
940    final ArtManagerService mArtManagerService;
941
942    private final PackageDexOptimizer mPackageDexOptimizer;
943    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
944    // is used by other apps).
945    private final DexManager mDexManager;
946
947    private AtomicInteger mNextMoveId = new AtomicInteger();
948    private final MoveCallbacks mMoveCallbacks;
949
950    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
951
952    // Cache of users who need badging.
953    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
954
955    /** Token for keys in mPendingVerification. */
956    private int mPendingVerificationToken = 0;
957
958    volatile boolean mSystemReady;
959    volatile boolean mSafeMode;
960    volatile boolean mHasSystemUidErrors;
961    private volatile boolean mEphemeralAppsDisabled;
962
963    ApplicationInfo mAndroidApplication;
964    final ActivityInfo mResolveActivity = new ActivityInfo();
965    final ResolveInfo mResolveInfo = new ResolveInfo();
966    ComponentName mResolveComponentName;
967    PackageParser.Package mPlatformPackage;
968    ComponentName mCustomResolverComponentName;
969
970    boolean mResolverReplaced = false;
971
972    private final @Nullable ComponentName mIntentFilterVerifierComponent;
973    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
974
975    private int mIntentFilterVerificationToken = 0;
976
977    /** The service connection to the ephemeral resolver */
978    final EphemeralResolverConnection mInstantAppResolverConnection;
979    /** Component used to show resolver settings for Instant Apps */
980    final ComponentName mInstantAppResolverSettingsComponent;
981
982    /** Activity used to install instant applications */
983    ActivityInfo mInstantAppInstallerActivity;
984    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
985
986    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
987            = new SparseArray<IntentFilterVerificationState>();
988
989    // TODO remove this and go through mPermissonManager directly
990    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
991    private final PermissionManagerInternal mPermissionManager;
992
993    // List of packages names to keep cached, even if they are uninstalled for all users
994    private List<String> mKeepUninstalledPackages;
995
996    private UserManagerInternal mUserManagerInternal;
997    private ActivityManagerInternal mActivityManagerInternal;
998
999    private DeviceIdleController.LocalService mDeviceIdleController;
1000
1001    private File mCacheDir;
1002
1003    private Future<?> mPrepareAppDataFuture;
1004
1005    private static class IFVerificationParams {
1006        PackageParser.Package pkg;
1007        boolean replacing;
1008        int userId;
1009        int verifierUid;
1010
1011        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1012                int _userId, int _verifierUid) {
1013            pkg = _pkg;
1014            replacing = _replacing;
1015            userId = _userId;
1016            replacing = _replacing;
1017            verifierUid = _verifierUid;
1018        }
1019    }
1020
1021    private interface IntentFilterVerifier<T extends IntentFilter> {
1022        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1023                                               T filter, String packageName);
1024        void startVerifications(int userId);
1025        void receiveVerificationResponse(int verificationId);
1026    }
1027
1028    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1029        private Context mContext;
1030        private ComponentName mIntentFilterVerifierComponent;
1031        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1032
1033        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1034            mContext = context;
1035            mIntentFilterVerifierComponent = verifierComponent;
1036        }
1037
1038        private String getDefaultScheme() {
1039            return IntentFilter.SCHEME_HTTPS;
1040        }
1041
1042        @Override
1043        public void startVerifications(int userId) {
1044            // Launch verifications requests
1045            int count = mCurrentIntentFilterVerifications.size();
1046            for (int n=0; n<count; n++) {
1047                int verificationId = mCurrentIntentFilterVerifications.get(n);
1048                final IntentFilterVerificationState ivs =
1049                        mIntentFilterVerificationStates.get(verificationId);
1050
1051                String packageName = ivs.getPackageName();
1052
1053                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1054                final int filterCount = filters.size();
1055                ArraySet<String> domainsSet = new ArraySet<>();
1056                for (int m=0; m<filterCount; m++) {
1057                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1058                    domainsSet.addAll(filter.getHostsList());
1059                }
1060                synchronized (mPackages) {
1061                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1062                            packageName, domainsSet) != null) {
1063                        scheduleWriteSettingsLocked();
1064                    }
1065                }
1066                sendVerificationRequest(verificationId, ivs);
1067            }
1068            mCurrentIntentFilterVerifications.clear();
1069        }
1070
1071        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1072            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1073            verificationIntent.putExtra(
1074                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1075                    verificationId);
1076            verificationIntent.putExtra(
1077                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1078                    getDefaultScheme());
1079            verificationIntent.putExtra(
1080                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1081                    ivs.getHostsString());
1082            verificationIntent.putExtra(
1083                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1084                    ivs.getPackageName());
1085            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1086            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1087
1088            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1089            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1090                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1091                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1092
1093            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1094            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1095                    "Sending IntentFilter verification broadcast");
1096        }
1097
1098        public void receiveVerificationResponse(int verificationId) {
1099            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1100
1101            final boolean verified = ivs.isVerified();
1102
1103            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1104            final int count = filters.size();
1105            if (DEBUG_DOMAIN_VERIFICATION) {
1106                Slog.i(TAG, "Received verification response " + verificationId
1107                        + " for " + count + " filters, verified=" + verified);
1108            }
1109            for (int n=0; n<count; n++) {
1110                PackageParser.ActivityIntentInfo filter = filters.get(n);
1111                filter.setVerified(verified);
1112
1113                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1114                        + " verified with result:" + verified + " and hosts:"
1115                        + ivs.getHostsString());
1116            }
1117
1118            mIntentFilterVerificationStates.remove(verificationId);
1119
1120            final String packageName = ivs.getPackageName();
1121            IntentFilterVerificationInfo ivi = null;
1122
1123            synchronized (mPackages) {
1124                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1125            }
1126            if (ivi == null) {
1127                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1128                        + verificationId + " packageName:" + packageName);
1129                return;
1130            }
1131            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1132                    "Updating IntentFilterVerificationInfo for package " + packageName
1133                            +" verificationId:" + verificationId);
1134
1135            synchronized (mPackages) {
1136                if (verified) {
1137                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1138                } else {
1139                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1140                }
1141                scheduleWriteSettingsLocked();
1142
1143                final int userId = ivs.getUserId();
1144                if (userId != UserHandle.USER_ALL) {
1145                    final int userStatus =
1146                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1147
1148                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1149                    boolean needUpdate = false;
1150
1151                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1152                    // already been set by the User thru the Disambiguation dialog
1153                    switch (userStatus) {
1154                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1155                            if (verified) {
1156                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1157                            } else {
1158                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1159                            }
1160                            needUpdate = true;
1161                            break;
1162
1163                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1164                            if (verified) {
1165                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1166                                needUpdate = true;
1167                            }
1168                            break;
1169
1170                        default:
1171                            // Nothing to do
1172                    }
1173
1174                    if (needUpdate) {
1175                        mSettings.updateIntentFilterVerificationStatusLPw(
1176                                packageName, updatedStatus, userId);
1177                        scheduleWritePackageRestrictionsLocked(userId);
1178                    }
1179                }
1180            }
1181        }
1182
1183        @Override
1184        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1185                    ActivityIntentInfo filter, String packageName) {
1186            if (!hasValidDomains(filter)) {
1187                return false;
1188            }
1189            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1190            if (ivs == null) {
1191                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1192                        packageName);
1193            }
1194            if (DEBUG_DOMAIN_VERIFICATION) {
1195                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1196            }
1197            ivs.addFilter(filter);
1198            return true;
1199        }
1200
1201        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1202                int userId, int verificationId, String packageName) {
1203            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1204                    verifierUid, userId, packageName);
1205            ivs.setPendingState();
1206            synchronized (mPackages) {
1207                mIntentFilterVerificationStates.append(verificationId, ivs);
1208                mCurrentIntentFilterVerifications.add(verificationId);
1209            }
1210            return ivs;
1211        }
1212    }
1213
1214    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1215        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1216                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1217                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1218    }
1219
1220    // Set of pending broadcasts for aggregating enable/disable of components.
1221    static class PendingPackageBroadcasts {
1222        // for each user id, a map of <package name -> components within that package>
1223        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1224
1225        public PendingPackageBroadcasts() {
1226            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1227        }
1228
1229        public ArrayList<String> get(int userId, String packageName) {
1230            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1231            return packages.get(packageName);
1232        }
1233
1234        public void put(int userId, String packageName, ArrayList<String> components) {
1235            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1236            packages.put(packageName, components);
1237        }
1238
1239        public void remove(int userId, String packageName) {
1240            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1241            if (packages != null) {
1242                packages.remove(packageName);
1243            }
1244        }
1245
1246        public void remove(int userId) {
1247            mUidMap.remove(userId);
1248        }
1249
1250        public int userIdCount() {
1251            return mUidMap.size();
1252        }
1253
1254        public int userIdAt(int n) {
1255            return mUidMap.keyAt(n);
1256        }
1257
1258        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1259            return mUidMap.get(userId);
1260        }
1261
1262        public int size() {
1263            // total number of pending broadcast entries across all userIds
1264            int num = 0;
1265            for (int i = 0; i< mUidMap.size(); i++) {
1266                num += mUidMap.valueAt(i).size();
1267            }
1268            return num;
1269        }
1270
1271        public void clear() {
1272            mUidMap.clear();
1273        }
1274
1275        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1276            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1277            if (map == null) {
1278                map = new ArrayMap<String, ArrayList<String>>();
1279                mUidMap.put(userId, map);
1280            }
1281            return map;
1282        }
1283    }
1284    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1285
1286    // Service Connection to remote media container service to copy
1287    // package uri's from external media onto secure containers
1288    // or internal storage.
1289    private IMediaContainerService mContainerService = null;
1290
1291    static final int SEND_PENDING_BROADCAST = 1;
1292    static final int MCS_BOUND = 3;
1293    static final int END_COPY = 4;
1294    static final int INIT_COPY = 5;
1295    static final int MCS_UNBIND = 6;
1296    static final int START_CLEANING_PACKAGE = 7;
1297    static final int FIND_INSTALL_LOC = 8;
1298    static final int POST_INSTALL = 9;
1299    static final int MCS_RECONNECT = 10;
1300    static final int MCS_GIVE_UP = 11;
1301    static final int WRITE_SETTINGS = 13;
1302    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1303    static final int PACKAGE_VERIFIED = 15;
1304    static final int CHECK_PENDING_VERIFICATION = 16;
1305    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1306    static final int INTENT_FILTER_VERIFIED = 18;
1307    static final int WRITE_PACKAGE_LIST = 19;
1308    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1309
1310    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1311
1312    // Delay time in millisecs
1313    static final int BROADCAST_DELAY = 10 * 1000;
1314
1315    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1316            2 * 60 * 60 * 1000L; /* two hours */
1317
1318    static UserManagerService sUserManager;
1319
1320    // Stores a list of users whose package restrictions file needs to be updated
1321    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1322
1323    final private DefaultContainerConnection mDefContainerConn =
1324            new DefaultContainerConnection();
1325    class DefaultContainerConnection implements ServiceConnection {
1326        public void onServiceConnected(ComponentName name, IBinder service) {
1327            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1328            final IMediaContainerService imcs = IMediaContainerService.Stub
1329                    .asInterface(Binder.allowBlocking(service));
1330            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1331        }
1332
1333        public void onServiceDisconnected(ComponentName name) {
1334            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1335        }
1336    }
1337
1338    // Recordkeeping of restore-after-install operations that are currently in flight
1339    // between the Package Manager and the Backup Manager
1340    static class PostInstallData {
1341        public InstallArgs args;
1342        public PackageInstalledInfo res;
1343
1344        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1345            args = _a;
1346            res = _r;
1347        }
1348    }
1349
1350    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1351    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1352
1353    // XML tags for backup/restore of various bits of state
1354    private static final String TAG_PREFERRED_BACKUP = "pa";
1355    private static final String TAG_DEFAULT_APPS = "da";
1356    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1357
1358    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1359    private static final String TAG_ALL_GRANTS = "rt-grants";
1360    private static final String TAG_GRANT = "grant";
1361    private static final String ATTR_PACKAGE_NAME = "pkg";
1362
1363    private static final String TAG_PERMISSION = "perm";
1364    private static final String ATTR_PERMISSION_NAME = "name";
1365    private static final String ATTR_IS_GRANTED = "g";
1366    private static final String ATTR_USER_SET = "set";
1367    private static final String ATTR_USER_FIXED = "fixed";
1368    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1369
1370    // System/policy permission grants are not backed up
1371    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1372            FLAG_PERMISSION_POLICY_FIXED
1373            | FLAG_PERMISSION_SYSTEM_FIXED
1374            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1375
1376    // And we back up these user-adjusted states
1377    private static final int USER_RUNTIME_GRANT_MASK =
1378            FLAG_PERMISSION_USER_SET
1379            | FLAG_PERMISSION_USER_FIXED
1380            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1381
1382    final @Nullable String mRequiredVerifierPackage;
1383    final @NonNull String mRequiredInstallerPackage;
1384    final @NonNull String mRequiredUninstallerPackage;
1385    final @Nullable String mSetupWizardPackage;
1386    final @Nullable String mStorageManagerPackage;
1387    final @NonNull String mServicesSystemSharedLibraryPackageName;
1388    final @NonNull String mSharedSystemSharedLibraryPackageName;
1389
1390    private final PackageUsage mPackageUsage = new PackageUsage();
1391    private final CompilerStats mCompilerStats = new CompilerStats();
1392
1393    class PackageHandler extends Handler {
1394        private boolean mBound = false;
1395        final ArrayList<HandlerParams> mPendingInstalls =
1396            new ArrayList<HandlerParams>();
1397
1398        private boolean connectToService() {
1399            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1400                    " DefaultContainerService");
1401            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1402            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1403            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1404                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1405                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1406                mBound = true;
1407                return true;
1408            }
1409            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1410            return false;
1411        }
1412
1413        private void disconnectService() {
1414            mContainerService = null;
1415            mBound = false;
1416            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1417            mContext.unbindService(mDefContainerConn);
1418            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1419        }
1420
1421        PackageHandler(Looper looper) {
1422            super(looper);
1423        }
1424
1425        public void handleMessage(Message msg) {
1426            try {
1427                doHandleMessage(msg);
1428            } finally {
1429                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1430            }
1431        }
1432
1433        void doHandleMessage(Message msg) {
1434            switch (msg.what) {
1435                case INIT_COPY: {
1436                    HandlerParams params = (HandlerParams) msg.obj;
1437                    int idx = mPendingInstalls.size();
1438                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1439                    // If a bind was already initiated we dont really
1440                    // need to do anything. The pending install
1441                    // will be processed later on.
1442                    if (!mBound) {
1443                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1444                                System.identityHashCode(mHandler));
1445                        // If this is the only one pending we might
1446                        // have to bind to the service again.
1447                        if (!connectToService()) {
1448                            Slog.e(TAG, "Failed to bind to media container service");
1449                            params.serviceError();
1450                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1451                                    System.identityHashCode(mHandler));
1452                            if (params.traceMethod != null) {
1453                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1454                                        params.traceCookie);
1455                            }
1456                            return;
1457                        } else {
1458                            // Once we bind to the service, the first
1459                            // pending request will be processed.
1460                            mPendingInstalls.add(idx, params);
1461                        }
1462                    } else {
1463                        mPendingInstalls.add(idx, params);
1464                        // Already bound to the service. Just make
1465                        // sure we trigger off processing the first request.
1466                        if (idx == 0) {
1467                            mHandler.sendEmptyMessage(MCS_BOUND);
1468                        }
1469                    }
1470                    break;
1471                }
1472                case MCS_BOUND: {
1473                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1474                    if (msg.obj != null) {
1475                        mContainerService = (IMediaContainerService) msg.obj;
1476                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1477                                System.identityHashCode(mHandler));
1478                    }
1479                    if (mContainerService == null) {
1480                        if (!mBound) {
1481                            // Something seriously wrong since we are not bound and we are not
1482                            // waiting for connection. Bail out.
1483                            Slog.e(TAG, "Cannot bind to media container service");
1484                            for (HandlerParams params : mPendingInstalls) {
1485                                // Indicate service bind error
1486                                params.serviceError();
1487                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1488                                        System.identityHashCode(params));
1489                                if (params.traceMethod != null) {
1490                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1491                                            params.traceMethod, params.traceCookie);
1492                                }
1493                                return;
1494                            }
1495                            mPendingInstalls.clear();
1496                        } else {
1497                            Slog.w(TAG, "Waiting to connect to media container service");
1498                        }
1499                    } else if (mPendingInstalls.size() > 0) {
1500                        HandlerParams params = mPendingInstalls.get(0);
1501                        if (params != null) {
1502                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1503                                    System.identityHashCode(params));
1504                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1505                            if (params.startCopy()) {
1506                                // We are done...  look for more work or to
1507                                // go idle.
1508                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1509                                        "Checking for more work or unbind...");
1510                                // Delete pending install
1511                                if (mPendingInstalls.size() > 0) {
1512                                    mPendingInstalls.remove(0);
1513                                }
1514                                if (mPendingInstalls.size() == 0) {
1515                                    if (mBound) {
1516                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1517                                                "Posting delayed MCS_UNBIND");
1518                                        removeMessages(MCS_UNBIND);
1519                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1520                                        // Unbind after a little delay, to avoid
1521                                        // continual thrashing.
1522                                        sendMessageDelayed(ubmsg, 10000);
1523                                    }
1524                                } else {
1525                                    // There are more pending requests in queue.
1526                                    // Just post MCS_BOUND message to trigger processing
1527                                    // of next pending install.
1528                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1529                                            "Posting MCS_BOUND for next work");
1530                                    mHandler.sendEmptyMessage(MCS_BOUND);
1531                                }
1532                            }
1533                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1534                        }
1535                    } else {
1536                        // Should never happen ideally.
1537                        Slog.w(TAG, "Empty queue");
1538                    }
1539                    break;
1540                }
1541                case MCS_RECONNECT: {
1542                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1543                    if (mPendingInstalls.size() > 0) {
1544                        if (mBound) {
1545                            disconnectService();
1546                        }
1547                        if (!connectToService()) {
1548                            Slog.e(TAG, "Failed to bind to media container service");
1549                            for (HandlerParams params : mPendingInstalls) {
1550                                // Indicate service bind error
1551                                params.serviceError();
1552                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1553                                        System.identityHashCode(params));
1554                            }
1555                            mPendingInstalls.clear();
1556                        }
1557                    }
1558                    break;
1559                }
1560                case MCS_UNBIND: {
1561                    // If there is no actual work left, then time to unbind.
1562                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1563
1564                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1565                        if (mBound) {
1566                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1567
1568                            disconnectService();
1569                        }
1570                    } else if (mPendingInstalls.size() > 0) {
1571                        // There are more pending requests in queue.
1572                        // Just post MCS_BOUND message to trigger processing
1573                        // of next pending install.
1574                        mHandler.sendEmptyMessage(MCS_BOUND);
1575                    }
1576
1577                    break;
1578                }
1579                case MCS_GIVE_UP: {
1580                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1581                    HandlerParams params = mPendingInstalls.remove(0);
1582                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1583                            System.identityHashCode(params));
1584                    break;
1585                }
1586                case SEND_PENDING_BROADCAST: {
1587                    String packages[];
1588                    ArrayList<String> components[];
1589                    int size = 0;
1590                    int uids[];
1591                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1592                    synchronized (mPackages) {
1593                        if (mPendingBroadcasts == null) {
1594                            return;
1595                        }
1596                        size = mPendingBroadcasts.size();
1597                        if (size <= 0) {
1598                            // Nothing to be done. Just return
1599                            return;
1600                        }
1601                        packages = new String[size];
1602                        components = new ArrayList[size];
1603                        uids = new int[size];
1604                        int i = 0;  // filling out the above arrays
1605
1606                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1607                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1608                            Iterator<Map.Entry<String, ArrayList<String>>> it
1609                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1610                                            .entrySet().iterator();
1611                            while (it.hasNext() && i < size) {
1612                                Map.Entry<String, ArrayList<String>> ent = it.next();
1613                                packages[i] = ent.getKey();
1614                                components[i] = ent.getValue();
1615                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1616                                uids[i] = (ps != null)
1617                                        ? UserHandle.getUid(packageUserId, ps.appId)
1618                                        : -1;
1619                                i++;
1620                            }
1621                        }
1622                        size = i;
1623                        mPendingBroadcasts.clear();
1624                    }
1625                    // Send broadcasts
1626                    for (int i = 0; i < size; i++) {
1627                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1628                    }
1629                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1630                    break;
1631                }
1632                case START_CLEANING_PACKAGE: {
1633                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1634                    final String packageName = (String)msg.obj;
1635                    final int userId = msg.arg1;
1636                    final boolean andCode = msg.arg2 != 0;
1637                    synchronized (mPackages) {
1638                        if (userId == UserHandle.USER_ALL) {
1639                            int[] users = sUserManager.getUserIds();
1640                            for (int user : users) {
1641                                mSettings.addPackageToCleanLPw(
1642                                        new PackageCleanItem(user, packageName, andCode));
1643                            }
1644                        } else {
1645                            mSettings.addPackageToCleanLPw(
1646                                    new PackageCleanItem(userId, packageName, andCode));
1647                        }
1648                    }
1649                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1650                    startCleaningPackages();
1651                } break;
1652                case POST_INSTALL: {
1653                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1654
1655                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1656                    final boolean didRestore = (msg.arg2 != 0);
1657                    mRunningInstalls.delete(msg.arg1);
1658
1659                    if (data != null) {
1660                        InstallArgs args = data.args;
1661                        PackageInstalledInfo parentRes = data.res;
1662
1663                        final boolean grantPermissions = (args.installFlags
1664                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1665                        final boolean killApp = (args.installFlags
1666                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1667                        final boolean virtualPreload = ((args.installFlags
1668                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1669                        final String[] grantedPermissions = args.installGrantPermissions;
1670
1671                        // Handle the parent package
1672                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1673                                virtualPreload, grantedPermissions, didRestore,
1674                                args.installerPackageName, args.observer);
1675
1676                        // Handle the child packages
1677                        final int childCount = (parentRes.addedChildPackages != null)
1678                                ? parentRes.addedChildPackages.size() : 0;
1679                        for (int i = 0; i < childCount; i++) {
1680                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1681                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1682                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1683                                    args.installerPackageName, args.observer);
1684                        }
1685
1686                        // Log tracing if needed
1687                        if (args.traceMethod != null) {
1688                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1689                                    args.traceCookie);
1690                        }
1691                    } else {
1692                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1693                    }
1694
1695                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1696                } break;
1697                case WRITE_SETTINGS: {
1698                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1699                    synchronized (mPackages) {
1700                        removeMessages(WRITE_SETTINGS);
1701                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1702                        mSettings.writeLPr();
1703                        mDirtyUsers.clear();
1704                    }
1705                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1706                } break;
1707                case WRITE_PACKAGE_RESTRICTIONS: {
1708                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1709                    synchronized (mPackages) {
1710                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1711                        for (int userId : mDirtyUsers) {
1712                            mSettings.writePackageRestrictionsLPr(userId);
1713                        }
1714                        mDirtyUsers.clear();
1715                    }
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1717                } break;
1718                case WRITE_PACKAGE_LIST: {
1719                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1720                    synchronized (mPackages) {
1721                        removeMessages(WRITE_PACKAGE_LIST);
1722                        mSettings.writePackageListLPr(msg.arg1);
1723                    }
1724                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1725                } break;
1726                case CHECK_PENDING_VERIFICATION: {
1727                    final int verificationId = msg.arg1;
1728                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1729
1730                    if ((state != null) && !state.timeoutExtended()) {
1731                        final InstallArgs args = state.getInstallArgs();
1732                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1733
1734                        Slog.i(TAG, "Verification timed out for " + originUri);
1735                        mPendingVerification.remove(verificationId);
1736
1737                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1738
1739                        final UserHandle user = args.getUser();
1740                        if (getDefaultVerificationResponse(user)
1741                                == PackageManager.VERIFICATION_ALLOW) {
1742                            Slog.i(TAG, "Continuing with installation of " + originUri);
1743                            state.setVerifierResponse(Binder.getCallingUid(),
1744                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1745                            broadcastPackageVerified(verificationId, originUri,
1746                                    PackageManager.VERIFICATION_ALLOW, user);
1747                            try {
1748                                ret = args.copyApk(mContainerService, true);
1749                            } catch (RemoteException e) {
1750                                Slog.e(TAG, "Could not contact the ContainerService");
1751                            }
1752                        } else {
1753                            broadcastPackageVerified(verificationId, originUri,
1754                                    PackageManager.VERIFICATION_REJECT, user);
1755                        }
1756
1757                        Trace.asyncTraceEnd(
1758                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1759
1760                        processPendingInstall(args, ret);
1761                        mHandler.sendEmptyMessage(MCS_UNBIND);
1762                    }
1763                    break;
1764                }
1765                case PACKAGE_VERIFIED: {
1766                    final int verificationId = msg.arg1;
1767
1768                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1769                    if (state == null) {
1770                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1771                        break;
1772                    }
1773
1774                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1775
1776                    state.setVerifierResponse(response.callerUid, response.code);
1777
1778                    if (state.isVerificationComplete()) {
1779                        mPendingVerification.remove(verificationId);
1780
1781                        final InstallArgs args = state.getInstallArgs();
1782                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1783
1784                        int ret;
1785                        if (state.isInstallAllowed()) {
1786                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1787                            broadcastPackageVerified(verificationId, originUri,
1788                                    response.code, state.getInstallArgs().getUser());
1789                            try {
1790                                ret = args.copyApk(mContainerService, true);
1791                            } catch (RemoteException e) {
1792                                Slog.e(TAG, "Could not contact the ContainerService");
1793                            }
1794                        } else {
1795                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1796                        }
1797
1798                        Trace.asyncTraceEnd(
1799                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1800
1801                        processPendingInstall(args, ret);
1802                        mHandler.sendEmptyMessage(MCS_UNBIND);
1803                    }
1804
1805                    break;
1806                }
1807                case START_INTENT_FILTER_VERIFICATIONS: {
1808                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1809                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1810                            params.replacing, params.pkg);
1811                    break;
1812                }
1813                case INTENT_FILTER_VERIFIED: {
1814                    final int verificationId = msg.arg1;
1815
1816                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1817                            verificationId);
1818                    if (state == null) {
1819                        Slog.w(TAG, "Invalid IntentFilter verification token "
1820                                + verificationId + " received");
1821                        break;
1822                    }
1823
1824                    final int userId = state.getUserId();
1825
1826                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1827                            "Processing IntentFilter verification with token:"
1828                            + verificationId + " and userId:" + userId);
1829
1830                    final IntentFilterVerificationResponse response =
1831                            (IntentFilterVerificationResponse) msg.obj;
1832
1833                    state.setVerifierResponse(response.callerUid, response.code);
1834
1835                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1836                            "IntentFilter verification with token:" + verificationId
1837                            + " and userId:" + userId
1838                            + " is settings verifier response with response code:"
1839                            + response.code);
1840
1841                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1842                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1843                                + response.getFailedDomainsString());
1844                    }
1845
1846                    if (state.isVerificationComplete()) {
1847                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1848                    } else {
1849                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1850                                "IntentFilter verification with token:" + verificationId
1851                                + " was not said to be complete");
1852                    }
1853
1854                    break;
1855                }
1856                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1857                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1858                            mInstantAppResolverConnection,
1859                            (InstantAppRequest) msg.obj,
1860                            mInstantAppInstallerActivity,
1861                            mHandler);
1862                }
1863            }
1864        }
1865    }
1866
1867    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1868        @Override
1869        public void onGidsChanged(int appId, int userId) {
1870            mHandler.post(new Runnable() {
1871                @Override
1872                public void run() {
1873                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1874                }
1875            });
1876        }
1877        @Override
1878        public void onPermissionGranted(int uid, int userId) {
1879            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1880
1881            // Not critical; if this is lost, the application has to request again.
1882            synchronized (mPackages) {
1883                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1884            }
1885        }
1886        @Override
1887        public void onInstallPermissionGranted() {
1888            synchronized (mPackages) {
1889                scheduleWriteSettingsLocked();
1890            }
1891        }
1892        @Override
1893        public void onPermissionRevoked(int uid, int userId) {
1894            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1895
1896            synchronized (mPackages) {
1897                // Critical; after this call the application should never have the permission
1898                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1899            }
1900
1901            final int appId = UserHandle.getAppId(uid);
1902            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1903        }
1904        @Override
1905        public void onInstallPermissionRevoked() {
1906            synchronized (mPackages) {
1907                scheduleWriteSettingsLocked();
1908            }
1909        }
1910        @Override
1911        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1912            synchronized (mPackages) {
1913                for (int userId : updatedUserIds) {
1914                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1915                }
1916            }
1917        }
1918        @Override
1919        public void onInstallPermissionUpdated() {
1920            synchronized (mPackages) {
1921                scheduleWriteSettingsLocked();
1922            }
1923        }
1924        @Override
1925        public void onPermissionRemoved() {
1926            synchronized (mPackages) {
1927                mSettings.writeLPr();
1928            }
1929        }
1930    };
1931
1932    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1933            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1934            boolean launchedForRestore, String installerPackage,
1935            IPackageInstallObserver2 installObserver) {
1936        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1937            // Send the removed broadcasts
1938            if (res.removedInfo != null) {
1939                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1940            }
1941
1942            // Now that we successfully installed the package, grant runtime
1943            // permissions if requested before broadcasting the install. Also
1944            // for legacy apps in permission review mode we clear the permission
1945            // review flag which is used to emulate runtime permissions for
1946            // legacy apps.
1947            if (grantPermissions) {
1948                final int callingUid = Binder.getCallingUid();
1949                mPermissionManager.grantRequestedRuntimePermissions(
1950                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1951                        mPermissionCallback);
1952            }
1953
1954            final boolean update = res.removedInfo != null
1955                    && res.removedInfo.removedPackage != null;
1956            final String installerPackageName =
1957                    res.installerPackageName != null
1958                            ? res.installerPackageName
1959                            : res.removedInfo != null
1960                                    ? res.removedInfo.installerPackageName
1961                                    : null;
1962
1963            // If this is the first time we have child packages for a disabled privileged
1964            // app that had no children, we grant requested runtime permissions to the new
1965            // children if the parent on the system image had them already granted.
1966            if (res.pkg.parentPackage != null) {
1967                final int callingUid = Binder.getCallingUid();
1968                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1969                        res.pkg, callingUid, mPermissionCallback);
1970            }
1971
1972            synchronized (mPackages) {
1973                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1974            }
1975
1976            final String packageName = res.pkg.applicationInfo.packageName;
1977
1978            // Determine the set of users who are adding this package for
1979            // the first time vs. those who are seeing an update.
1980            int[] firstUserIds = EMPTY_INT_ARRAY;
1981            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1982            int[] updateUserIds = EMPTY_INT_ARRAY;
1983            int[] instantUserIds = EMPTY_INT_ARRAY;
1984            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1985            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1986            for (int newUser : res.newUsers) {
1987                final boolean isInstantApp = ps.getInstantApp(newUser);
1988                if (allNewUsers) {
1989                    if (isInstantApp) {
1990                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1991                    } else {
1992                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1993                    }
1994                    continue;
1995                }
1996                boolean isNew = true;
1997                for (int origUser : res.origUsers) {
1998                    if (origUser == newUser) {
1999                        isNew = false;
2000                        break;
2001                    }
2002                }
2003                if (isNew) {
2004                    if (isInstantApp) {
2005                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2006                    } else {
2007                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2008                    }
2009                } else {
2010                    if (isInstantApp) {
2011                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2012                    } else {
2013                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2014                    }
2015                }
2016            }
2017
2018            // Send installed broadcasts if the package is not a static shared lib.
2019            if (res.pkg.staticSharedLibName == null) {
2020                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2021
2022                // Send added for users that see the package for the first time
2023                // sendPackageAddedForNewUsers also deals with system apps
2024                int appId = UserHandle.getAppId(res.uid);
2025                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2026                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2027                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2028
2029                // Send added for users that don't see the package for the first time
2030                Bundle extras = new Bundle(1);
2031                extras.putInt(Intent.EXTRA_UID, res.uid);
2032                if (update) {
2033                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2034                }
2035                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2036                        extras, 0 /*flags*/,
2037                        null /*targetPackage*/, null /*finishedReceiver*/,
2038                        updateUserIds, instantUserIds);
2039                if (installerPackageName != null) {
2040                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2041                            extras, 0 /*flags*/,
2042                            installerPackageName, null /*finishedReceiver*/,
2043                            updateUserIds, instantUserIds);
2044                }
2045
2046                // Send replaced for users that don't see the package for the first time
2047                if (update) {
2048                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2049                            packageName, extras, 0 /*flags*/,
2050                            null /*targetPackage*/, null /*finishedReceiver*/,
2051                            updateUserIds, instantUserIds);
2052                    if (installerPackageName != null) {
2053                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2054                                extras, 0 /*flags*/,
2055                                installerPackageName, null /*finishedReceiver*/,
2056                                updateUserIds, instantUserIds);
2057                    }
2058                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2059                            null /*package*/, null /*extras*/, 0 /*flags*/,
2060                            packageName /*targetPackage*/,
2061                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2062                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2063                    // First-install and we did a restore, so we're responsible for the
2064                    // first-launch broadcast.
2065                    if (DEBUG_BACKUP) {
2066                        Slog.i(TAG, "Post-restore of " + packageName
2067                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2068                    }
2069                    sendFirstLaunchBroadcast(packageName, installerPackage,
2070                            firstUserIds, firstInstantUserIds);
2071                }
2072
2073                // Send broadcast package appeared if forward locked/external for all users
2074                // treat asec-hosted packages like removable media on upgrade
2075                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2076                    if (DEBUG_INSTALL) {
2077                        Slog.i(TAG, "upgrading pkg " + res.pkg
2078                                + " is ASEC-hosted -> AVAILABLE");
2079                    }
2080                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2081                    ArrayList<String> pkgList = new ArrayList<>(1);
2082                    pkgList.add(packageName);
2083                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2084                }
2085            }
2086
2087            // Work that needs to happen on first install within each user
2088            if (firstUserIds != null && firstUserIds.length > 0) {
2089                synchronized (mPackages) {
2090                    for (int userId : firstUserIds) {
2091                        // If this app is a browser and it's newly-installed for some
2092                        // users, clear any default-browser state in those users. The
2093                        // app's nature doesn't depend on the user, so we can just check
2094                        // its browser nature in any user and generalize.
2095                        if (packageIsBrowser(packageName, userId)) {
2096                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2097                        }
2098
2099                        // We may also need to apply pending (restored) runtime
2100                        // permission grants within these users.
2101                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2102                    }
2103                }
2104            }
2105
2106            if (allNewUsers && !update) {
2107                notifyPackageAdded(packageName);
2108            }
2109
2110            // Log current value of "unknown sources" setting
2111            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2112                    getUnknownSourcesSettings());
2113
2114            // Remove the replaced package's older resources safely now
2115            // We delete after a gc for applications  on sdcard.
2116            if (res.removedInfo != null && res.removedInfo.args != null) {
2117                Runtime.getRuntime().gc();
2118                synchronized (mInstallLock) {
2119                    res.removedInfo.args.doPostDeleteLI(true);
2120                }
2121            } else {
2122                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2123                // and not block here.
2124                VMRuntime.getRuntime().requestConcurrentGC();
2125            }
2126
2127            // Notify DexManager that the package was installed for new users.
2128            // The updated users should already be indexed and the package code paths
2129            // should not change.
2130            // Don't notify the manager for ephemeral apps as they are not expected to
2131            // survive long enough to benefit of background optimizations.
2132            for (int userId : firstUserIds) {
2133                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2134                // There's a race currently where some install events may interleave with an uninstall.
2135                // This can lead to package info being null (b/36642664).
2136                if (info != null) {
2137                    mDexManager.notifyPackageInstalled(info, userId);
2138                }
2139            }
2140        }
2141
2142        // If someone is watching installs - notify them
2143        if (installObserver != null) {
2144            try {
2145                Bundle extras = extrasForInstallResult(res);
2146                installObserver.onPackageInstalled(res.name, res.returnCode,
2147                        res.returnMsg, extras);
2148            } catch (RemoteException e) {
2149                Slog.i(TAG, "Observer no longer exists.");
2150            }
2151        }
2152    }
2153
2154    private StorageEventListener mStorageListener = new StorageEventListener() {
2155        @Override
2156        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2157            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2158                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2159                    final String volumeUuid = vol.getFsUuid();
2160
2161                    // Clean up any users or apps that were removed or recreated
2162                    // while this volume was missing
2163                    sUserManager.reconcileUsers(volumeUuid);
2164                    reconcileApps(volumeUuid);
2165
2166                    // Clean up any install sessions that expired or were
2167                    // cancelled while this volume was missing
2168                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2169
2170                    loadPrivatePackages(vol);
2171
2172                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2173                    unloadPrivatePackages(vol);
2174                }
2175            }
2176        }
2177
2178        @Override
2179        public void onVolumeForgotten(String fsUuid) {
2180            if (TextUtils.isEmpty(fsUuid)) {
2181                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2182                return;
2183            }
2184
2185            // Remove any apps installed on the forgotten volume
2186            synchronized (mPackages) {
2187                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2188                for (PackageSetting ps : packages) {
2189                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2190                    deletePackageVersioned(new VersionedPackage(ps.name,
2191                            PackageManager.VERSION_CODE_HIGHEST),
2192                            new LegacyPackageDeleteObserver(null).getBinder(),
2193                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2194                    // Try very hard to release any references to this package
2195                    // so we don't risk the system server being killed due to
2196                    // open FDs
2197                    AttributeCache.instance().removePackage(ps.name);
2198                }
2199
2200                mSettings.onVolumeForgotten(fsUuid);
2201                mSettings.writeLPr();
2202            }
2203        }
2204    };
2205
2206    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2207        Bundle extras = null;
2208        switch (res.returnCode) {
2209            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2210                extras = new Bundle();
2211                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2212                        res.origPermission);
2213                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2214                        res.origPackage);
2215                break;
2216            }
2217            case PackageManager.INSTALL_SUCCEEDED: {
2218                extras = new Bundle();
2219                extras.putBoolean(Intent.EXTRA_REPLACING,
2220                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2221                break;
2222            }
2223        }
2224        return extras;
2225    }
2226
2227    void scheduleWriteSettingsLocked() {
2228        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2229            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2230        }
2231    }
2232
2233    void scheduleWritePackageListLocked(int userId) {
2234        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2235            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2236            msg.arg1 = userId;
2237            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2238        }
2239    }
2240
2241    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2242        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2243        scheduleWritePackageRestrictionsLocked(userId);
2244    }
2245
2246    void scheduleWritePackageRestrictionsLocked(int userId) {
2247        final int[] userIds = (userId == UserHandle.USER_ALL)
2248                ? sUserManager.getUserIds() : new int[]{userId};
2249        for (int nextUserId : userIds) {
2250            if (!sUserManager.exists(nextUserId)) return;
2251            mDirtyUsers.add(nextUserId);
2252            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2253                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2254            }
2255        }
2256    }
2257
2258    public static PackageManagerService main(Context context, Installer installer,
2259            boolean factoryTest, boolean onlyCore) {
2260        // Self-check for initial settings.
2261        PackageManagerServiceCompilerMapping.checkProperties();
2262
2263        PackageManagerService m = new PackageManagerService(context, installer,
2264                factoryTest, onlyCore);
2265        m.enableSystemUserPackages();
2266        ServiceManager.addService("package", m);
2267        final PackageManagerNative pmn = m.new PackageManagerNative();
2268        ServiceManager.addService("package_native", pmn);
2269        return m;
2270    }
2271
2272    private void enableSystemUserPackages() {
2273        if (!UserManager.isSplitSystemUser()) {
2274            return;
2275        }
2276        // For system user, enable apps based on the following conditions:
2277        // - app is whitelisted or belong to one of these groups:
2278        //   -- system app which has no launcher icons
2279        //   -- system app which has INTERACT_ACROSS_USERS permission
2280        //   -- system IME app
2281        // - app is not in the blacklist
2282        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2283        Set<String> enableApps = new ArraySet<>();
2284        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2285                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2286                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2287        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2288        enableApps.addAll(wlApps);
2289        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2290                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2291        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2292        enableApps.removeAll(blApps);
2293        Log.i(TAG, "Applications installed for system user: " + enableApps);
2294        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2295                UserHandle.SYSTEM);
2296        final int allAppsSize = allAps.size();
2297        synchronized (mPackages) {
2298            for (int i = 0; i < allAppsSize; i++) {
2299                String pName = allAps.get(i);
2300                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2301                // Should not happen, but we shouldn't be failing if it does
2302                if (pkgSetting == null) {
2303                    continue;
2304                }
2305                boolean install = enableApps.contains(pName);
2306                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2307                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2308                            + " for system user");
2309                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2310                }
2311            }
2312            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2313        }
2314    }
2315
2316    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2317        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2318                Context.DISPLAY_SERVICE);
2319        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2320    }
2321
2322    /**
2323     * Requests that files preopted on a secondary system partition be copied to the data partition
2324     * if possible.  Note that the actual copying of the files is accomplished by init for security
2325     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2326     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2327     */
2328    private static void requestCopyPreoptedFiles() {
2329        final int WAIT_TIME_MS = 100;
2330        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2331        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2332            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2333            // We will wait for up to 100 seconds.
2334            final long timeStart = SystemClock.uptimeMillis();
2335            final long timeEnd = timeStart + 100 * 1000;
2336            long timeNow = timeStart;
2337            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2338                try {
2339                    Thread.sleep(WAIT_TIME_MS);
2340                } catch (InterruptedException e) {
2341                    // Do nothing
2342                }
2343                timeNow = SystemClock.uptimeMillis();
2344                if (timeNow > timeEnd) {
2345                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2346                    Slog.wtf(TAG, "cppreopt did not finish!");
2347                    break;
2348                }
2349            }
2350
2351            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2352        }
2353    }
2354
2355    public PackageManagerService(Context context, Installer installer,
2356            boolean factoryTest, boolean onlyCore) {
2357        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2358        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2359        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2360                SystemClock.uptimeMillis());
2361
2362        if (mSdkVersion <= 0) {
2363            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2364        }
2365
2366        mContext = context;
2367
2368        mFactoryTest = factoryTest;
2369        mOnlyCore = onlyCore;
2370        mMetrics = new DisplayMetrics();
2371        mInstaller = installer;
2372
2373        // Create sub-components that provide services / data. Order here is important.
2374        synchronized (mInstallLock) {
2375        synchronized (mPackages) {
2376            // Expose private service for system components to use.
2377            LocalServices.addService(
2378                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2379            sUserManager = new UserManagerService(context, this,
2380                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2381            mPermissionManager = PermissionManagerService.create(context,
2382                    new DefaultPermissionGrantedCallback() {
2383                        @Override
2384                        public void onDefaultRuntimePermissionsGranted(int userId) {
2385                            synchronized(mPackages) {
2386                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2387                            }
2388                        }
2389                    }, mPackages /*externalLock*/);
2390            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2391            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2392        }
2393        }
2394        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2395                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2396        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2397                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2398        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2399                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2400        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2401                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2402        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2403                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2404        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2405                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2406
2407        String separateProcesses = SystemProperties.get("debug.separate_processes");
2408        if (separateProcesses != null && separateProcesses.length() > 0) {
2409            if ("*".equals(separateProcesses)) {
2410                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2411                mSeparateProcesses = null;
2412                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2413            } else {
2414                mDefParseFlags = 0;
2415                mSeparateProcesses = separateProcesses.split(",");
2416                Slog.w(TAG, "Running with debug.separate_processes: "
2417                        + separateProcesses);
2418            }
2419        } else {
2420            mDefParseFlags = 0;
2421            mSeparateProcesses = null;
2422        }
2423
2424        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2425                "*dexopt*");
2426        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2427                installer, mInstallLock);
2428        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2429                dexManagerListener);
2430        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2431
2432        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2433                FgThread.get().getLooper());
2434
2435        getDefaultDisplayMetrics(context, mMetrics);
2436
2437        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2438        SystemConfig systemConfig = SystemConfig.getInstance();
2439        mAvailableFeatures = systemConfig.getAvailableFeatures();
2440        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2441
2442        mProtectedPackages = new ProtectedPackages(mContext);
2443
2444        synchronized (mInstallLock) {
2445        // writer
2446        synchronized (mPackages) {
2447            mHandlerThread = new ServiceThread(TAG,
2448                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2449            mHandlerThread.start();
2450            mHandler = new PackageHandler(mHandlerThread.getLooper());
2451            mProcessLoggingHandler = new ProcessLoggingHandler();
2452            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2453            mInstantAppRegistry = new InstantAppRegistry(this);
2454
2455            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2456            final int builtInLibCount = libConfig.size();
2457            for (int i = 0; i < builtInLibCount; i++) {
2458                String name = libConfig.keyAt(i);
2459                String path = libConfig.valueAt(i);
2460                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2461                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2462            }
2463
2464            SELinuxMMAC.readInstallPolicy();
2465
2466            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2467            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2468            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2469
2470            // Clean up orphaned packages for which the code path doesn't exist
2471            // and they are an update to a system app - caused by bug/32321269
2472            final int packageSettingCount = mSettings.mPackages.size();
2473            for (int i = packageSettingCount - 1; i >= 0; i--) {
2474                PackageSetting ps = mSettings.mPackages.valueAt(i);
2475                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2476                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2477                    mSettings.mPackages.removeAt(i);
2478                    mSettings.enableSystemPackageLPw(ps.name);
2479                }
2480            }
2481
2482            if (mFirstBoot) {
2483                requestCopyPreoptedFiles();
2484            }
2485
2486            String customResolverActivity = Resources.getSystem().getString(
2487                    R.string.config_customResolverActivity);
2488            if (TextUtils.isEmpty(customResolverActivity)) {
2489                customResolverActivity = null;
2490            } else {
2491                mCustomResolverComponentName = ComponentName.unflattenFromString(
2492                        customResolverActivity);
2493            }
2494
2495            long startTime = SystemClock.uptimeMillis();
2496
2497            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2498                    startTime);
2499
2500            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2501            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2502
2503            if (bootClassPath == null) {
2504                Slog.w(TAG, "No BOOTCLASSPATH found!");
2505            }
2506
2507            if (systemServerClassPath == null) {
2508                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2509            }
2510
2511            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2512
2513            final VersionInfo ver = mSettings.getInternalVersion();
2514            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2515            if (mIsUpgrade) {
2516                logCriticalInfo(Log.INFO,
2517                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2518            }
2519
2520            // when upgrading from pre-M, promote system app permissions from install to runtime
2521            mPromoteSystemApps =
2522                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2523
2524            // When upgrading from pre-N, we need to handle package extraction like first boot,
2525            // as there is no profiling data available.
2526            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2527
2528            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2529
2530            // save off the names of pre-existing system packages prior to scanning; we don't
2531            // want to automatically grant runtime permissions for new system apps
2532            if (mPromoteSystemApps) {
2533                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2534                while (pkgSettingIter.hasNext()) {
2535                    PackageSetting ps = pkgSettingIter.next();
2536                    if (isSystemApp(ps)) {
2537                        mExistingSystemPackages.add(ps.name);
2538                    }
2539                }
2540            }
2541
2542            mCacheDir = preparePackageParserCache(mIsUpgrade);
2543
2544            // Set flag to monitor and not change apk file paths when
2545            // scanning install directories.
2546            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2547
2548            if (mIsUpgrade || mFirstBoot) {
2549                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2550            }
2551
2552            // Collect vendor overlay packages. (Do this before scanning any apps.)
2553            // For security and version matching reason, only consider
2554            // overlay packages if they reside in the right directory.
2555            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2556                    mDefParseFlags
2557                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2558                    scanFlags
2559                    | SCAN_AS_SYSTEM
2560                    | SCAN_TRUSTED_OVERLAY,
2561                    0);
2562
2563            mParallelPackageParserCallback.findStaticOverlayPackages();
2564
2565            // Find base frameworks (resource packages without code).
2566            scanDirTracedLI(frameworkDir,
2567                    mDefParseFlags
2568                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2569                    scanFlags
2570                    | SCAN_NO_DEX
2571                    | SCAN_AS_SYSTEM
2572                    | SCAN_AS_PRIVILEGED,
2573                    0);
2574
2575            // Collected privileged system packages.
2576            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2577            scanDirTracedLI(privilegedAppDir,
2578                    mDefParseFlags
2579                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2580                    scanFlags
2581                    | SCAN_AS_SYSTEM
2582                    | SCAN_AS_PRIVILEGED,
2583                    0);
2584
2585            // Collect ordinary system packages.
2586            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2587            scanDirTracedLI(systemAppDir,
2588                    mDefParseFlags
2589                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2590                    scanFlags
2591                    | SCAN_AS_SYSTEM,
2592                    0);
2593
2594            // Collected privileged vendor packages.
2595                File privilegedVendorAppDir = new File(Environment.getVendorDirectory(),
2596                        "priv-app");
2597            try {
2598                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2599            } catch (IOException e) {
2600                // failed to look up canonical path, continue with original one
2601            }
2602            scanDirTracedLI(privilegedVendorAppDir,
2603                    mDefParseFlags
2604                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2605                    scanFlags
2606                    | SCAN_AS_SYSTEM
2607                    | SCAN_AS_VENDOR
2608                    | SCAN_AS_PRIVILEGED,
2609                    0);
2610
2611            // Collect ordinary vendor packages.
2612            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2613            try {
2614                vendorAppDir = vendorAppDir.getCanonicalFile();
2615            } catch (IOException e) {
2616                // failed to look up canonical path, continue with original one
2617            }
2618            scanDirTracedLI(vendorAppDir,
2619                    mDefParseFlags
2620                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2621                    scanFlags
2622                    | SCAN_AS_SYSTEM
2623                    | SCAN_AS_VENDOR,
2624                    0);
2625
2626            // Collect all OEM packages.
2627            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2628            scanDirTracedLI(oemAppDir,
2629                    mDefParseFlags
2630                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2631                    scanFlags
2632                    | SCAN_AS_SYSTEM
2633                    | SCAN_AS_OEM,
2634                    0);
2635
2636            // Prune any system packages that no longer exist.
2637            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2638            // Stub packages must either be replaced with full versions in the /data
2639            // partition or be disabled.
2640            final List<String> stubSystemApps = new ArrayList<>();
2641            if (!mOnlyCore) {
2642                // do this first before mucking with mPackages for the "expecting better" case
2643                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2644                while (pkgIterator.hasNext()) {
2645                    final PackageParser.Package pkg = pkgIterator.next();
2646                    if (pkg.isStub) {
2647                        stubSystemApps.add(pkg.packageName);
2648                    }
2649                }
2650
2651                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2652                while (psit.hasNext()) {
2653                    PackageSetting ps = psit.next();
2654
2655                    /*
2656                     * If this is not a system app, it can't be a
2657                     * disable system app.
2658                     */
2659                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2660                        continue;
2661                    }
2662
2663                    /*
2664                     * If the package is scanned, it's not erased.
2665                     */
2666                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2667                    if (scannedPkg != null) {
2668                        /*
2669                         * If the system app is both scanned and in the
2670                         * disabled packages list, then it must have been
2671                         * added via OTA. Remove it from the currently
2672                         * scanned package so the previously user-installed
2673                         * application can be scanned.
2674                         */
2675                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2676                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2677                                    + ps.name + "; removing system app.  Last known codePath="
2678                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2679                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2680                                    + scannedPkg.getLongVersionCode());
2681                            removePackageLI(scannedPkg, true);
2682                            mExpectingBetter.put(ps.name, ps.codePath);
2683                        }
2684
2685                        continue;
2686                    }
2687
2688                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2689                        psit.remove();
2690                        logCriticalInfo(Log.WARN, "System package " + ps.name
2691                                + " no longer exists; it's data will be wiped");
2692                        // Actual deletion of code and data will be handled by later
2693                        // reconciliation step
2694                    } else {
2695                        // we still have a disabled system package, but, it still might have
2696                        // been removed. check the code path still exists and check there's
2697                        // still a package. the latter can happen if an OTA keeps the same
2698                        // code path, but, changes the package name.
2699                        final PackageSetting disabledPs =
2700                                mSettings.getDisabledSystemPkgLPr(ps.name);
2701                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2702                                || disabledPs.pkg == null) {
2703if (REFACTOR_DEBUG) {
2704Slog.e("TODD",
2705        "Possibly deleted app: " + ps.dumpState_temp()
2706        + "; path: " + (disabledPs.codePath == null ? "<<NULL>>":disabledPs.codePath)
2707        + "; pkg: " + (disabledPs.pkg==null?"<<NULL>>":disabledPs.pkg.toString()));
2708}
2709                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2710                        }
2711                    }
2712                }
2713            }
2714
2715            //look for any incomplete package installations
2716            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2717            for (int i = 0; i < deletePkgsList.size(); i++) {
2718                // Actual deletion of code and data will be handled by later
2719                // reconciliation step
2720                final String packageName = deletePkgsList.get(i).name;
2721                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2722                synchronized (mPackages) {
2723                    mSettings.removePackageLPw(packageName);
2724                }
2725            }
2726
2727            //delete tmp files
2728            deleteTempPackageFiles();
2729
2730            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2731
2732            // Remove any shared userIDs that have no associated packages
2733            mSettings.pruneSharedUsersLPw();
2734            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2735            final int systemPackagesCount = mPackages.size();
2736            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2737                    + " ms, packageCount: " + systemPackagesCount
2738                    + " , timePerPackage: "
2739                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2740                    + " , cached: " + cachedSystemApps);
2741            if (mIsUpgrade && systemPackagesCount > 0) {
2742                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2743                        ((int) systemScanTime) / systemPackagesCount);
2744            }
2745            if (!mOnlyCore) {
2746                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2747                        SystemClock.uptimeMillis());
2748                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2749
2750                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2751                        | PackageParser.PARSE_FORWARD_LOCK,
2752                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2753
2754                // Remove disable package settings for updated system apps that were
2755                // removed via an OTA. If the update is no longer present, remove the
2756                // app completely. Otherwise, revoke their system privileges.
2757                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2758                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2759                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2760if (REFACTOR_DEBUG) {
2761Slog.e("TODD",
2762        "remove update; name: " + deletedAppName + ", exists? " + (deletedPkg != null));
2763}
2764                    final String msg;
2765                    if (deletedPkg == null) {
2766                        // should have found an update, but, we didn't; remove everything
2767                        msg = "Updated system package " + deletedAppName
2768                                + " no longer exists; removing its data";
2769                        // Actual deletion of code and data will be handled by later
2770                        // reconciliation step
2771                    } else {
2772                        // found an update; revoke system privileges
2773                        msg = "Updated system package + " + deletedAppName
2774                                + " no longer exists; revoking system privileges";
2775
2776                        // Don't do anything if a stub is removed from the system image. If
2777                        // we were to remove the uncompressed version from the /data partition,
2778                        // this is where it'd be done.
2779
2780                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2781                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2782                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2783                    }
2784                    logCriticalInfo(Log.WARN, msg);
2785                }
2786
2787                /*
2788                 * Make sure all system apps that we expected to appear on
2789                 * the userdata partition actually showed up. If they never
2790                 * appeared, crawl back and revive the system version.
2791                 */
2792                for (int i = 0; i < mExpectingBetter.size(); i++) {
2793                    final String packageName = mExpectingBetter.keyAt(i);
2794                    if (!mPackages.containsKey(packageName)) {
2795                        final File scanFile = mExpectingBetter.valueAt(i);
2796
2797                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2798                                + " but never showed up; reverting to system");
2799
2800                        final @ParseFlags int reparseFlags;
2801                        final @ScanFlags int rescanFlags;
2802                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2803                            reparseFlags =
2804                                    mDefParseFlags |
2805                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2806                            rescanFlags =
2807                                    scanFlags
2808                                    | SCAN_AS_SYSTEM
2809                                    | SCAN_AS_PRIVILEGED;
2810                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2811                            reparseFlags =
2812                                    mDefParseFlags |
2813                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2814                            rescanFlags =
2815                                    scanFlags
2816                                    | SCAN_AS_SYSTEM;
2817                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2818                            reparseFlags =
2819                                    mDefParseFlags |
2820                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2821                            rescanFlags =
2822                                    scanFlags
2823                                    | SCAN_AS_SYSTEM
2824                                    | SCAN_AS_VENDOR
2825                                    | SCAN_AS_PRIVILEGED;
2826                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2827                            reparseFlags =
2828                                    mDefParseFlags |
2829                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2830                            rescanFlags =
2831                                    scanFlags
2832                                    | SCAN_AS_SYSTEM
2833                                    | SCAN_AS_VENDOR;
2834                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2835                            reparseFlags =
2836                                    mDefParseFlags |
2837                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2838                            rescanFlags =
2839                                    scanFlags
2840                                    | SCAN_AS_SYSTEM
2841                                    | SCAN_AS_OEM;
2842                        } else {
2843                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2844                            continue;
2845                        }
2846
2847                        mSettings.enableSystemPackageLPw(packageName);
2848
2849                        try {
2850                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2851                        } catch (PackageManagerException e) {
2852                            Slog.e(TAG, "Failed to parse original system package: "
2853                                    + e.getMessage());
2854                        }
2855                    }
2856                }
2857
2858                // Uncompress and install any stubbed system applications.
2859                // This must be done last to ensure all stubs are replaced or disabled.
2860                decompressSystemApplications(stubSystemApps, scanFlags);
2861
2862                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2863                                - cachedSystemApps;
2864
2865                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2866                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2867                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2868                        + " ms, packageCount: " + dataPackagesCount
2869                        + " , timePerPackage: "
2870                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2871                        + " , cached: " + cachedNonSystemApps);
2872                if (mIsUpgrade && dataPackagesCount > 0) {
2873                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2874                            ((int) dataScanTime) / dataPackagesCount);
2875                }
2876            }
2877            mExpectingBetter.clear();
2878
2879            // Resolve the storage manager.
2880            mStorageManagerPackage = getStorageManagerPackageName();
2881
2882            // Resolve protected action filters. Only the setup wizard is allowed to
2883            // have a high priority filter for these actions.
2884            mSetupWizardPackage = getSetupWizardPackageName();
2885            if (mProtectedFilters.size() > 0) {
2886                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2887                    Slog.i(TAG, "No setup wizard;"
2888                        + " All protected intents capped to priority 0");
2889                }
2890                for (ActivityIntentInfo filter : mProtectedFilters) {
2891                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2892                        if (DEBUG_FILTERS) {
2893                            Slog.i(TAG, "Found setup wizard;"
2894                                + " allow priority " + filter.getPriority() + ";"
2895                                + " package: " + filter.activity.info.packageName
2896                                + " activity: " + filter.activity.className
2897                                + " priority: " + filter.getPriority());
2898                        }
2899                        // skip setup wizard; allow it to keep the high priority filter
2900                        continue;
2901                    }
2902                    if (DEBUG_FILTERS) {
2903                        Slog.i(TAG, "Protected action; cap priority to 0;"
2904                                + " package: " + filter.activity.info.packageName
2905                                + " activity: " + filter.activity.className
2906                                + " origPrio: " + filter.getPriority());
2907                    }
2908                    filter.setPriority(0);
2909                }
2910            }
2911            mDeferProtectedFilters = false;
2912            mProtectedFilters.clear();
2913
2914            // Now that we know all of the shared libraries, update all clients to have
2915            // the correct library paths.
2916            updateAllSharedLibrariesLPw(null);
2917
2918            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2919                // NOTE: We ignore potential failures here during a system scan (like
2920                // the rest of the commands above) because there's precious little we
2921                // can do about it. A settings error is reported, though.
2922                final List<String> changedAbiCodePath =
2923                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2924                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
2925                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
2926                        final String codePathString = changedAbiCodePath.get(i);
2927                        try {
2928                            mInstaller.rmdex(codePathString,
2929                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
2930                        } catch (InstallerException ignored) {
2931                        }
2932                    }
2933                }
2934            }
2935
2936            // Now that we know all the packages we are keeping,
2937            // read and update their last usage times.
2938            mPackageUsage.read(mPackages);
2939            mCompilerStats.read();
2940
2941            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2942                    SystemClock.uptimeMillis());
2943            Slog.i(TAG, "Time to scan packages: "
2944                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2945                    + " seconds");
2946
2947            // If the platform SDK has changed since the last time we booted,
2948            // we need to re-grant app permission to catch any new ones that
2949            // appear.  This is really a hack, and means that apps can in some
2950            // cases get permissions that the user didn't initially explicitly
2951            // allow...  it would be nice to have some better way to handle
2952            // this situation.
2953            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
2954            if (sdkUpdated) {
2955                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2956                        + mSdkVersion + "; regranting permissions for internal storage");
2957            }
2958            mPermissionManager.updateAllPermissions(
2959                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
2960                    mPermissionCallback);
2961            ver.sdkVersion = mSdkVersion;
2962
2963            // If this is the first boot or an update from pre-M, and it is a normal
2964            // boot, then we need to initialize the default preferred apps across
2965            // all defined users.
2966            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2967                for (UserInfo user : sUserManager.getUsers(true)) {
2968                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2969                    applyFactoryDefaultBrowserLPw(user.id);
2970                    primeDomainVerificationsLPw(user.id);
2971                }
2972            }
2973
2974            // Prepare storage for system user really early during boot,
2975            // since core system apps like SettingsProvider and SystemUI
2976            // can't wait for user to start
2977            final int storageFlags;
2978            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2979                storageFlags = StorageManager.FLAG_STORAGE_DE;
2980            } else {
2981                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2982            }
2983            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2984                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2985                    true /* onlyCoreApps */);
2986            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2987                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2988                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2989                traceLog.traceBegin("AppDataFixup");
2990                try {
2991                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2992                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2993                } catch (InstallerException e) {
2994                    Slog.w(TAG, "Trouble fixing GIDs", e);
2995                }
2996                traceLog.traceEnd();
2997
2998                traceLog.traceBegin("AppDataPrepare");
2999                if (deferPackages == null || deferPackages.isEmpty()) {
3000                    return;
3001                }
3002                int count = 0;
3003                for (String pkgName : deferPackages) {
3004                    PackageParser.Package pkg = null;
3005                    synchronized (mPackages) {
3006                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
3007                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3008                            pkg = ps.pkg;
3009                        }
3010                    }
3011                    if (pkg != null) {
3012                        synchronized (mInstallLock) {
3013                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3014                                    true /* maybeMigrateAppData */);
3015                        }
3016                        count++;
3017                    }
3018                }
3019                traceLog.traceEnd();
3020                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3021            }, "prepareAppData");
3022
3023            // If this is first boot after an OTA, and a normal boot, then
3024            // we need to clear code cache directories.
3025            // Note that we do *not* clear the application profiles. These remain valid
3026            // across OTAs and are used to drive profile verification (post OTA) and
3027            // profile compilation (without waiting to collect a fresh set of profiles).
3028            if (mIsUpgrade && !onlyCore) {
3029                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3030                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3031                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3032                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3033                        // No apps are running this early, so no need to freeze
3034                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3035                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3036                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3037                    }
3038                }
3039                ver.fingerprint = Build.FINGERPRINT;
3040            }
3041
3042            checkDefaultBrowser();
3043
3044            // clear only after permissions and other defaults have been updated
3045            mExistingSystemPackages.clear();
3046            mPromoteSystemApps = false;
3047
3048            // All the changes are done during package scanning.
3049            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3050
3051            // can downgrade to reader
3052            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3053            mSettings.writeLPr();
3054            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3055            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3056                    SystemClock.uptimeMillis());
3057
3058            if (!mOnlyCore) {
3059                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3060                mRequiredInstallerPackage = getRequiredInstallerLPr();
3061                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3062                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3063                if (mIntentFilterVerifierComponent != null) {
3064                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3065                            mIntentFilterVerifierComponent);
3066                } else {
3067                    mIntentFilterVerifier = null;
3068                }
3069                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3070                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3071                        SharedLibraryInfo.VERSION_UNDEFINED);
3072                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3073                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3074                        SharedLibraryInfo.VERSION_UNDEFINED);
3075            } else {
3076                mRequiredVerifierPackage = null;
3077                mRequiredInstallerPackage = null;
3078                mRequiredUninstallerPackage = null;
3079                mIntentFilterVerifierComponent = null;
3080                mIntentFilterVerifier = null;
3081                mServicesSystemSharedLibraryPackageName = null;
3082                mSharedSystemSharedLibraryPackageName = null;
3083            }
3084
3085            mInstallerService = new PackageInstallerService(context, this);
3086            mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock);
3087            final Pair<ComponentName, String> instantAppResolverComponent =
3088                    getInstantAppResolverLPr();
3089            if (instantAppResolverComponent != null) {
3090                if (DEBUG_EPHEMERAL) {
3091                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3092                }
3093                mInstantAppResolverConnection = new EphemeralResolverConnection(
3094                        mContext, instantAppResolverComponent.first,
3095                        instantAppResolverComponent.second);
3096                mInstantAppResolverSettingsComponent =
3097                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3098            } else {
3099                mInstantAppResolverConnection = null;
3100                mInstantAppResolverSettingsComponent = null;
3101            }
3102            updateInstantAppInstallerLocked(null);
3103
3104            // Read and update the usage of dex files.
3105            // Do this at the end of PM init so that all the packages have their
3106            // data directory reconciled.
3107            // At this point we know the code paths of the packages, so we can validate
3108            // the disk file and build the internal cache.
3109            // The usage file is expected to be small so loading and verifying it
3110            // should take a fairly small time compare to the other activities (e.g. package
3111            // scanning).
3112            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3113            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3114            for (int userId : currentUserIds) {
3115                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3116            }
3117            mDexManager.load(userPackages);
3118            if (mIsUpgrade) {
3119                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3120                        (int) (SystemClock.uptimeMillis() - startTime));
3121            }
3122        } // synchronized (mPackages)
3123        } // synchronized (mInstallLock)
3124
3125        // Now after opening every single application zip, make sure they
3126        // are all flushed.  Not really needed, but keeps things nice and
3127        // tidy.
3128        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3129        Runtime.getRuntime().gc();
3130        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3131
3132        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3133        FallbackCategoryProvider.loadFallbacks();
3134        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3135
3136        // The initial scanning above does many calls into installd while
3137        // holding the mPackages lock, but we're mostly interested in yelling
3138        // once we have a booted system.
3139        mInstaller.setWarnIfHeld(mPackages);
3140
3141        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3142    }
3143
3144    /**
3145     * Uncompress and install stub applications.
3146     * <p>In order to save space on the system partition, some applications are shipped in a
3147     * compressed form. In addition the compressed bits for the full application, the
3148     * system image contains a tiny stub comprised of only the Android manifest.
3149     * <p>During the first boot, attempt to uncompress and install the full application. If
3150     * the application can't be installed for any reason, disable the stub and prevent
3151     * uncompressing the full application during future boots.
3152     * <p>In order to forcefully attempt an installation of a full application, go to app
3153     * settings and enable the application.
3154     */
3155    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3156        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3157            final String pkgName = stubSystemApps.get(i);
3158            // skip if the system package is already disabled
3159            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3160                stubSystemApps.remove(i);
3161                continue;
3162            }
3163            // skip if the package isn't installed (?!); this should never happen
3164            final PackageParser.Package pkg = mPackages.get(pkgName);
3165            if (pkg == null) {
3166                stubSystemApps.remove(i);
3167                continue;
3168            }
3169            // skip if the package has been disabled by the user
3170            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3171            if (ps != null) {
3172                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3173                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3174                    stubSystemApps.remove(i);
3175                    continue;
3176                }
3177            }
3178
3179            if (DEBUG_COMPRESSION) {
3180                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3181            }
3182
3183            // uncompress the binary to its eventual destination on /data
3184            final File scanFile = decompressPackage(pkg);
3185            if (scanFile == null) {
3186                continue;
3187            }
3188
3189            // install the package to replace the stub on /system
3190            try {
3191                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3192                removePackageLI(pkg, true /*chatty*/);
3193                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3194                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3195                        UserHandle.USER_SYSTEM, "android");
3196                stubSystemApps.remove(i);
3197                continue;
3198            } catch (PackageManagerException e) {
3199                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3200            }
3201
3202            // any failed attempt to install the package will be cleaned up later
3203        }
3204
3205        // disable any stub still left; these failed to install the full application
3206        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3207            final String pkgName = stubSystemApps.get(i);
3208            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3209            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3210                    UserHandle.USER_SYSTEM, "android");
3211            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3212        }
3213    }
3214
3215    /**
3216     * Decompresses the given package on the system image onto
3217     * the /data partition.
3218     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3219     */
3220    private File decompressPackage(PackageParser.Package pkg) {
3221        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3222        if (compressedFiles == null || compressedFiles.length == 0) {
3223            if (DEBUG_COMPRESSION) {
3224                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3225            }
3226            return null;
3227        }
3228        final File dstCodePath =
3229                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3230        int ret = PackageManager.INSTALL_SUCCEEDED;
3231        try {
3232            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3233            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3234            for (File srcFile : compressedFiles) {
3235                final String srcFileName = srcFile.getName();
3236                final String dstFileName = srcFileName.substring(
3237                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3238                final File dstFile = new File(dstCodePath, dstFileName);
3239                ret = decompressFile(srcFile, dstFile);
3240                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3241                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3242                            + "; pkg: " + pkg.packageName
3243                            + ", file: " + dstFileName);
3244                    break;
3245                }
3246            }
3247        } catch (ErrnoException e) {
3248            logCriticalInfo(Log.ERROR, "Failed to decompress"
3249                    + "; pkg: " + pkg.packageName
3250                    + ", err: " + e.errno);
3251        }
3252        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3253            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3254            NativeLibraryHelper.Handle handle = null;
3255            try {
3256                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3257                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3258                        null /*abiOverride*/);
3259            } catch (IOException e) {
3260                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3261                        + "; pkg: " + pkg.packageName);
3262                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3263            } finally {
3264                IoUtils.closeQuietly(handle);
3265            }
3266        }
3267        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3268            if (dstCodePath == null || !dstCodePath.exists()) {
3269                return null;
3270            }
3271            removeCodePathLI(dstCodePath);
3272            return null;
3273        }
3274
3275        return dstCodePath;
3276    }
3277
3278    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3279        // we're only interested in updating the installer appliction when 1) it's not
3280        // already set or 2) the modified package is the installer
3281        if (mInstantAppInstallerActivity != null
3282                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3283                        .equals(modifiedPackage)) {
3284            return;
3285        }
3286        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3287    }
3288
3289    private static File preparePackageParserCache(boolean isUpgrade) {
3290        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3291            return null;
3292        }
3293
3294        // Disable package parsing on eng builds to allow for faster incremental development.
3295        if (Build.IS_ENG) {
3296            return null;
3297        }
3298
3299        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3300            Slog.i(TAG, "Disabling package parser cache due to system property.");
3301            return null;
3302        }
3303
3304        // The base directory for the package parser cache lives under /data/system/.
3305        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3306                "package_cache");
3307        if (cacheBaseDir == null) {
3308            return null;
3309        }
3310
3311        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3312        // This also serves to "GC" unused entries when the package cache version changes (which
3313        // can only happen during upgrades).
3314        if (isUpgrade) {
3315            FileUtils.deleteContents(cacheBaseDir);
3316        }
3317
3318
3319        // Return the versioned package cache directory. This is something like
3320        // "/data/system/package_cache/1"
3321        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3322
3323        // The following is a workaround to aid development on non-numbered userdebug
3324        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3325        // the system partition is newer.
3326        //
3327        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3328        // that starts with "eng." to signify that this is an engineering build and not
3329        // destined for release.
3330        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3331            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3332
3333            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3334            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3335            // in general and should not be used for production changes. In this specific case,
3336            // we know that they will work.
3337            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3338            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3339                FileUtils.deleteContents(cacheBaseDir);
3340                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3341            }
3342        }
3343
3344        return cacheDir;
3345    }
3346
3347    @Override
3348    public boolean isFirstBoot() {
3349        // allow instant applications
3350        return mFirstBoot;
3351    }
3352
3353    @Override
3354    public boolean isOnlyCoreApps() {
3355        // allow instant applications
3356        return mOnlyCore;
3357    }
3358
3359    @Override
3360    public boolean isUpgrade() {
3361        // allow instant applications
3362        // The system property allows testing ota flow when upgraded to the same image.
3363        return mIsUpgrade || SystemProperties.getBoolean(
3364                "persist.pm.mock-upgrade", false /* default */);
3365    }
3366
3367    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3368        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3369
3370        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3371                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3372                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3373        if (matches.size() == 1) {
3374            return matches.get(0).getComponentInfo().packageName;
3375        } else if (matches.size() == 0) {
3376            Log.e(TAG, "There should probably be a verifier, but, none were found");
3377            return null;
3378        }
3379        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3380    }
3381
3382    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3383        synchronized (mPackages) {
3384            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3385            if (libraryEntry == null) {
3386                throw new IllegalStateException("Missing required shared library:" + name);
3387            }
3388            return libraryEntry.apk;
3389        }
3390    }
3391
3392    private @NonNull String getRequiredInstallerLPr() {
3393        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3394        intent.addCategory(Intent.CATEGORY_DEFAULT);
3395        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3396
3397        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3398                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3399                UserHandle.USER_SYSTEM);
3400        if (matches.size() == 1) {
3401            ResolveInfo resolveInfo = matches.get(0);
3402            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3403                throw new RuntimeException("The installer must be a privileged app");
3404            }
3405            return matches.get(0).getComponentInfo().packageName;
3406        } else {
3407            throw new RuntimeException("There must be exactly one installer; found " + matches);
3408        }
3409    }
3410
3411    private @NonNull String getRequiredUninstallerLPr() {
3412        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3413        intent.addCategory(Intent.CATEGORY_DEFAULT);
3414        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3415
3416        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3417                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3418                UserHandle.USER_SYSTEM);
3419        if (resolveInfo == null ||
3420                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3421            throw new RuntimeException("There must be exactly one uninstaller; found "
3422                    + resolveInfo);
3423        }
3424        return resolveInfo.getComponentInfo().packageName;
3425    }
3426
3427    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3428        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3429
3430        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3431                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3432                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3433        ResolveInfo best = null;
3434        final int N = matches.size();
3435        for (int i = 0; i < N; i++) {
3436            final ResolveInfo cur = matches.get(i);
3437            final String packageName = cur.getComponentInfo().packageName;
3438            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3439                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3440                continue;
3441            }
3442
3443            if (best == null || cur.priority > best.priority) {
3444                best = cur;
3445            }
3446        }
3447
3448        if (best != null) {
3449            return best.getComponentInfo().getComponentName();
3450        }
3451        Slog.w(TAG, "Intent filter verifier not found");
3452        return null;
3453    }
3454
3455    @Override
3456    public @Nullable ComponentName getInstantAppResolverComponent() {
3457        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3458            return null;
3459        }
3460        synchronized (mPackages) {
3461            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3462            if (instantAppResolver == null) {
3463                return null;
3464            }
3465            return instantAppResolver.first;
3466        }
3467    }
3468
3469    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3470        final String[] packageArray =
3471                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3472        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3473            if (DEBUG_EPHEMERAL) {
3474                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3475            }
3476            return null;
3477        }
3478
3479        final int callingUid = Binder.getCallingUid();
3480        final int resolveFlags =
3481                MATCH_DIRECT_BOOT_AWARE
3482                | MATCH_DIRECT_BOOT_UNAWARE
3483                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3484        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3485        final Intent resolverIntent = new Intent(actionName);
3486        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3487                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3488        // temporarily look for the old action
3489        if (resolvers.size() == 0) {
3490            if (DEBUG_EPHEMERAL) {
3491                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3492            }
3493            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3494            resolverIntent.setAction(actionName);
3495            resolvers = queryIntentServicesInternal(resolverIntent, null,
3496                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3497        }
3498        final int N = resolvers.size();
3499        if (N == 0) {
3500            if (DEBUG_EPHEMERAL) {
3501                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3502            }
3503            return null;
3504        }
3505
3506        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3507        for (int i = 0; i < N; i++) {
3508            final ResolveInfo info = resolvers.get(i);
3509
3510            if (info.serviceInfo == null) {
3511                continue;
3512            }
3513
3514            final String packageName = info.serviceInfo.packageName;
3515            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3516                if (DEBUG_EPHEMERAL) {
3517                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3518                            + " pkg: " + packageName + ", info:" + info);
3519                }
3520                continue;
3521            }
3522
3523            if (DEBUG_EPHEMERAL) {
3524                Slog.v(TAG, "Ephemeral resolver found;"
3525                        + " pkg: " + packageName + ", info:" + info);
3526            }
3527            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3528        }
3529        if (DEBUG_EPHEMERAL) {
3530            Slog.v(TAG, "Ephemeral resolver NOT found");
3531        }
3532        return null;
3533    }
3534
3535    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3536        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3537        intent.addCategory(Intent.CATEGORY_DEFAULT);
3538        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3539
3540        final int resolveFlags =
3541                MATCH_DIRECT_BOOT_AWARE
3542                | MATCH_DIRECT_BOOT_UNAWARE
3543                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3544        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3545                resolveFlags, UserHandle.USER_SYSTEM);
3546        // temporarily look for the old action
3547        if (matches.isEmpty()) {
3548            if (DEBUG_EPHEMERAL) {
3549                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3550            }
3551            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3552            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3553                    resolveFlags, UserHandle.USER_SYSTEM);
3554        }
3555        Iterator<ResolveInfo> iter = matches.iterator();
3556        while (iter.hasNext()) {
3557            final ResolveInfo rInfo = iter.next();
3558            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3559            if (ps != null) {
3560                final PermissionsState permissionsState = ps.getPermissionsState();
3561                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3562                    continue;
3563                }
3564            }
3565            iter.remove();
3566        }
3567        if (matches.size() == 0) {
3568            return null;
3569        } else if (matches.size() == 1) {
3570            return (ActivityInfo) matches.get(0).getComponentInfo();
3571        } else {
3572            throw new RuntimeException(
3573                    "There must be at most one ephemeral installer; found " + matches);
3574        }
3575    }
3576
3577    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3578            @NonNull ComponentName resolver) {
3579        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3580                .addCategory(Intent.CATEGORY_DEFAULT)
3581                .setPackage(resolver.getPackageName());
3582        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3583        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3584                UserHandle.USER_SYSTEM);
3585        // temporarily look for the old action
3586        if (matches.isEmpty()) {
3587            if (DEBUG_EPHEMERAL) {
3588                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3589            }
3590            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3591            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3592                    UserHandle.USER_SYSTEM);
3593        }
3594        if (matches.isEmpty()) {
3595            return null;
3596        }
3597        return matches.get(0).getComponentInfo().getComponentName();
3598    }
3599
3600    private void primeDomainVerificationsLPw(int userId) {
3601        if (DEBUG_DOMAIN_VERIFICATION) {
3602            Slog.d(TAG, "Priming domain verifications in user " + userId);
3603        }
3604
3605        SystemConfig systemConfig = SystemConfig.getInstance();
3606        ArraySet<String> packages = systemConfig.getLinkedApps();
3607
3608        for (String packageName : packages) {
3609            PackageParser.Package pkg = mPackages.get(packageName);
3610            if (pkg != null) {
3611                if (!pkg.isSystem()) {
3612                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3613                    continue;
3614                }
3615
3616                ArraySet<String> domains = null;
3617                for (PackageParser.Activity a : pkg.activities) {
3618                    for (ActivityIntentInfo filter : a.intents) {
3619                        if (hasValidDomains(filter)) {
3620                            if (domains == null) {
3621                                domains = new ArraySet<String>();
3622                            }
3623                            domains.addAll(filter.getHostsList());
3624                        }
3625                    }
3626                }
3627
3628                if (domains != null && domains.size() > 0) {
3629                    if (DEBUG_DOMAIN_VERIFICATION) {
3630                        Slog.v(TAG, "      + " + packageName);
3631                    }
3632                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3633                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3634                    // and then 'always' in the per-user state actually used for intent resolution.
3635                    final IntentFilterVerificationInfo ivi;
3636                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3637                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3638                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3639                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3640                } else {
3641                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3642                            + "' does not handle web links");
3643                }
3644            } else {
3645                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3646            }
3647        }
3648
3649        scheduleWritePackageRestrictionsLocked(userId);
3650        scheduleWriteSettingsLocked();
3651    }
3652
3653    private void applyFactoryDefaultBrowserLPw(int userId) {
3654        // The default browser app's package name is stored in a string resource,
3655        // with a product-specific overlay used for vendor customization.
3656        String browserPkg = mContext.getResources().getString(
3657                com.android.internal.R.string.default_browser);
3658        if (!TextUtils.isEmpty(browserPkg)) {
3659            // non-empty string => required to be a known package
3660            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3661            if (ps == null) {
3662                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3663                browserPkg = null;
3664            } else {
3665                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3666            }
3667        }
3668
3669        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3670        // default.  If there's more than one, just leave everything alone.
3671        if (browserPkg == null) {
3672            calculateDefaultBrowserLPw(userId);
3673        }
3674    }
3675
3676    private void calculateDefaultBrowserLPw(int userId) {
3677        List<String> allBrowsers = resolveAllBrowserApps(userId);
3678        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3679        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3680    }
3681
3682    private List<String> resolveAllBrowserApps(int userId) {
3683        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3684        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3685                PackageManager.MATCH_ALL, userId);
3686
3687        final int count = list.size();
3688        List<String> result = new ArrayList<String>(count);
3689        for (int i=0; i<count; i++) {
3690            ResolveInfo info = list.get(i);
3691            if (info.activityInfo == null
3692                    || !info.handleAllWebDataURI
3693                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3694                    || result.contains(info.activityInfo.packageName)) {
3695                continue;
3696            }
3697            result.add(info.activityInfo.packageName);
3698        }
3699
3700        return result;
3701    }
3702
3703    private boolean packageIsBrowser(String packageName, int userId) {
3704        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3705                PackageManager.MATCH_ALL, userId);
3706        final int N = list.size();
3707        for (int i = 0; i < N; i++) {
3708            ResolveInfo info = list.get(i);
3709            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3710                return true;
3711            }
3712        }
3713        return false;
3714    }
3715
3716    private void checkDefaultBrowser() {
3717        final int myUserId = UserHandle.myUserId();
3718        final String packageName = getDefaultBrowserPackageName(myUserId);
3719        if (packageName != null) {
3720            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3721            if (info == null) {
3722                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3723                synchronized (mPackages) {
3724                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3725                }
3726            }
3727        }
3728    }
3729
3730    @Override
3731    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3732            throws RemoteException {
3733        try {
3734            return super.onTransact(code, data, reply, flags);
3735        } catch (RuntimeException e) {
3736            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3737                Slog.wtf(TAG, "Package Manager Crash", e);
3738            }
3739            throw e;
3740        }
3741    }
3742
3743    static int[] appendInts(int[] cur, int[] add) {
3744        if (add == null) return cur;
3745        if (cur == null) return add;
3746        final int N = add.length;
3747        for (int i=0; i<N; i++) {
3748            cur = appendInt(cur, add[i]);
3749        }
3750        return cur;
3751    }
3752
3753    /**
3754     * Returns whether or not a full application can see an instant application.
3755     * <p>
3756     * Currently, there are three cases in which this can occur:
3757     * <ol>
3758     * <li>The calling application is a "special" process. Special processes
3759     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3760     * <li>The calling application has the permission
3761     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3762     * <li>The calling application is the default launcher on the
3763     *     system partition.</li>
3764     * </ol>
3765     */
3766    private boolean canViewInstantApps(int callingUid, int userId) {
3767        if (callingUid < Process.FIRST_APPLICATION_UID) {
3768            return true;
3769        }
3770        if (mContext.checkCallingOrSelfPermission(
3771                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3772            return true;
3773        }
3774        if (mContext.checkCallingOrSelfPermission(
3775                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3776            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3777            if (homeComponent != null
3778                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3779                return true;
3780            }
3781        }
3782        return false;
3783    }
3784
3785    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3786        if (!sUserManager.exists(userId)) return null;
3787        if (ps == null) {
3788            return null;
3789        }
3790        PackageParser.Package p = ps.pkg;
3791        if (p == null) {
3792            return null;
3793        }
3794        final int callingUid = Binder.getCallingUid();
3795        // Filter out ephemeral app metadata:
3796        //   * The system/shell/root can see metadata for any app
3797        //   * An installed app can see metadata for 1) other installed apps
3798        //     and 2) ephemeral apps that have explicitly interacted with it
3799        //   * Ephemeral apps can only see their own data and exposed installed apps
3800        //   * Holding a signature permission allows seeing instant apps
3801        if (filterAppAccessLPr(ps, callingUid, userId)) {
3802            return null;
3803        }
3804
3805        final PermissionsState permissionsState = ps.getPermissionsState();
3806
3807        // Compute GIDs only if requested
3808        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3809                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3810        // Compute granted permissions only if package has requested permissions
3811        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3812                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3813        final PackageUserState state = ps.readUserState(userId);
3814
3815        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3816                && ps.isSystem()) {
3817            flags |= MATCH_ANY_USER;
3818        }
3819
3820        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3821                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3822
3823        if (packageInfo == null) {
3824            return null;
3825        }
3826
3827        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3828                resolveExternalPackageNameLPr(p);
3829
3830        return packageInfo;
3831    }
3832
3833    @Override
3834    public void checkPackageStartable(String packageName, int userId) {
3835        final int callingUid = Binder.getCallingUid();
3836        if (getInstantAppPackageName(callingUid) != null) {
3837            throw new SecurityException("Instant applications don't have access to this method");
3838        }
3839        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3840        synchronized (mPackages) {
3841            final PackageSetting ps = mSettings.mPackages.get(packageName);
3842            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3843                throw new SecurityException("Package " + packageName + " was not found!");
3844            }
3845
3846            if (!ps.getInstalled(userId)) {
3847                throw new SecurityException(
3848                        "Package " + packageName + " was not installed for user " + userId + "!");
3849            }
3850
3851            if (mSafeMode && !ps.isSystem()) {
3852                throw new SecurityException("Package " + packageName + " not a system app!");
3853            }
3854
3855            if (mFrozenPackages.contains(packageName)) {
3856                throw new SecurityException("Package " + packageName + " is currently frozen!");
3857            }
3858
3859            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3860                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3861            }
3862        }
3863    }
3864
3865    @Override
3866    public boolean isPackageAvailable(String packageName, int userId) {
3867        if (!sUserManager.exists(userId)) return false;
3868        final int callingUid = Binder.getCallingUid();
3869        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3870                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3871        synchronized (mPackages) {
3872            PackageParser.Package p = mPackages.get(packageName);
3873            if (p != null) {
3874                final PackageSetting ps = (PackageSetting) p.mExtras;
3875                if (filterAppAccessLPr(ps, callingUid, userId)) {
3876                    return false;
3877                }
3878                if (ps != null) {
3879                    final PackageUserState state = ps.readUserState(userId);
3880                    if (state != null) {
3881                        return PackageParser.isAvailable(state);
3882                    }
3883                }
3884            }
3885        }
3886        return false;
3887    }
3888
3889    @Override
3890    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3891        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3892                flags, Binder.getCallingUid(), userId);
3893    }
3894
3895    @Override
3896    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3897            int flags, int userId) {
3898        return getPackageInfoInternal(versionedPackage.getPackageName(),
3899                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3900    }
3901
3902    /**
3903     * Important: The provided filterCallingUid is used exclusively to filter out packages
3904     * that can be seen based on user state. It's typically the original caller uid prior
3905     * to clearing. Because it can only be provided by trusted code, it's value can be
3906     * trusted and will be used as-is; unlike userId which will be validated by this method.
3907     */
3908    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3909            int flags, int filterCallingUid, int userId) {
3910        if (!sUserManager.exists(userId)) return null;
3911        flags = updateFlagsForPackage(flags, userId, packageName);
3912        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
3913                false /* requireFullPermission */, false /* checkShell */, "get package info");
3914
3915        // reader
3916        synchronized (mPackages) {
3917            // Normalize package name to handle renamed packages and static libs
3918            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3919
3920            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3921            if (matchFactoryOnly) {
3922                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3923                if (ps != null) {
3924                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3925                        return null;
3926                    }
3927                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3928                        return null;
3929                    }
3930                    return generatePackageInfo(ps, flags, userId);
3931                }
3932            }
3933
3934            PackageParser.Package p = mPackages.get(packageName);
3935            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3936                return null;
3937            }
3938            if (DEBUG_PACKAGE_INFO)
3939                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3940            if (p != null) {
3941                final PackageSetting ps = (PackageSetting) p.mExtras;
3942                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3943                    return null;
3944                }
3945                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3946                    return null;
3947                }
3948                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3949            }
3950            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3951                final PackageSetting ps = mSettings.mPackages.get(packageName);
3952                if (ps == null) return null;
3953                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3954                    return null;
3955                }
3956                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3957                    return null;
3958                }
3959                return generatePackageInfo(ps, flags, userId);
3960            }
3961        }
3962        return null;
3963    }
3964
3965    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3966        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3967            return true;
3968        }
3969        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3970            return true;
3971        }
3972        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3973            return true;
3974        }
3975        return false;
3976    }
3977
3978    private boolean isComponentVisibleToInstantApp(
3979            @Nullable ComponentName component, @ComponentType int type) {
3980        if (type == TYPE_ACTIVITY) {
3981            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3982            return activity != null
3983                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3984                    : false;
3985        } else if (type == TYPE_RECEIVER) {
3986            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3987            return activity != null
3988                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3989                    : false;
3990        } else if (type == TYPE_SERVICE) {
3991            final PackageParser.Service service = mServices.mServices.get(component);
3992            return service != null
3993                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3994                    : false;
3995        } else if (type == TYPE_PROVIDER) {
3996            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3997            return provider != null
3998                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3999                    : false;
4000        } else if (type == TYPE_UNKNOWN) {
4001            return isComponentVisibleToInstantApp(component);
4002        }
4003        return false;
4004    }
4005
4006    /**
4007     * Returns whether or not access to the application should be filtered.
4008     * <p>
4009     * Access may be limited based upon whether the calling or target applications
4010     * are instant applications.
4011     *
4012     * @see #canAccessInstantApps(int)
4013     */
4014    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4015            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4016        // if we're in an isolated process, get the real calling UID
4017        if (Process.isIsolated(callingUid)) {
4018            callingUid = mIsolatedOwners.get(callingUid);
4019        }
4020        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4021        final boolean callerIsInstantApp = instantAppPkgName != null;
4022        if (ps == null) {
4023            if (callerIsInstantApp) {
4024                // pretend the application exists, but, needs to be filtered
4025                return true;
4026            }
4027            return false;
4028        }
4029        // if the target and caller are the same application, don't filter
4030        if (isCallerSameApp(ps.name, callingUid)) {
4031            return false;
4032        }
4033        if (callerIsInstantApp) {
4034            // request for a specific component; if it hasn't been explicitly exposed, filter
4035            if (component != null) {
4036                return !isComponentVisibleToInstantApp(component, componentType);
4037            }
4038            // request for application; if no components have been explicitly exposed, filter
4039            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4040        }
4041        if (ps.getInstantApp(userId)) {
4042            // caller can see all components of all instant applications, don't filter
4043            if (canViewInstantApps(callingUid, userId)) {
4044                return false;
4045            }
4046            // request for a specific instant application component, filter
4047            if (component != null) {
4048                return true;
4049            }
4050            // request for an instant application; if the caller hasn't been granted access, filter
4051            return !mInstantAppRegistry.isInstantAccessGranted(
4052                    userId, UserHandle.getAppId(callingUid), ps.appId);
4053        }
4054        return false;
4055    }
4056
4057    /**
4058     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4059     */
4060    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4061        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4062    }
4063
4064    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4065            int flags) {
4066        // Callers can access only the libs they depend on, otherwise they need to explicitly
4067        // ask for the shared libraries given the caller is allowed to access all static libs.
4068        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4069            // System/shell/root get to see all static libs
4070            final int appId = UserHandle.getAppId(uid);
4071            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4072                    || appId == Process.ROOT_UID) {
4073                return false;
4074            }
4075        }
4076
4077        // No package means no static lib as it is always on internal storage
4078        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4079            return false;
4080        }
4081
4082        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4083                ps.pkg.staticSharedLibVersion);
4084        if (libEntry == null) {
4085            return false;
4086        }
4087
4088        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4089        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4090        if (uidPackageNames == null) {
4091            return true;
4092        }
4093
4094        for (String uidPackageName : uidPackageNames) {
4095            if (ps.name.equals(uidPackageName)) {
4096                return false;
4097            }
4098            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4099            if (uidPs != null) {
4100                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4101                        libEntry.info.getName());
4102                if (index < 0) {
4103                    continue;
4104                }
4105                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4106                    return false;
4107                }
4108            }
4109        }
4110        return true;
4111    }
4112
4113    @Override
4114    public String[] currentToCanonicalPackageNames(String[] names) {
4115        final int callingUid = Binder.getCallingUid();
4116        if (getInstantAppPackageName(callingUid) != null) {
4117            return names;
4118        }
4119        final String[] out = new String[names.length];
4120        // reader
4121        synchronized (mPackages) {
4122            final int callingUserId = UserHandle.getUserId(callingUid);
4123            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4124            for (int i=names.length-1; i>=0; i--) {
4125                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4126                boolean translateName = false;
4127                if (ps != null && ps.realName != null) {
4128                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4129                    translateName = !targetIsInstantApp
4130                            || canViewInstantApps
4131                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4132                                    UserHandle.getAppId(callingUid), ps.appId);
4133                }
4134                out[i] = translateName ? ps.realName : names[i];
4135            }
4136        }
4137        return out;
4138    }
4139
4140    @Override
4141    public String[] canonicalToCurrentPackageNames(String[] names) {
4142        final int callingUid = Binder.getCallingUid();
4143        if (getInstantAppPackageName(callingUid) != null) {
4144            return names;
4145        }
4146        final String[] out = new String[names.length];
4147        // reader
4148        synchronized (mPackages) {
4149            final int callingUserId = UserHandle.getUserId(callingUid);
4150            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4151            for (int i=names.length-1; i>=0; i--) {
4152                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4153                boolean translateName = false;
4154                if (cur != null) {
4155                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4156                    final boolean targetIsInstantApp =
4157                            ps != null && ps.getInstantApp(callingUserId);
4158                    translateName = !targetIsInstantApp
4159                            || canViewInstantApps
4160                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4161                                    UserHandle.getAppId(callingUid), ps.appId);
4162                }
4163                out[i] = translateName ? cur : names[i];
4164            }
4165        }
4166        return out;
4167    }
4168
4169    @Override
4170    public int getPackageUid(String packageName, int flags, int userId) {
4171        if (!sUserManager.exists(userId)) return -1;
4172        final int callingUid = Binder.getCallingUid();
4173        flags = updateFlagsForPackage(flags, userId, packageName);
4174        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4175                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4176
4177        // reader
4178        synchronized (mPackages) {
4179            final PackageParser.Package p = mPackages.get(packageName);
4180            if (p != null && p.isMatch(flags)) {
4181                PackageSetting ps = (PackageSetting) p.mExtras;
4182                if (filterAppAccessLPr(ps, callingUid, userId)) {
4183                    return -1;
4184                }
4185                return UserHandle.getUid(userId, p.applicationInfo.uid);
4186            }
4187            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4188                final PackageSetting ps = mSettings.mPackages.get(packageName);
4189                if (ps != null && ps.isMatch(flags)
4190                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4191                    return UserHandle.getUid(userId, ps.appId);
4192                }
4193            }
4194        }
4195
4196        return -1;
4197    }
4198
4199    @Override
4200    public int[] getPackageGids(String packageName, int flags, int userId) {
4201        if (!sUserManager.exists(userId)) return null;
4202        final int callingUid = Binder.getCallingUid();
4203        flags = updateFlagsForPackage(flags, userId, packageName);
4204        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4205                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4206
4207        // reader
4208        synchronized (mPackages) {
4209            final PackageParser.Package p = mPackages.get(packageName);
4210            if (p != null && p.isMatch(flags)) {
4211                PackageSetting ps = (PackageSetting) p.mExtras;
4212                if (filterAppAccessLPr(ps, callingUid, userId)) {
4213                    return null;
4214                }
4215                // TODO: Shouldn't this be checking for package installed state for userId and
4216                // return null?
4217                return ps.getPermissionsState().computeGids(userId);
4218            }
4219            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4220                final PackageSetting ps = mSettings.mPackages.get(packageName);
4221                if (ps != null && ps.isMatch(flags)
4222                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4223                    return ps.getPermissionsState().computeGids(userId);
4224                }
4225            }
4226        }
4227
4228        return null;
4229    }
4230
4231    @Override
4232    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4233        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4234    }
4235
4236    @Override
4237    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4238            int flags) {
4239        final List<PermissionInfo> permissionList =
4240                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4241        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4242    }
4243
4244    @Override
4245    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4246        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4247    }
4248
4249    @Override
4250    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4251        final List<PermissionGroupInfo> permissionList =
4252                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4253        return (permissionList == null)
4254                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4255    }
4256
4257    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4258            int filterCallingUid, int userId) {
4259        if (!sUserManager.exists(userId)) return null;
4260        PackageSetting ps = mSettings.mPackages.get(packageName);
4261        if (ps != null) {
4262            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4263                return null;
4264            }
4265            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4266                return null;
4267            }
4268            if (ps.pkg == null) {
4269                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4270                if (pInfo != null) {
4271                    return pInfo.applicationInfo;
4272                }
4273                return null;
4274            }
4275            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4276                    ps.readUserState(userId), userId);
4277            if (ai != null) {
4278                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4279            }
4280            return ai;
4281        }
4282        return null;
4283    }
4284
4285    @Override
4286    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4287        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4288    }
4289
4290    /**
4291     * Important: The provided filterCallingUid is used exclusively to filter out applications
4292     * that can be seen based on user state. It's typically the original caller uid prior
4293     * to clearing. Because it can only be provided by trusted code, it's value can be
4294     * trusted and will be used as-is; unlike userId which will be validated by this method.
4295     */
4296    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4297            int filterCallingUid, int userId) {
4298        if (!sUserManager.exists(userId)) return null;
4299        flags = updateFlagsForApplication(flags, userId, packageName);
4300        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4301                false /* requireFullPermission */, false /* checkShell */, "get application info");
4302
4303        // writer
4304        synchronized (mPackages) {
4305            // Normalize package name to handle renamed packages and static libs
4306            packageName = resolveInternalPackageNameLPr(packageName,
4307                    PackageManager.VERSION_CODE_HIGHEST);
4308
4309            PackageParser.Package p = mPackages.get(packageName);
4310            if (DEBUG_PACKAGE_INFO) Log.v(
4311                    TAG, "getApplicationInfo " + packageName
4312                    + ": " + p);
4313            if (p != null) {
4314                PackageSetting ps = mSettings.mPackages.get(packageName);
4315                if (ps == null) return null;
4316                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4317                    return null;
4318                }
4319                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4320                    return null;
4321                }
4322                // Note: isEnabledLP() does not apply here - always return info
4323                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4324                        p, flags, ps.readUserState(userId), userId);
4325                if (ai != null) {
4326                    ai.packageName = resolveExternalPackageNameLPr(p);
4327                }
4328                return ai;
4329            }
4330            if ("android".equals(packageName)||"system".equals(packageName)) {
4331                return mAndroidApplication;
4332            }
4333            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4334                // Already generates the external package name
4335                return generateApplicationInfoFromSettingsLPw(packageName,
4336                        flags, filterCallingUid, userId);
4337            }
4338        }
4339        return null;
4340    }
4341
4342    private String normalizePackageNameLPr(String packageName) {
4343        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4344        return normalizedPackageName != null ? normalizedPackageName : packageName;
4345    }
4346
4347    @Override
4348    public void deletePreloadsFileCache() {
4349        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4350            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4351        }
4352        File dir = Environment.getDataPreloadsFileCacheDirectory();
4353        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4354        FileUtils.deleteContents(dir);
4355    }
4356
4357    @Override
4358    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4359            final int storageFlags, final IPackageDataObserver observer) {
4360        mContext.enforceCallingOrSelfPermission(
4361                android.Manifest.permission.CLEAR_APP_CACHE, null);
4362        mHandler.post(() -> {
4363            boolean success = false;
4364            try {
4365                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4366                success = true;
4367            } catch (IOException e) {
4368                Slog.w(TAG, e);
4369            }
4370            if (observer != null) {
4371                try {
4372                    observer.onRemoveCompleted(null, success);
4373                } catch (RemoteException e) {
4374                    Slog.w(TAG, e);
4375                }
4376            }
4377        });
4378    }
4379
4380    @Override
4381    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4382            final int storageFlags, final IntentSender pi) {
4383        mContext.enforceCallingOrSelfPermission(
4384                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4385        mHandler.post(() -> {
4386            boolean success = false;
4387            try {
4388                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4389                success = true;
4390            } catch (IOException e) {
4391                Slog.w(TAG, e);
4392            }
4393            if (pi != null) {
4394                try {
4395                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4396                } catch (SendIntentException e) {
4397                    Slog.w(TAG, e);
4398                }
4399            }
4400        });
4401    }
4402
4403    /**
4404     * Blocking call to clear various types of cached data across the system
4405     * until the requested bytes are available.
4406     */
4407    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4408        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4409        final File file = storage.findPathForUuid(volumeUuid);
4410        if (file.getUsableSpace() >= bytes) return;
4411
4412        if (ENABLE_FREE_CACHE_V2) {
4413            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4414                    volumeUuid);
4415            final boolean aggressive = (storageFlags
4416                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4417            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4418
4419            // 1. Pre-flight to determine if we have any chance to succeed
4420            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4421            if (internalVolume && (aggressive || SystemProperties
4422                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4423                deletePreloadsFileCache();
4424                if (file.getUsableSpace() >= bytes) return;
4425            }
4426
4427            // 3. Consider parsed APK data (aggressive only)
4428            if (internalVolume && aggressive) {
4429                FileUtils.deleteContents(mCacheDir);
4430                if (file.getUsableSpace() >= bytes) return;
4431            }
4432
4433            // 4. Consider cached app data (above quotas)
4434            try {
4435                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4436                        Installer.FLAG_FREE_CACHE_V2);
4437            } catch (InstallerException ignored) {
4438            }
4439            if (file.getUsableSpace() >= bytes) return;
4440
4441            // 5. Consider shared libraries with refcount=0 and age>min cache period
4442            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4443                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4444                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4445                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4446                return;
4447            }
4448
4449            // 6. Consider dexopt output (aggressive only)
4450            // TODO: Implement
4451
4452            // 7. Consider installed instant apps unused longer than min cache period
4453            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4454                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4455                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4456                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4457                return;
4458            }
4459
4460            // 8. Consider cached app data (below quotas)
4461            try {
4462                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4463                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4464            } catch (InstallerException ignored) {
4465            }
4466            if (file.getUsableSpace() >= bytes) return;
4467
4468            // 9. Consider DropBox entries
4469            // TODO: Implement
4470
4471            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4472            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4473                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4474                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4475                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4476                return;
4477            }
4478        } else {
4479            try {
4480                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4481            } catch (InstallerException ignored) {
4482            }
4483            if (file.getUsableSpace() >= bytes) return;
4484        }
4485
4486        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4487    }
4488
4489    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4490            throws IOException {
4491        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4492        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4493
4494        List<VersionedPackage> packagesToDelete = null;
4495        final long now = System.currentTimeMillis();
4496
4497        synchronized (mPackages) {
4498            final int[] allUsers = sUserManager.getUserIds();
4499            final int libCount = mSharedLibraries.size();
4500            for (int i = 0; i < libCount; i++) {
4501                final LongSparseArray<SharedLibraryEntry> versionedLib
4502                        = mSharedLibraries.valueAt(i);
4503                if (versionedLib == null) {
4504                    continue;
4505                }
4506                final int versionCount = versionedLib.size();
4507                for (int j = 0; j < versionCount; j++) {
4508                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4509                    // Skip packages that are not static shared libs.
4510                    if (!libInfo.isStatic()) {
4511                        break;
4512                    }
4513                    // Important: We skip static shared libs used for some user since
4514                    // in such a case we need to keep the APK on the device. The check for
4515                    // a lib being used for any user is performed by the uninstall call.
4516                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4517                    // Resolve the package name - we use synthetic package names internally
4518                    final String internalPackageName = resolveInternalPackageNameLPr(
4519                            declaringPackage.getPackageName(),
4520                            declaringPackage.getLongVersionCode());
4521                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4522                    // Skip unused static shared libs cached less than the min period
4523                    // to prevent pruning a lib needed by a subsequently installed package.
4524                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4525                        continue;
4526                    }
4527                    if (packagesToDelete == null) {
4528                        packagesToDelete = new ArrayList<>();
4529                    }
4530                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4531                            declaringPackage.getLongVersionCode()));
4532                }
4533            }
4534        }
4535
4536        if (packagesToDelete != null) {
4537            final int packageCount = packagesToDelete.size();
4538            for (int i = 0; i < packageCount; i++) {
4539                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4540                // Delete the package synchronously (will fail of the lib used for any user).
4541                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4542                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4543                                == PackageManager.DELETE_SUCCEEDED) {
4544                    if (volume.getUsableSpace() >= neededSpace) {
4545                        return true;
4546                    }
4547                }
4548            }
4549        }
4550
4551        return false;
4552    }
4553
4554    /**
4555     * Update given flags based on encryption status of current user.
4556     */
4557    private int updateFlags(int flags, int userId) {
4558        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4559                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4560            // Caller expressed an explicit opinion about what encryption
4561            // aware/unaware components they want to see, so fall through and
4562            // give them what they want
4563        } else {
4564            // Caller expressed no opinion, so match based on user state
4565            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4566                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4567            } else {
4568                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4569            }
4570        }
4571        return flags;
4572    }
4573
4574    private UserManagerInternal getUserManagerInternal() {
4575        if (mUserManagerInternal == null) {
4576            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4577        }
4578        return mUserManagerInternal;
4579    }
4580
4581    private ActivityManagerInternal getActivityManagerInternal() {
4582        if (mActivityManagerInternal == null) {
4583            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4584        }
4585        return mActivityManagerInternal;
4586    }
4587
4588
4589    private DeviceIdleController.LocalService getDeviceIdleController() {
4590        if (mDeviceIdleController == null) {
4591            mDeviceIdleController =
4592                    LocalServices.getService(DeviceIdleController.LocalService.class);
4593        }
4594        return mDeviceIdleController;
4595    }
4596
4597    /**
4598     * Update given flags when being used to request {@link PackageInfo}.
4599     */
4600    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4601        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4602        boolean triaged = true;
4603        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4604                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4605            // Caller is asking for component details, so they'd better be
4606            // asking for specific encryption matching behavior, or be triaged
4607            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4608                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4609                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4610                triaged = false;
4611            }
4612        }
4613        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4614                | PackageManager.MATCH_SYSTEM_ONLY
4615                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4616            triaged = false;
4617        }
4618        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4619            mPermissionManager.enforceCrossUserPermission(
4620                    Binder.getCallingUid(), userId, false, false,
4621                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4622                    + Debug.getCallers(5));
4623        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4624                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4625            // If the caller wants all packages and has a restricted profile associated with it,
4626            // then match all users. This is to make sure that launchers that need to access work
4627            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4628            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4629            flags |= PackageManager.MATCH_ANY_USER;
4630        }
4631        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4632            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4633                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4634        }
4635        return updateFlags(flags, userId);
4636    }
4637
4638    /**
4639     * Update given flags when being used to request {@link ApplicationInfo}.
4640     */
4641    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4642        return updateFlagsForPackage(flags, userId, cookie);
4643    }
4644
4645    /**
4646     * Update given flags when being used to request {@link ComponentInfo}.
4647     */
4648    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4649        if (cookie instanceof Intent) {
4650            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4651                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4652            }
4653        }
4654
4655        boolean triaged = true;
4656        // Caller is asking for component details, so they'd better be
4657        // asking for specific encryption matching behavior, or be triaged
4658        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4659                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4660                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4661            triaged = false;
4662        }
4663        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4664            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4665                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4666        }
4667
4668        return updateFlags(flags, userId);
4669    }
4670
4671    /**
4672     * Update given intent when being used to request {@link ResolveInfo}.
4673     */
4674    private Intent updateIntentForResolve(Intent intent) {
4675        if (intent.getSelector() != null) {
4676            intent = intent.getSelector();
4677        }
4678        if (DEBUG_PREFERRED) {
4679            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4680        }
4681        return intent;
4682    }
4683
4684    /**
4685     * Update given flags when being used to request {@link ResolveInfo}.
4686     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4687     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4688     * flag set. However, this flag is only honoured in three circumstances:
4689     * <ul>
4690     * <li>when called from a system process</li>
4691     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4692     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4693     * action and a {@code android.intent.category.BROWSABLE} category</li>
4694     * </ul>
4695     */
4696    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4697        return updateFlagsForResolve(flags, userId, intent, callingUid,
4698                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4699    }
4700    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4701            boolean wantInstantApps) {
4702        return updateFlagsForResolve(flags, userId, intent, callingUid,
4703                wantInstantApps, false /*onlyExposedExplicitly*/);
4704    }
4705    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4706            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4707        // Safe mode means we shouldn't match any third-party components
4708        if (mSafeMode) {
4709            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4710        }
4711        if (getInstantAppPackageName(callingUid) != null) {
4712            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4713            if (onlyExposedExplicitly) {
4714                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4715            }
4716            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4717            flags |= PackageManager.MATCH_INSTANT;
4718        } else {
4719            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4720            final boolean allowMatchInstant =
4721                    (wantInstantApps
4722                            && Intent.ACTION_VIEW.equals(intent.getAction())
4723                            && hasWebURI(intent))
4724                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4725            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4726                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4727            if (!allowMatchInstant) {
4728                flags &= ~PackageManager.MATCH_INSTANT;
4729            }
4730        }
4731        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4732    }
4733
4734    @Override
4735    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4736        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4737    }
4738
4739    /**
4740     * Important: The provided filterCallingUid is used exclusively to filter out activities
4741     * that can be seen based on user state. It's typically the original caller uid prior
4742     * to clearing. Because it can only be provided by trusted code, it's value can be
4743     * trusted and will be used as-is; unlike userId which will be validated by this method.
4744     */
4745    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4746            int filterCallingUid, int userId) {
4747        if (!sUserManager.exists(userId)) return null;
4748        flags = updateFlagsForComponent(flags, userId, component);
4749
4750        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4751            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4752                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
4753        }
4754
4755        synchronized (mPackages) {
4756            PackageParser.Activity a = mActivities.mActivities.get(component);
4757
4758            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4759            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4760                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4761                if (ps == null) return null;
4762                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4763                    return null;
4764                }
4765                return PackageParser.generateActivityInfo(
4766                        a, flags, ps.readUserState(userId), userId);
4767            }
4768            if (mResolveComponentName.equals(component)) {
4769                return PackageParser.generateActivityInfo(
4770                        mResolveActivity, flags, new PackageUserState(), userId);
4771            }
4772        }
4773        return null;
4774    }
4775
4776    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4777        if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4778            return false;
4779        }
4780        final long token = Binder.clearCallingIdentity();
4781        try {
4782            final int callingUserId = UserHandle.getUserId(callingUid);
4783            if (ActivityManager.getCurrentUser() != callingUserId) {
4784                return false;
4785            }
4786            return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4787        } finally {
4788            Binder.restoreCallingIdentity(token);
4789        }
4790    }
4791
4792    @Override
4793    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4794            String resolvedType) {
4795        synchronized (mPackages) {
4796            if (component.equals(mResolveComponentName)) {
4797                // The resolver supports EVERYTHING!
4798                return true;
4799            }
4800            final int callingUid = Binder.getCallingUid();
4801            final int callingUserId = UserHandle.getUserId(callingUid);
4802            PackageParser.Activity a = mActivities.mActivities.get(component);
4803            if (a == null) {
4804                return false;
4805            }
4806            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4807            if (ps == null) {
4808                return false;
4809            }
4810            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4811                return false;
4812            }
4813            for (int i=0; i<a.intents.size(); i++) {
4814                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4815                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4816                    return true;
4817                }
4818            }
4819            return false;
4820        }
4821    }
4822
4823    @Override
4824    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4825        if (!sUserManager.exists(userId)) return null;
4826        final int callingUid = Binder.getCallingUid();
4827        flags = updateFlagsForComponent(flags, userId, component);
4828        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4829                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4830        synchronized (mPackages) {
4831            PackageParser.Activity a = mReceivers.mActivities.get(component);
4832            if (DEBUG_PACKAGE_INFO) Log.v(
4833                TAG, "getReceiverInfo " + component + ": " + a);
4834            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4835                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4836                if (ps == null) return null;
4837                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4838                    return null;
4839                }
4840                return PackageParser.generateActivityInfo(
4841                        a, flags, ps.readUserState(userId), userId);
4842            }
4843        }
4844        return null;
4845    }
4846
4847    @Override
4848    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4849            int flags, int userId) {
4850        if (!sUserManager.exists(userId)) return null;
4851        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4852        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4853            return null;
4854        }
4855
4856        flags = updateFlagsForPackage(flags, userId, null);
4857
4858        final boolean canSeeStaticLibraries =
4859                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4860                        == PERMISSION_GRANTED
4861                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4862                        == PERMISSION_GRANTED
4863                || canRequestPackageInstallsInternal(packageName,
4864                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4865                        false  /* throwIfPermNotDeclared*/)
4866                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4867                        == PERMISSION_GRANTED;
4868
4869        synchronized (mPackages) {
4870            List<SharedLibraryInfo> result = null;
4871
4872            final int libCount = mSharedLibraries.size();
4873            for (int i = 0; i < libCount; i++) {
4874                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4875                if (versionedLib == null) {
4876                    continue;
4877                }
4878
4879                final int versionCount = versionedLib.size();
4880                for (int j = 0; j < versionCount; j++) {
4881                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4882                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4883                        break;
4884                    }
4885                    final long identity = Binder.clearCallingIdentity();
4886                    try {
4887                        PackageInfo packageInfo = getPackageInfoVersioned(
4888                                libInfo.getDeclaringPackage(), flags
4889                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4890                        if (packageInfo == null) {
4891                            continue;
4892                        }
4893                    } finally {
4894                        Binder.restoreCallingIdentity(identity);
4895                    }
4896
4897                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4898                            libInfo.getLongVersion(), libInfo.getType(),
4899                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4900                            flags, userId));
4901
4902                    if (result == null) {
4903                        result = new ArrayList<>();
4904                    }
4905                    result.add(resLibInfo);
4906                }
4907            }
4908
4909            return result != null ? new ParceledListSlice<>(result) : null;
4910        }
4911    }
4912
4913    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4914            SharedLibraryInfo libInfo, int flags, int userId) {
4915        List<VersionedPackage> versionedPackages = null;
4916        final int packageCount = mSettings.mPackages.size();
4917        for (int i = 0; i < packageCount; i++) {
4918            PackageSetting ps = mSettings.mPackages.valueAt(i);
4919
4920            if (ps == null) {
4921                continue;
4922            }
4923
4924            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4925                continue;
4926            }
4927
4928            final String libName = libInfo.getName();
4929            if (libInfo.isStatic()) {
4930                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4931                if (libIdx < 0) {
4932                    continue;
4933                }
4934                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
4935                    continue;
4936                }
4937                if (versionedPackages == null) {
4938                    versionedPackages = new ArrayList<>();
4939                }
4940                // If the dependent is a static shared lib, use the public package name
4941                String dependentPackageName = ps.name;
4942                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4943                    dependentPackageName = ps.pkg.manifestPackageName;
4944                }
4945                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4946            } else if (ps.pkg != null) {
4947                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4948                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4949                    if (versionedPackages == null) {
4950                        versionedPackages = new ArrayList<>();
4951                    }
4952                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4953                }
4954            }
4955        }
4956
4957        return versionedPackages;
4958    }
4959
4960    @Override
4961    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4962        if (!sUserManager.exists(userId)) return null;
4963        final int callingUid = Binder.getCallingUid();
4964        flags = updateFlagsForComponent(flags, userId, component);
4965        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4966                false /* requireFullPermission */, false /* checkShell */, "get service info");
4967        synchronized (mPackages) {
4968            PackageParser.Service s = mServices.mServices.get(component);
4969            if (DEBUG_PACKAGE_INFO) Log.v(
4970                TAG, "getServiceInfo " + component + ": " + s);
4971            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4972                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4973                if (ps == null) return null;
4974                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4975                    return null;
4976                }
4977                return PackageParser.generateServiceInfo(
4978                        s, flags, ps.readUserState(userId), userId);
4979            }
4980        }
4981        return null;
4982    }
4983
4984    @Override
4985    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4986        if (!sUserManager.exists(userId)) return null;
4987        final int callingUid = Binder.getCallingUid();
4988        flags = updateFlagsForComponent(flags, userId, component);
4989        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4990                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4991        synchronized (mPackages) {
4992            PackageParser.Provider p = mProviders.mProviders.get(component);
4993            if (DEBUG_PACKAGE_INFO) Log.v(
4994                TAG, "getProviderInfo " + component + ": " + p);
4995            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4996                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4997                if (ps == null) return null;
4998                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4999                    return null;
5000                }
5001                return PackageParser.generateProviderInfo(
5002                        p, flags, ps.readUserState(userId), userId);
5003            }
5004        }
5005        return null;
5006    }
5007
5008    @Override
5009    public String[] getSystemSharedLibraryNames() {
5010        // allow instant applications
5011        synchronized (mPackages) {
5012            Set<String> libs = null;
5013            final int libCount = mSharedLibraries.size();
5014            for (int i = 0; i < libCount; i++) {
5015                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5016                if (versionedLib == null) {
5017                    continue;
5018                }
5019                final int versionCount = versionedLib.size();
5020                for (int j = 0; j < versionCount; j++) {
5021                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5022                    if (!libEntry.info.isStatic()) {
5023                        if (libs == null) {
5024                            libs = new ArraySet<>();
5025                        }
5026                        libs.add(libEntry.info.getName());
5027                        break;
5028                    }
5029                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5030                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5031                            UserHandle.getUserId(Binder.getCallingUid()),
5032                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5033                        if (libs == null) {
5034                            libs = new ArraySet<>();
5035                        }
5036                        libs.add(libEntry.info.getName());
5037                        break;
5038                    }
5039                }
5040            }
5041
5042            if (libs != null) {
5043                String[] libsArray = new String[libs.size()];
5044                libs.toArray(libsArray);
5045                return libsArray;
5046            }
5047
5048            return null;
5049        }
5050    }
5051
5052    @Override
5053    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5054        // allow instant applications
5055        synchronized (mPackages) {
5056            return mServicesSystemSharedLibraryPackageName;
5057        }
5058    }
5059
5060    @Override
5061    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5062        // allow instant applications
5063        synchronized (mPackages) {
5064            return mSharedSystemSharedLibraryPackageName;
5065        }
5066    }
5067
5068    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5069        for (int i = userList.length - 1; i >= 0; --i) {
5070            final int userId = userList[i];
5071            // don't add instant app to the list of updates
5072            if (pkgSetting.getInstantApp(userId)) {
5073                continue;
5074            }
5075            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5076            if (changedPackages == null) {
5077                changedPackages = new SparseArray<>();
5078                mChangedPackages.put(userId, changedPackages);
5079            }
5080            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5081            if (sequenceNumbers == null) {
5082                sequenceNumbers = new HashMap<>();
5083                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5084            }
5085            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5086            if (sequenceNumber != null) {
5087                changedPackages.remove(sequenceNumber);
5088            }
5089            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5090            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5091        }
5092        mChangedPackagesSequenceNumber++;
5093    }
5094
5095    @Override
5096    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5097        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5098            return null;
5099        }
5100        synchronized (mPackages) {
5101            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5102                return null;
5103            }
5104            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5105            if (changedPackages == null) {
5106                return null;
5107            }
5108            final List<String> packageNames =
5109                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5110            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5111                final String packageName = changedPackages.get(i);
5112                if (packageName != null) {
5113                    packageNames.add(packageName);
5114                }
5115            }
5116            return packageNames.isEmpty()
5117                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5118        }
5119    }
5120
5121    @Override
5122    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5123        // allow instant applications
5124        ArrayList<FeatureInfo> res;
5125        synchronized (mAvailableFeatures) {
5126            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5127            res.addAll(mAvailableFeatures.values());
5128        }
5129        final FeatureInfo fi = new FeatureInfo();
5130        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5131                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5132        res.add(fi);
5133
5134        return new ParceledListSlice<>(res);
5135    }
5136
5137    @Override
5138    public boolean hasSystemFeature(String name, int version) {
5139        // allow instant applications
5140        synchronized (mAvailableFeatures) {
5141            final FeatureInfo feat = mAvailableFeatures.get(name);
5142            if (feat == null) {
5143                return false;
5144            } else {
5145                return feat.version >= version;
5146            }
5147        }
5148    }
5149
5150    @Override
5151    public int checkPermission(String permName, String pkgName, int userId) {
5152        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5153    }
5154
5155    @Override
5156    public int checkUidPermission(String permName, int uid) {
5157        return mPermissionManager.checkUidPermission(permName, uid, getCallingUid());
5158    }
5159
5160    @Override
5161    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5162        if (UserHandle.getCallingUserId() != userId) {
5163            mContext.enforceCallingPermission(
5164                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5165                    "isPermissionRevokedByPolicy for user " + userId);
5166        }
5167
5168        if (checkPermission(permission, packageName, userId)
5169                == PackageManager.PERMISSION_GRANTED) {
5170            return false;
5171        }
5172
5173        final int callingUid = Binder.getCallingUid();
5174        if (getInstantAppPackageName(callingUid) != null) {
5175            if (!isCallerSameApp(packageName, callingUid)) {
5176                return false;
5177            }
5178        } else {
5179            if (isInstantApp(packageName, userId)) {
5180                return false;
5181            }
5182        }
5183
5184        final long identity = Binder.clearCallingIdentity();
5185        try {
5186            final int flags = getPermissionFlags(permission, packageName, userId);
5187            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5188        } finally {
5189            Binder.restoreCallingIdentity(identity);
5190        }
5191    }
5192
5193    @Override
5194    public String getPermissionControllerPackageName() {
5195        synchronized (mPackages) {
5196            return mRequiredInstallerPackage;
5197        }
5198    }
5199
5200    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5201        return mPermissionManager.addDynamicPermission(
5202                info, async, getCallingUid(), new PermissionCallback() {
5203                    @Override
5204                    public void onPermissionChanged() {
5205                        if (!async) {
5206                            mSettings.writeLPr();
5207                        } else {
5208                            scheduleWriteSettingsLocked();
5209                        }
5210                    }
5211                });
5212    }
5213
5214    @Override
5215    public boolean addPermission(PermissionInfo info) {
5216        synchronized (mPackages) {
5217            return addDynamicPermission(info, false);
5218        }
5219    }
5220
5221    @Override
5222    public boolean addPermissionAsync(PermissionInfo info) {
5223        synchronized (mPackages) {
5224            return addDynamicPermission(info, true);
5225        }
5226    }
5227
5228    @Override
5229    public void removePermission(String permName) {
5230        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5231    }
5232
5233    @Override
5234    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5235        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5236                getCallingUid(), userId, mPermissionCallback);
5237    }
5238
5239    @Override
5240    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5241        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5242                getCallingUid(), userId, mPermissionCallback);
5243    }
5244
5245    @Override
5246    public void resetRuntimePermissions() {
5247        mContext.enforceCallingOrSelfPermission(
5248                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5249                "revokeRuntimePermission");
5250
5251        int callingUid = Binder.getCallingUid();
5252        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5253            mContext.enforceCallingOrSelfPermission(
5254                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5255                    "resetRuntimePermissions");
5256        }
5257
5258        synchronized (mPackages) {
5259            mPermissionManager.updateAllPermissions(
5260                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5261                    mPermissionCallback);
5262            for (int userId : UserManagerService.getInstance().getUserIds()) {
5263                final int packageCount = mPackages.size();
5264                for (int i = 0; i < packageCount; i++) {
5265                    PackageParser.Package pkg = mPackages.valueAt(i);
5266                    if (!(pkg.mExtras instanceof PackageSetting)) {
5267                        continue;
5268                    }
5269                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5270                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5271                }
5272            }
5273        }
5274    }
5275
5276    @Override
5277    public int getPermissionFlags(String permName, String packageName, int userId) {
5278        return mPermissionManager.getPermissionFlags(
5279                permName, packageName, getCallingUid(), userId);
5280    }
5281
5282    @Override
5283    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5284            int flagValues, int userId) {
5285        mPermissionManager.updatePermissionFlags(
5286                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5287                mPermissionCallback);
5288    }
5289
5290    /**
5291     * Update the permission flags for all packages and runtime permissions of a user in order
5292     * to allow device or profile owner to remove POLICY_FIXED.
5293     */
5294    @Override
5295    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5296        synchronized (mPackages) {
5297            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5298                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5299                    mPermissionCallback);
5300            if (changed) {
5301                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5302            }
5303        }
5304    }
5305
5306    @Override
5307    public boolean shouldShowRequestPermissionRationale(String permissionName,
5308            String packageName, int userId) {
5309        if (UserHandle.getCallingUserId() != userId) {
5310            mContext.enforceCallingPermission(
5311                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5312                    "canShowRequestPermissionRationale for user " + userId);
5313        }
5314
5315        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5316        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5317            return false;
5318        }
5319
5320        if (checkPermission(permissionName, packageName, userId)
5321                == PackageManager.PERMISSION_GRANTED) {
5322            return false;
5323        }
5324
5325        final int flags;
5326
5327        final long identity = Binder.clearCallingIdentity();
5328        try {
5329            flags = getPermissionFlags(permissionName,
5330                    packageName, userId);
5331        } finally {
5332            Binder.restoreCallingIdentity(identity);
5333        }
5334
5335        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5336                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5337                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5338
5339        if ((flags & fixedFlags) != 0) {
5340            return false;
5341        }
5342
5343        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5344    }
5345
5346    @Override
5347    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5348        mContext.enforceCallingOrSelfPermission(
5349                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5350                "addOnPermissionsChangeListener");
5351
5352        synchronized (mPackages) {
5353            mOnPermissionChangeListeners.addListenerLocked(listener);
5354        }
5355    }
5356
5357    @Override
5358    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5359        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5360            throw new SecurityException("Instant applications don't have access to this method");
5361        }
5362        synchronized (mPackages) {
5363            mOnPermissionChangeListeners.removeListenerLocked(listener);
5364        }
5365    }
5366
5367    @Override
5368    public boolean isProtectedBroadcast(String actionName) {
5369        // allow instant applications
5370        synchronized (mProtectedBroadcasts) {
5371            if (mProtectedBroadcasts.contains(actionName)) {
5372                return true;
5373            } else if (actionName != null) {
5374                // TODO: remove these terrible hacks
5375                if (actionName.startsWith("android.net.netmon.lingerExpired")
5376                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5377                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5378                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5379                    return true;
5380                }
5381            }
5382        }
5383        return false;
5384    }
5385
5386    @Override
5387    public int checkSignatures(String pkg1, String pkg2) {
5388        synchronized (mPackages) {
5389            final PackageParser.Package p1 = mPackages.get(pkg1);
5390            final PackageParser.Package p2 = mPackages.get(pkg2);
5391            if (p1 == null || p1.mExtras == null
5392                    || p2 == null || p2.mExtras == null) {
5393                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5394            }
5395            final int callingUid = Binder.getCallingUid();
5396            final int callingUserId = UserHandle.getUserId(callingUid);
5397            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5398            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5399            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5400                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5401                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5402            }
5403            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5404        }
5405    }
5406
5407    @Override
5408    public int checkUidSignatures(int uid1, int uid2) {
5409        final int callingUid = Binder.getCallingUid();
5410        final int callingUserId = UserHandle.getUserId(callingUid);
5411        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5412        // Map to base uids.
5413        uid1 = UserHandle.getAppId(uid1);
5414        uid2 = UserHandle.getAppId(uid2);
5415        // reader
5416        synchronized (mPackages) {
5417            Signature[] s1;
5418            Signature[] s2;
5419            Object obj = mSettings.getUserIdLPr(uid1);
5420            if (obj != null) {
5421                if (obj instanceof SharedUserSetting) {
5422                    if (isCallerInstantApp) {
5423                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5424                    }
5425                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5426                } else if (obj instanceof PackageSetting) {
5427                    final PackageSetting ps = (PackageSetting) obj;
5428                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5429                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5430                    }
5431                    s1 = ps.signatures.mSignatures;
5432                } else {
5433                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5434                }
5435            } else {
5436                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5437            }
5438            obj = mSettings.getUserIdLPr(uid2);
5439            if (obj != null) {
5440                if (obj instanceof SharedUserSetting) {
5441                    if (isCallerInstantApp) {
5442                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5443                    }
5444                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5445                } else if (obj instanceof PackageSetting) {
5446                    final PackageSetting ps = (PackageSetting) obj;
5447                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5448                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5449                    }
5450                    s2 = ps.signatures.mSignatures;
5451                } else {
5452                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5453                }
5454            } else {
5455                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5456            }
5457            return compareSignatures(s1, s2);
5458        }
5459    }
5460
5461    /**
5462     * This method should typically only be used when granting or revoking
5463     * permissions, since the app may immediately restart after this call.
5464     * <p>
5465     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5466     * guard your work against the app being relaunched.
5467     */
5468    private void killUid(int appId, int userId, String reason) {
5469        final long identity = Binder.clearCallingIdentity();
5470        try {
5471            IActivityManager am = ActivityManager.getService();
5472            if (am != null) {
5473                try {
5474                    am.killUid(appId, userId, reason);
5475                } catch (RemoteException e) {
5476                    /* ignore - same process */
5477                }
5478            }
5479        } finally {
5480            Binder.restoreCallingIdentity(identity);
5481        }
5482    }
5483
5484    /**
5485     * If the database version for this type of package (internal storage or
5486     * external storage) is less than the version where package signatures
5487     * were updated, return true.
5488     */
5489    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5490        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5491        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5492    }
5493
5494    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5495        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5496        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5497    }
5498
5499    @Override
5500    public List<String> getAllPackages() {
5501        final int callingUid = Binder.getCallingUid();
5502        final int callingUserId = UserHandle.getUserId(callingUid);
5503        synchronized (mPackages) {
5504            if (canViewInstantApps(callingUid, callingUserId)) {
5505                return new ArrayList<String>(mPackages.keySet());
5506            }
5507            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5508            final List<String> result = new ArrayList<>();
5509            if (instantAppPkgName != null) {
5510                // caller is an instant application; filter unexposed applications
5511                for (PackageParser.Package pkg : mPackages.values()) {
5512                    if (!pkg.visibleToInstantApps) {
5513                        continue;
5514                    }
5515                    result.add(pkg.packageName);
5516                }
5517            } else {
5518                // caller is a normal application; filter instant applications
5519                for (PackageParser.Package pkg : mPackages.values()) {
5520                    final PackageSetting ps =
5521                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5522                    if (ps != null
5523                            && ps.getInstantApp(callingUserId)
5524                            && !mInstantAppRegistry.isInstantAccessGranted(
5525                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5526                        continue;
5527                    }
5528                    result.add(pkg.packageName);
5529                }
5530            }
5531            return result;
5532        }
5533    }
5534
5535    @Override
5536    public String[] getPackagesForUid(int uid) {
5537        final int callingUid = Binder.getCallingUid();
5538        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5539        final int userId = UserHandle.getUserId(uid);
5540        uid = UserHandle.getAppId(uid);
5541        // reader
5542        synchronized (mPackages) {
5543            Object obj = mSettings.getUserIdLPr(uid);
5544            if (obj instanceof SharedUserSetting) {
5545                if (isCallerInstantApp) {
5546                    return null;
5547                }
5548                final SharedUserSetting sus = (SharedUserSetting) obj;
5549                final int N = sus.packages.size();
5550                String[] res = new String[N];
5551                final Iterator<PackageSetting> it = sus.packages.iterator();
5552                int i = 0;
5553                while (it.hasNext()) {
5554                    PackageSetting ps = it.next();
5555                    if (ps.getInstalled(userId)) {
5556                        res[i++] = ps.name;
5557                    } else {
5558                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5559                    }
5560                }
5561                return res;
5562            } else if (obj instanceof PackageSetting) {
5563                final PackageSetting ps = (PackageSetting) obj;
5564                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5565                    return new String[]{ps.name};
5566                }
5567            }
5568        }
5569        return null;
5570    }
5571
5572    @Override
5573    public String getNameForUid(int uid) {
5574        final int callingUid = Binder.getCallingUid();
5575        if (getInstantAppPackageName(callingUid) != null) {
5576            return null;
5577        }
5578        synchronized (mPackages) {
5579            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5580            if (obj instanceof SharedUserSetting) {
5581                final SharedUserSetting sus = (SharedUserSetting) obj;
5582                return sus.name + ":" + sus.userId;
5583            } else if (obj instanceof PackageSetting) {
5584                final PackageSetting ps = (PackageSetting) obj;
5585                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5586                    return null;
5587                }
5588                return ps.name;
5589            }
5590            return null;
5591        }
5592    }
5593
5594    @Override
5595    public String[] getNamesForUids(int[] uids) {
5596        if (uids == null || uids.length == 0) {
5597            return null;
5598        }
5599        final int callingUid = Binder.getCallingUid();
5600        if (getInstantAppPackageName(callingUid) != null) {
5601            return null;
5602        }
5603        final String[] names = new String[uids.length];
5604        synchronized (mPackages) {
5605            for (int i = uids.length - 1; i >= 0; i--) {
5606                final int uid = uids[i];
5607                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5608                if (obj instanceof SharedUserSetting) {
5609                    final SharedUserSetting sus = (SharedUserSetting) obj;
5610                    names[i] = "shared:" + sus.name;
5611                } else if (obj instanceof PackageSetting) {
5612                    final PackageSetting ps = (PackageSetting) obj;
5613                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5614                        names[i] = null;
5615                    } else {
5616                        names[i] = ps.name;
5617                    }
5618                } else {
5619                    names[i] = null;
5620                }
5621            }
5622        }
5623        return names;
5624    }
5625
5626    @Override
5627    public int getUidForSharedUser(String sharedUserName) {
5628        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5629            return -1;
5630        }
5631        if (sharedUserName == null) {
5632            return -1;
5633        }
5634        // reader
5635        synchronized (mPackages) {
5636            SharedUserSetting suid;
5637            try {
5638                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5639                if (suid != null) {
5640                    return suid.userId;
5641                }
5642            } catch (PackageManagerException ignore) {
5643                // can't happen, but, still need to catch it
5644            }
5645            return -1;
5646        }
5647    }
5648
5649    @Override
5650    public int getFlagsForUid(int uid) {
5651        final int callingUid = Binder.getCallingUid();
5652        if (getInstantAppPackageName(callingUid) != null) {
5653            return 0;
5654        }
5655        synchronized (mPackages) {
5656            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5657            if (obj instanceof SharedUserSetting) {
5658                final SharedUserSetting sus = (SharedUserSetting) obj;
5659                return sus.pkgFlags;
5660            } else if (obj instanceof PackageSetting) {
5661                final PackageSetting ps = (PackageSetting) obj;
5662                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5663                    return 0;
5664                }
5665                return ps.pkgFlags;
5666            }
5667        }
5668        return 0;
5669    }
5670
5671    @Override
5672    public int getPrivateFlagsForUid(int uid) {
5673        final int callingUid = Binder.getCallingUid();
5674        if (getInstantAppPackageName(callingUid) != null) {
5675            return 0;
5676        }
5677        synchronized (mPackages) {
5678            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5679            if (obj instanceof SharedUserSetting) {
5680                final SharedUserSetting sus = (SharedUserSetting) obj;
5681                return sus.pkgPrivateFlags;
5682            } else if (obj instanceof PackageSetting) {
5683                final PackageSetting ps = (PackageSetting) obj;
5684                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5685                    return 0;
5686                }
5687                return ps.pkgPrivateFlags;
5688            }
5689        }
5690        return 0;
5691    }
5692
5693    @Override
5694    public boolean isUidPrivileged(int uid) {
5695        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5696            return false;
5697        }
5698        uid = UserHandle.getAppId(uid);
5699        // reader
5700        synchronized (mPackages) {
5701            Object obj = mSettings.getUserIdLPr(uid);
5702            if (obj instanceof SharedUserSetting) {
5703                final SharedUserSetting sus = (SharedUserSetting) obj;
5704                final Iterator<PackageSetting> it = sus.packages.iterator();
5705                while (it.hasNext()) {
5706                    if (it.next().isPrivileged()) {
5707                        return true;
5708                    }
5709                }
5710            } else if (obj instanceof PackageSetting) {
5711                final PackageSetting ps = (PackageSetting) obj;
5712                return ps.isPrivileged();
5713            }
5714        }
5715        return false;
5716    }
5717
5718    @Override
5719    public String[] getAppOpPermissionPackages(String permName) {
5720        return mPermissionManager.getAppOpPermissionPackages(permName);
5721    }
5722
5723    @Override
5724    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5725            int flags, int userId) {
5726        return resolveIntentInternal(
5727                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5728    }
5729
5730    /**
5731     * Normally instant apps can only be resolved when they're visible to the caller.
5732     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5733     * since we need to allow the system to start any installed application.
5734     */
5735    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5736            int flags, int userId, boolean resolveForStart) {
5737        try {
5738            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5739
5740            if (!sUserManager.exists(userId)) return null;
5741            final int callingUid = Binder.getCallingUid();
5742            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5743            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5744                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5745
5746            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5747            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5748                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5749            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5750
5751            final ResolveInfo bestChoice =
5752                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5753            return bestChoice;
5754        } finally {
5755            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5756        }
5757    }
5758
5759    @Override
5760    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5761        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5762            throw new SecurityException(
5763                    "findPersistentPreferredActivity can only be run by the system");
5764        }
5765        if (!sUserManager.exists(userId)) {
5766            return null;
5767        }
5768        final int callingUid = Binder.getCallingUid();
5769        intent = updateIntentForResolve(intent);
5770        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5771        final int flags = updateFlagsForResolve(
5772                0, userId, intent, callingUid, false /*includeInstantApps*/);
5773        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5774                userId);
5775        synchronized (mPackages) {
5776            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5777                    userId);
5778        }
5779    }
5780
5781    @Override
5782    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5783            IntentFilter filter, int match, ComponentName activity) {
5784        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5785            return;
5786        }
5787        final int userId = UserHandle.getCallingUserId();
5788        if (DEBUG_PREFERRED) {
5789            Log.v(TAG, "setLastChosenActivity intent=" + intent
5790                + " resolvedType=" + resolvedType
5791                + " flags=" + flags
5792                + " filter=" + filter
5793                + " match=" + match
5794                + " activity=" + activity);
5795            filter.dump(new PrintStreamPrinter(System.out), "    ");
5796        }
5797        intent.setComponent(null);
5798        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5799                userId);
5800        // Find any earlier preferred or last chosen entries and nuke them
5801        findPreferredActivity(intent, resolvedType,
5802                flags, query, 0, false, true, false, userId);
5803        // Add the new activity as the last chosen for this filter
5804        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5805                "Setting last chosen");
5806    }
5807
5808    @Override
5809    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5810        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5811            return null;
5812        }
5813        final int userId = UserHandle.getCallingUserId();
5814        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5815        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5816                userId);
5817        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5818                false, false, false, userId);
5819    }
5820
5821    /**
5822     * Returns whether or not instant apps have been disabled remotely.
5823     */
5824    private boolean isEphemeralDisabled() {
5825        return mEphemeralAppsDisabled;
5826    }
5827
5828    private boolean isInstantAppAllowed(
5829            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5830            boolean skipPackageCheck) {
5831        if (mInstantAppResolverConnection == null) {
5832            return false;
5833        }
5834        if (mInstantAppInstallerActivity == null) {
5835            return false;
5836        }
5837        if (intent.getComponent() != null) {
5838            return false;
5839        }
5840        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5841            return false;
5842        }
5843        if (!skipPackageCheck && intent.getPackage() != null) {
5844            return false;
5845        }
5846        final boolean isWebUri = hasWebURI(intent);
5847        if (!isWebUri || intent.getData().getHost() == null) {
5848            return false;
5849        }
5850        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5851        // Or if there's already an ephemeral app installed that handles the action
5852        synchronized (mPackages) {
5853            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5854            for (int n = 0; n < count; n++) {
5855                final ResolveInfo info = resolvedActivities.get(n);
5856                final String packageName = info.activityInfo.packageName;
5857                final PackageSetting ps = mSettings.mPackages.get(packageName);
5858                if (ps != null) {
5859                    // only check domain verification status if the app is not a browser
5860                    if (!info.handleAllWebDataURI) {
5861                        // Try to get the status from User settings first
5862                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5863                        final int status = (int) (packedStatus >> 32);
5864                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5865                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5866                            if (DEBUG_EPHEMERAL) {
5867                                Slog.v(TAG, "DENY instant app;"
5868                                    + " pkg: " + packageName + ", status: " + status);
5869                            }
5870                            return false;
5871                        }
5872                    }
5873                    if (ps.getInstantApp(userId)) {
5874                        if (DEBUG_EPHEMERAL) {
5875                            Slog.v(TAG, "DENY instant app installed;"
5876                                    + " pkg: " + packageName);
5877                        }
5878                        return false;
5879                    }
5880                }
5881            }
5882        }
5883        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5884        return true;
5885    }
5886
5887    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5888            Intent origIntent, String resolvedType, String callingPackage,
5889            Bundle verificationBundle, int userId) {
5890        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5891                new InstantAppRequest(responseObj, origIntent, resolvedType,
5892                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
5893        mHandler.sendMessage(msg);
5894    }
5895
5896    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5897            int flags, List<ResolveInfo> query, int userId) {
5898        if (query != null) {
5899            final int N = query.size();
5900            if (N == 1) {
5901                return query.get(0);
5902            } else if (N > 1) {
5903                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5904                // If there is more than one activity with the same priority,
5905                // then let the user decide between them.
5906                ResolveInfo r0 = query.get(0);
5907                ResolveInfo r1 = query.get(1);
5908                if (DEBUG_INTENT_MATCHING || debug) {
5909                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5910                            + r1.activityInfo.name + "=" + r1.priority);
5911                }
5912                // If the first activity has a higher priority, or a different
5913                // default, then it is always desirable to pick it.
5914                if (r0.priority != r1.priority
5915                        || r0.preferredOrder != r1.preferredOrder
5916                        || r0.isDefault != r1.isDefault) {
5917                    return query.get(0);
5918                }
5919                // If we have saved a preference for a preferred activity for
5920                // this Intent, use that.
5921                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5922                        flags, query, r0.priority, true, false, debug, userId);
5923                if (ri != null) {
5924                    return ri;
5925                }
5926                // If we have an ephemeral app, use it
5927                for (int i = 0; i < N; i++) {
5928                    ri = query.get(i);
5929                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5930                        final String packageName = ri.activityInfo.packageName;
5931                        final PackageSetting ps = mSettings.mPackages.get(packageName);
5932                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5933                        final int status = (int)(packedStatus >> 32);
5934                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5935                            return ri;
5936                        }
5937                    }
5938                }
5939                ri = new ResolveInfo(mResolveInfo);
5940                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5941                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5942                // If all of the options come from the same package, show the application's
5943                // label and icon instead of the generic resolver's.
5944                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5945                // and then throw away the ResolveInfo itself, meaning that the caller loses
5946                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5947                // a fallback for this case; we only set the target package's resources on
5948                // the ResolveInfo, not the ActivityInfo.
5949                final String intentPackage = intent.getPackage();
5950                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5951                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5952                    ri.resolvePackageName = intentPackage;
5953                    if (userNeedsBadging(userId)) {
5954                        ri.noResourceId = true;
5955                    } else {
5956                        ri.icon = appi.icon;
5957                    }
5958                    ri.iconResourceId = appi.icon;
5959                    ri.labelRes = appi.labelRes;
5960                }
5961                ri.activityInfo.applicationInfo = new ApplicationInfo(
5962                        ri.activityInfo.applicationInfo);
5963                if (userId != 0) {
5964                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5965                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5966                }
5967                // Make sure that the resolver is displayable in car mode
5968                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5969                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5970                return ri;
5971            }
5972        }
5973        return null;
5974    }
5975
5976    /**
5977     * Return true if the given list is not empty and all of its contents have
5978     * an activityInfo with the given package name.
5979     */
5980    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5981        if (ArrayUtils.isEmpty(list)) {
5982            return false;
5983        }
5984        for (int i = 0, N = list.size(); i < N; i++) {
5985            final ResolveInfo ri = list.get(i);
5986            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5987            if (ai == null || !packageName.equals(ai.packageName)) {
5988                return false;
5989            }
5990        }
5991        return true;
5992    }
5993
5994    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5995            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5996        final int N = query.size();
5997        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5998                .get(userId);
5999        // Get the list of persistent preferred activities that handle the intent
6000        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6001        List<PersistentPreferredActivity> pprefs = ppir != null
6002                ? ppir.queryIntent(intent, resolvedType,
6003                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6004                        userId)
6005                : null;
6006        if (pprefs != null && pprefs.size() > 0) {
6007            final int M = pprefs.size();
6008            for (int i=0; i<M; i++) {
6009                final PersistentPreferredActivity ppa = pprefs.get(i);
6010                if (DEBUG_PREFERRED || debug) {
6011                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6012                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6013                            + "\n  component=" + ppa.mComponent);
6014                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6015                }
6016                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6017                        flags | MATCH_DISABLED_COMPONENTS, userId);
6018                if (DEBUG_PREFERRED || debug) {
6019                    Slog.v(TAG, "Found persistent preferred activity:");
6020                    if (ai != null) {
6021                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6022                    } else {
6023                        Slog.v(TAG, "  null");
6024                    }
6025                }
6026                if (ai == null) {
6027                    // This previously registered persistent preferred activity
6028                    // component is no longer known. Ignore it and do NOT remove it.
6029                    continue;
6030                }
6031                for (int j=0; j<N; j++) {
6032                    final ResolveInfo ri = query.get(j);
6033                    if (!ri.activityInfo.applicationInfo.packageName
6034                            .equals(ai.applicationInfo.packageName)) {
6035                        continue;
6036                    }
6037                    if (!ri.activityInfo.name.equals(ai.name)) {
6038                        continue;
6039                    }
6040                    //  Found a persistent preference that can handle the intent.
6041                    if (DEBUG_PREFERRED || debug) {
6042                        Slog.v(TAG, "Returning persistent preferred activity: " +
6043                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6044                    }
6045                    return ri;
6046                }
6047            }
6048        }
6049        return null;
6050    }
6051
6052    // TODO: handle preferred activities missing while user has amnesia
6053    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6054            List<ResolveInfo> query, int priority, boolean always,
6055            boolean removeMatches, boolean debug, int userId) {
6056        if (!sUserManager.exists(userId)) return null;
6057        final int callingUid = Binder.getCallingUid();
6058        flags = updateFlagsForResolve(
6059                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6060        intent = updateIntentForResolve(intent);
6061        // writer
6062        synchronized (mPackages) {
6063            // Try to find a matching persistent preferred activity.
6064            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6065                    debug, userId);
6066
6067            // If a persistent preferred activity matched, use it.
6068            if (pri != null) {
6069                return pri;
6070            }
6071
6072            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6073            // Get the list of preferred activities that handle the intent
6074            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6075            List<PreferredActivity> prefs = pir != null
6076                    ? pir.queryIntent(intent, resolvedType,
6077                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6078                            userId)
6079                    : null;
6080            if (prefs != null && prefs.size() > 0) {
6081                boolean changed = false;
6082                try {
6083                    // First figure out how good the original match set is.
6084                    // We will only allow preferred activities that came
6085                    // from the same match quality.
6086                    int match = 0;
6087
6088                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6089
6090                    final int N = query.size();
6091                    for (int j=0; j<N; j++) {
6092                        final ResolveInfo ri = query.get(j);
6093                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6094                                + ": 0x" + Integer.toHexString(match));
6095                        if (ri.match > match) {
6096                            match = ri.match;
6097                        }
6098                    }
6099
6100                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6101                            + Integer.toHexString(match));
6102
6103                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6104                    final int M = prefs.size();
6105                    for (int i=0; i<M; i++) {
6106                        final PreferredActivity pa = prefs.get(i);
6107                        if (DEBUG_PREFERRED || debug) {
6108                            Slog.v(TAG, "Checking PreferredActivity ds="
6109                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6110                                    + "\n  component=" + pa.mPref.mComponent);
6111                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6112                        }
6113                        if (pa.mPref.mMatch != match) {
6114                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6115                                    + Integer.toHexString(pa.mPref.mMatch));
6116                            continue;
6117                        }
6118                        // If it's not an "always" type preferred activity and that's what we're
6119                        // looking for, skip it.
6120                        if (always && !pa.mPref.mAlways) {
6121                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6122                            continue;
6123                        }
6124                        final ActivityInfo ai = getActivityInfo(
6125                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6126                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6127                                userId);
6128                        if (DEBUG_PREFERRED || debug) {
6129                            Slog.v(TAG, "Found preferred activity:");
6130                            if (ai != null) {
6131                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6132                            } else {
6133                                Slog.v(TAG, "  null");
6134                            }
6135                        }
6136                        if (ai == null) {
6137                            // This previously registered preferred activity
6138                            // component is no longer known.  Most likely an update
6139                            // to the app was installed and in the new version this
6140                            // component no longer exists.  Clean it up by removing
6141                            // it from the preferred activities list, and skip it.
6142                            Slog.w(TAG, "Removing dangling preferred activity: "
6143                                    + pa.mPref.mComponent);
6144                            pir.removeFilter(pa);
6145                            changed = true;
6146                            continue;
6147                        }
6148                        for (int j=0; j<N; j++) {
6149                            final ResolveInfo ri = query.get(j);
6150                            if (!ri.activityInfo.applicationInfo.packageName
6151                                    .equals(ai.applicationInfo.packageName)) {
6152                                continue;
6153                            }
6154                            if (!ri.activityInfo.name.equals(ai.name)) {
6155                                continue;
6156                            }
6157
6158                            if (removeMatches) {
6159                                pir.removeFilter(pa);
6160                                changed = true;
6161                                if (DEBUG_PREFERRED) {
6162                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6163                                }
6164                                break;
6165                            }
6166
6167                            // Okay we found a previously set preferred or last chosen app.
6168                            // If the result set is different from when this
6169                            // was created, and is not a subset of the preferred set, we need to
6170                            // clear it and re-ask the user their preference, if we're looking for
6171                            // an "always" type entry.
6172                            if (always && !pa.mPref.sameSet(query)) {
6173                                if (pa.mPref.isSuperset(query)) {
6174                                    // some components of the set are no longer present in
6175                                    // the query, but the preferred activity can still be reused
6176                                    if (DEBUG_PREFERRED) {
6177                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6178                                                + " still valid as only non-preferred components"
6179                                                + " were removed for " + intent + " type "
6180                                                + resolvedType);
6181                                    }
6182                                    // remove obsolete components and re-add the up-to-date filter
6183                                    PreferredActivity freshPa = new PreferredActivity(pa,
6184                                            pa.mPref.mMatch,
6185                                            pa.mPref.discardObsoleteComponents(query),
6186                                            pa.mPref.mComponent,
6187                                            pa.mPref.mAlways);
6188                                    pir.removeFilter(pa);
6189                                    pir.addFilter(freshPa);
6190                                    changed = true;
6191                                } else {
6192                                    Slog.i(TAG,
6193                                            "Result set changed, dropping preferred activity for "
6194                                                    + intent + " type " + resolvedType);
6195                                    if (DEBUG_PREFERRED) {
6196                                        Slog.v(TAG, "Removing preferred activity since set changed "
6197                                                + pa.mPref.mComponent);
6198                                    }
6199                                    pir.removeFilter(pa);
6200                                    // Re-add the filter as a "last chosen" entry (!always)
6201                                    PreferredActivity lastChosen = new PreferredActivity(
6202                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6203                                    pir.addFilter(lastChosen);
6204                                    changed = true;
6205                                    return null;
6206                                }
6207                            }
6208
6209                            // Yay! Either the set matched or we're looking for the last chosen
6210                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6211                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6212                            return ri;
6213                        }
6214                    }
6215                } finally {
6216                    if (changed) {
6217                        if (DEBUG_PREFERRED) {
6218                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6219                        }
6220                        scheduleWritePackageRestrictionsLocked(userId);
6221                    }
6222                }
6223            }
6224        }
6225        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6226        return null;
6227    }
6228
6229    /*
6230     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6231     */
6232    @Override
6233    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6234            int targetUserId) {
6235        mContext.enforceCallingOrSelfPermission(
6236                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6237        List<CrossProfileIntentFilter> matches =
6238                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6239        if (matches != null) {
6240            int size = matches.size();
6241            for (int i = 0; i < size; i++) {
6242                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6243            }
6244        }
6245        if (hasWebURI(intent)) {
6246            // cross-profile app linking works only towards the parent.
6247            final int callingUid = Binder.getCallingUid();
6248            final UserInfo parent = getProfileParent(sourceUserId);
6249            synchronized(mPackages) {
6250                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6251                        false /*includeInstantApps*/);
6252                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6253                        intent, resolvedType, flags, sourceUserId, parent.id);
6254                return xpDomainInfo != null;
6255            }
6256        }
6257        return false;
6258    }
6259
6260    private UserInfo getProfileParent(int userId) {
6261        final long identity = Binder.clearCallingIdentity();
6262        try {
6263            return sUserManager.getProfileParent(userId);
6264        } finally {
6265            Binder.restoreCallingIdentity(identity);
6266        }
6267    }
6268
6269    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6270            String resolvedType, int userId) {
6271        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6272        if (resolver != null) {
6273            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6274        }
6275        return null;
6276    }
6277
6278    @Override
6279    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6280            String resolvedType, int flags, int userId) {
6281        try {
6282            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6283
6284            return new ParceledListSlice<>(
6285                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6286        } finally {
6287            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6288        }
6289    }
6290
6291    /**
6292     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6293     * instant, returns {@code null}.
6294     */
6295    private String getInstantAppPackageName(int callingUid) {
6296        synchronized (mPackages) {
6297            // If the caller is an isolated app use the owner's uid for the lookup.
6298            if (Process.isIsolated(callingUid)) {
6299                callingUid = mIsolatedOwners.get(callingUid);
6300            }
6301            final int appId = UserHandle.getAppId(callingUid);
6302            final Object obj = mSettings.getUserIdLPr(appId);
6303            if (obj instanceof PackageSetting) {
6304                final PackageSetting ps = (PackageSetting) obj;
6305                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6306                return isInstantApp ? ps.pkg.packageName : null;
6307            }
6308        }
6309        return null;
6310    }
6311
6312    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6313            String resolvedType, int flags, int userId) {
6314        return queryIntentActivitiesInternal(
6315                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6316                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6317    }
6318
6319    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6320            String resolvedType, int flags, int filterCallingUid, int userId,
6321            boolean resolveForStart, boolean allowDynamicSplits) {
6322        if (!sUserManager.exists(userId)) return Collections.emptyList();
6323        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6324        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6325                false /* requireFullPermission */, false /* checkShell */,
6326                "query intent activities");
6327        final String pkgName = intent.getPackage();
6328        ComponentName comp = intent.getComponent();
6329        if (comp == null) {
6330            if (intent.getSelector() != null) {
6331                intent = intent.getSelector();
6332                comp = intent.getComponent();
6333            }
6334        }
6335
6336        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6337                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6338        if (comp != null) {
6339            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6340            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6341            if (ai != null) {
6342                // When specifying an explicit component, we prevent the activity from being
6343                // used when either 1) the calling package is normal and the activity is within
6344                // an ephemeral application or 2) the calling package is ephemeral and the
6345                // activity is not visible to ephemeral applications.
6346                final boolean matchInstantApp =
6347                        (flags & PackageManager.MATCH_INSTANT) != 0;
6348                final boolean matchVisibleToInstantAppOnly =
6349                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6350                final boolean matchExplicitlyVisibleOnly =
6351                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6352                final boolean isCallerInstantApp =
6353                        instantAppPkgName != null;
6354                final boolean isTargetSameInstantApp =
6355                        comp.getPackageName().equals(instantAppPkgName);
6356                final boolean isTargetInstantApp =
6357                        (ai.applicationInfo.privateFlags
6358                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6359                final boolean isTargetVisibleToInstantApp =
6360                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6361                final boolean isTargetExplicitlyVisibleToInstantApp =
6362                        isTargetVisibleToInstantApp
6363                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6364                final boolean isTargetHiddenFromInstantApp =
6365                        !isTargetVisibleToInstantApp
6366                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6367                final boolean blockResolution =
6368                        !isTargetSameInstantApp
6369                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6370                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6371                                        && isTargetHiddenFromInstantApp));
6372                if (!blockResolution) {
6373                    final ResolveInfo ri = new ResolveInfo();
6374                    ri.activityInfo = ai;
6375                    list.add(ri);
6376                }
6377            }
6378            return applyPostResolutionFilter(
6379                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6380        }
6381
6382        // reader
6383        boolean sortResult = false;
6384        boolean addEphemeral = false;
6385        List<ResolveInfo> result;
6386        final boolean ephemeralDisabled = isEphemeralDisabled();
6387        synchronized (mPackages) {
6388            if (pkgName == null) {
6389                List<CrossProfileIntentFilter> matchingFilters =
6390                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6391                // Check for results that need to skip the current profile.
6392                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6393                        resolvedType, flags, userId);
6394                if (xpResolveInfo != null) {
6395                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6396                    xpResult.add(xpResolveInfo);
6397                    return applyPostResolutionFilter(
6398                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6399                            allowDynamicSplits, filterCallingUid, userId);
6400                }
6401
6402                // Check for results in the current profile.
6403                result = filterIfNotSystemUser(mActivities.queryIntent(
6404                        intent, resolvedType, flags, userId), userId);
6405                addEphemeral = !ephemeralDisabled
6406                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6407                // Check for cross profile results.
6408                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6409                xpResolveInfo = queryCrossProfileIntents(
6410                        matchingFilters, intent, resolvedType, flags, userId,
6411                        hasNonNegativePriorityResult);
6412                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6413                    boolean isVisibleToUser = filterIfNotSystemUser(
6414                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6415                    if (isVisibleToUser) {
6416                        result.add(xpResolveInfo);
6417                        sortResult = true;
6418                    }
6419                }
6420                if (hasWebURI(intent)) {
6421                    CrossProfileDomainInfo xpDomainInfo = null;
6422                    final UserInfo parent = getProfileParent(userId);
6423                    if (parent != null) {
6424                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6425                                flags, userId, parent.id);
6426                    }
6427                    if (xpDomainInfo != null) {
6428                        if (xpResolveInfo != null) {
6429                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6430                            // in the result.
6431                            result.remove(xpResolveInfo);
6432                        }
6433                        if (result.size() == 0 && !addEphemeral) {
6434                            // No result in current profile, but found candidate in parent user.
6435                            // And we are not going to add emphemeral app, so we can return the
6436                            // result straight away.
6437                            result.add(xpDomainInfo.resolveInfo);
6438                            return applyPostResolutionFilter(result, instantAppPkgName,
6439                                    allowDynamicSplits, filterCallingUid, userId);
6440                        }
6441                    } else if (result.size() <= 1 && !addEphemeral) {
6442                        // No result in parent user and <= 1 result in current profile, and we
6443                        // are not going to add emphemeral app, so we can return the result without
6444                        // further processing.
6445                        return applyPostResolutionFilter(result, instantAppPkgName,
6446                                allowDynamicSplits, filterCallingUid, userId);
6447                    }
6448                    // We have more than one candidate (combining results from current and parent
6449                    // profile), so we need filtering and sorting.
6450                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6451                            intent, flags, result, xpDomainInfo, userId);
6452                    sortResult = true;
6453                }
6454            } else {
6455                final PackageParser.Package pkg = mPackages.get(pkgName);
6456                result = null;
6457                if (pkg != null) {
6458                    result = filterIfNotSystemUser(
6459                            mActivities.queryIntentForPackage(
6460                                    intent, resolvedType, flags, pkg.activities, userId),
6461                            userId);
6462                }
6463                if (result == null || result.size() == 0) {
6464                    // the caller wants to resolve for a particular package; however, there
6465                    // were no installed results, so, try to find an ephemeral result
6466                    addEphemeral = !ephemeralDisabled
6467                            && isInstantAppAllowed(
6468                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6469                    if (result == null) {
6470                        result = new ArrayList<>();
6471                    }
6472                }
6473            }
6474        }
6475        if (addEphemeral) {
6476            result = maybeAddInstantAppInstaller(
6477                    result, intent, resolvedType, flags, userId, resolveForStart);
6478        }
6479        if (sortResult) {
6480            Collections.sort(result, mResolvePrioritySorter);
6481        }
6482        return applyPostResolutionFilter(
6483                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6484    }
6485
6486    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6487            String resolvedType, int flags, int userId, boolean resolveForStart) {
6488        // first, check to see if we've got an instant app already installed
6489        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6490        ResolveInfo localInstantApp = null;
6491        boolean blockResolution = false;
6492        if (!alreadyResolvedLocally) {
6493            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6494                    flags
6495                        | PackageManager.GET_RESOLVED_FILTER
6496                        | PackageManager.MATCH_INSTANT
6497                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6498                    userId);
6499            for (int i = instantApps.size() - 1; i >= 0; --i) {
6500                final ResolveInfo info = instantApps.get(i);
6501                final String packageName = info.activityInfo.packageName;
6502                final PackageSetting ps = mSettings.mPackages.get(packageName);
6503                if (ps.getInstantApp(userId)) {
6504                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6505                    final int status = (int)(packedStatus >> 32);
6506                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6507                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6508                        // there's a local instant application installed, but, the user has
6509                        // chosen to never use it; skip resolution and don't acknowledge
6510                        // an instant application is even available
6511                        if (DEBUG_EPHEMERAL) {
6512                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6513                        }
6514                        blockResolution = true;
6515                        break;
6516                    } else {
6517                        // we have a locally installed instant application; skip resolution
6518                        // but acknowledge there's an instant application available
6519                        if (DEBUG_EPHEMERAL) {
6520                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6521                        }
6522                        localInstantApp = info;
6523                        break;
6524                    }
6525                }
6526            }
6527        }
6528        // no app installed, let's see if one's available
6529        AuxiliaryResolveInfo auxiliaryResponse = null;
6530        if (!blockResolution) {
6531            if (localInstantApp == null) {
6532                // we don't have an instant app locally, resolve externally
6533                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6534                final InstantAppRequest requestObject = new InstantAppRequest(
6535                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6536                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6537                        resolveForStart);
6538                auxiliaryResponse =
6539                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6540                                mContext, mInstantAppResolverConnection, requestObject);
6541                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6542            } else {
6543                // we have an instant application locally, but, we can't admit that since
6544                // callers shouldn't be able to determine prior browsing. create a dummy
6545                // auxiliary response so the downstream code behaves as if there's an
6546                // instant application available externally. when it comes time to start
6547                // the instant application, we'll do the right thing.
6548                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6549                auxiliaryResponse = new AuxiliaryResolveInfo(
6550                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
6551                        ai.versionCode, null /*failureIntent*/);
6552            }
6553        }
6554        if (auxiliaryResponse != null) {
6555            if (DEBUG_EPHEMERAL) {
6556                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6557            }
6558            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6559            final PackageSetting ps =
6560                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6561            if (ps != null) {
6562                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6563                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6564                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6565                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6566                // make sure this resolver is the default
6567                ephemeralInstaller.isDefault = true;
6568                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6569                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6570                // add a non-generic filter
6571                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6572                ephemeralInstaller.filter.addDataPath(
6573                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6574                ephemeralInstaller.isInstantAppAvailable = true;
6575                result.add(ephemeralInstaller);
6576            }
6577        }
6578        return result;
6579    }
6580
6581    private static class CrossProfileDomainInfo {
6582        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6583        ResolveInfo resolveInfo;
6584        /* Best domain verification status of the activities found in the other profile */
6585        int bestDomainVerificationStatus;
6586    }
6587
6588    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6589            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6590        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6591                sourceUserId)) {
6592            return null;
6593        }
6594        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6595                resolvedType, flags, parentUserId);
6596
6597        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6598            return null;
6599        }
6600        CrossProfileDomainInfo result = null;
6601        int size = resultTargetUser.size();
6602        for (int i = 0; i < size; i++) {
6603            ResolveInfo riTargetUser = resultTargetUser.get(i);
6604            // Intent filter verification is only for filters that specify a host. So don't return
6605            // those that handle all web uris.
6606            if (riTargetUser.handleAllWebDataURI) {
6607                continue;
6608            }
6609            String packageName = riTargetUser.activityInfo.packageName;
6610            PackageSetting ps = mSettings.mPackages.get(packageName);
6611            if (ps == null) {
6612                continue;
6613            }
6614            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6615            int status = (int)(verificationState >> 32);
6616            if (result == null) {
6617                result = new CrossProfileDomainInfo();
6618                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6619                        sourceUserId, parentUserId);
6620                result.bestDomainVerificationStatus = status;
6621            } else {
6622                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6623                        result.bestDomainVerificationStatus);
6624            }
6625        }
6626        // Don't consider matches with status NEVER across profiles.
6627        if (result != null && result.bestDomainVerificationStatus
6628                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6629            return null;
6630        }
6631        return result;
6632    }
6633
6634    /**
6635     * Verification statuses are ordered from the worse to the best, except for
6636     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6637     */
6638    private int bestDomainVerificationStatus(int status1, int status2) {
6639        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6640            return status2;
6641        }
6642        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6643            return status1;
6644        }
6645        return (int) MathUtils.max(status1, status2);
6646    }
6647
6648    private boolean isUserEnabled(int userId) {
6649        long callingId = Binder.clearCallingIdentity();
6650        try {
6651            UserInfo userInfo = sUserManager.getUserInfo(userId);
6652            return userInfo != null && userInfo.isEnabled();
6653        } finally {
6654            Binder.restoreCallingIdentity(callingId);
6655        }
6656    }
6657
6658    /**
6659     * Filter out activities with systemUserOnly flag set, when current user is not System.
6660     *
6661     * @return filtered list
6662     */
6663    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6664        if (userId == UserHandle.USER_SYSTEM) {
6665            return resolveInfos;
6666        }
6667        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6668            ResolveInfo info = resolveInfos.get(i);
6669            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6670                resolveInfos.remove(i);
6671            }
6672        }
6673        return resolveInfos;
6674    }
6675
6676    /**
6677     * Filters out ephemeral activities.
6678     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6679     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6680     *
6681     * @param resolveInfos The pre-filtered list of resolved activities
6682     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6683     *          is performed.
6684     * @return A filtered list of resolved activities.
6685     */
6686    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6687            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
6688        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6689            final ResolveInfo info = resolveInfos.get(i);
6690            // allow activities that are defined in the provided package
6691            if (allowDynamicSplits
6692                    && info.activityInfo.splitName != null
6693                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6694                            info.activityInfo.splitName)) {
6695                if (mInstantAppInstallerInfo == null) {
6696                    if (DEBUG_INSTALL) {
6697                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6698                    }
6699                    resolveInfos.remove(i);
6700                    continue;
6701                }
6702                // requested activity is defined in a split that hasn't been installed yet.
6703                // add the installer to the resolve list
6704                if (DEBUG_INSTALL) {
6705                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6706                }
6707                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6708                final ComponentName installFailureActivity = findInstallFailureActivity(
6709                        info.activityInfo.packageName,  filterCallingUid, userId);
6710                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6711                        info.activityInfo.packageName, info.activityInfo.splitName,
6712                        installFailureActivity,
6713                        info.activityInfo.applicationInfo.versionCode,
6714                        null /*failureIntent*/);
6715                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6716                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6717                // add a non-generic filter
6718                installerInfo.filter = new IntentFilter();
6719
6720                // This resolve info may appear in the chooser UI, so let us make it
6721                // look as the one it replaces as far as the user is concerned which
6722                // requires loading the correct label and icon for the resolve info.
6723                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6724                installerInfo.labelRes = info.resolveLabelResId();
6725                installerInfo.icon = info.resolveIconResId();
6726
6727                // propagate priority/preferred order/default
6728                installerInfo.priority = info.priority;
6729                installerInfo.preferredOrder = info.preferredOrder;
6730                installerInfo.isDefault = info.isDefault;
6731                resolveInfos.set(i, installerInfo);
6732                continue;
6733            }
6734            // caller is a full app, don't need to apply any other filtering
6735            if (ephemeralPkgName == null) {
6736                continue;
6737            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6738                // caller is same app; don't need to apply any other filtering
6739                continue;
6740            }
6741            // allow activities that have been explicitly exposed to ephemeral apps
6742            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6743            if (!isEphemeralApp
6744                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6745                continue;
6746            }
6747            resolveInfos.remove(i);
6748        }
6749        return resolveInfos;
6750    }
6751
6752    /**
6753     * Returns the activity component that can handle install failures.
6754     * <p>By default, the instant application installer handles failures. However, an
6755     * application may want to handle failures on its own. Applications do this by
6756     * creating an activity with an intent filter that handles the action
6757     * {@link Intent#ACTION_INSTALL_FAILURE}.
6758     */
6759    private @Nullable ComponentName findInstallFailureActivity(
6760            String packageName, int filterCallingUid, int userId) {
6761        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6762        failureActivityIntent.setPackage(packageName);
6763        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6764        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6765                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6766                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6767        final int NR = result.size();
6768        if (NR > 0) {
6769            for (int i = 0; i < NR; i++) {
6770                final ResolveInfo info = result.get(i);
6771                if (info.activityInfo.splitName != null) {
6772                    continue;
6773                }
6774                return new ComponentName(packageName, info.activityInfo.name);
6775            }
6776        }
6777        return null;
6778    }
6779
6780    /**
6781     * @param resolveInfos list of resolve infos in descending priority order
6782     * @return if the list contains a resolve info with non-negative priority
6783     */
6784    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6785        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6786    }
6787
6788    private static boolean hasWebURI(Intent intent) {
6789        if (intent.getData() == null) {
6790            return false;
6791        }
6792        final String scheme = intent.getScheme();
6793        if (TextUtils.isEmpty(scheme)) {
6794            return false;
6795        }
6796        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6797    }
6798
6799    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6800            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6801            int userId) {
6802        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6803
6804        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6805            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6806                    candidates.size());
6807        }
6808
6809        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6810        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6811        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6812        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6813        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6814        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6815
6816        synchronized (mPackages) {
6817            final int count = candidates.size();
6818            // First, try to use linked apps. Partition the candidates into four lists:
6819            // one for the final results, one for the "do not use ever", one for "undefined status"
6820            // and finally one for "browser app type".
6821            for (int n=0; n<count; n++) {
6822                ResolveInfo info = candidates.get(n);
6823                String packageName = info.activityInfo.packageName;
6824                PackageSetting ps = mSettings.mPackages.get(packageName);
6825                if (ps != null) {
6826                    // Add to the special match all list (Browser use case)
6827                    if (info.handleAllWebDataURI) {
6828                        matchAllList.add(info);
6829                        continue;
6830                    }
6831                    // Try to get the status from User settings first
6832                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6833                    int status = (int)(packedStatus >> 32);
6834                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6835                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6836                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6837                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6838                                    + " : linkgen=" + linkGeneration);
6839                        }
6840                        // Use link-enabled generation as preferredOrder, i.e.
6841                        // prefer newly-enabled over earlier-enabled.
6842                        info.preferredOrder = linkGeneration;
6843                        alwaysList.add(info);
6844                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6845                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6846                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6847                        }
6848                        neverList.add(info);
6849                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6850                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6851                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6852                        }
6853                        alwaysAskList.add(info);
6854                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6855                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6856                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6857                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6858                        }
6859                        undefinedList.add(info);
6860                    }
6861                }
6862            }
6863
6864            // We'll want to include browser possibilities in a few cases
6865            boolean includeBrowser = false;
6866
6867            // First try to add the "always" resolution(s) for the current user, if any
6868            if (alwaysList.size() > 0) {
6869                result.addAll(alwaysList);
6870            } else {
6871                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6872                result.addAll(undefinedList);
6873                // Maybe add one for the other profile.
6874                if (xpDomainInfo != null && (
6875                        xpDomainInfo.bestDomainVerificationStatus
6876                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6877                    result.add(xpDomainInfo.resolveInfo);
6878                }
6879                includeBrowser = true;
6880            }
6881
6882            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6883            // If there were 'always' entries their preferred order has been set, so we also
6884            // back that off to make the alternatives equivalent
6885            if (alwaysAskList.size() > 0) {
6886                for (ResolveInfo i : result) {
6887                    i.preferredOrder = 0;
6888                }
6889                result.addAll(alwaysAskList);
6890                includeBrowser = true;
6891            }
6892
6893            if (includeBrowser) {
6894                // Also add browsers (all of them or only the default one)
6895                if (DEBUG_DOMAIN_VERIFICATION) {
6896                    Slog.v(TAG, "   ...including browsers in candidate set");
6897                }
6898                if ((matchFlags & MATCH_ALL) != 0) {
6899                    result.addAll(matchAllList);
6900                } else {
6901                    // Browser/generic handling case.  If there's a default browser, go straight
6902                    // to that (but only if there is no other higher-priority match).
6903                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6904                    int maxMatchPrio = 0;
6905                    ResolveInfo defaultBrowserMatch = null;
6906                    final int numCandidates = matchAllList.size();
6907                    for (int n = 0; n < numCandidates; n++) {
6908                        ResolveInfo info = matchAllList.get(n);
6909                        // track the highest overall match priority...
6910                        if (info.priority > maxMatchPrio) {
6911                            maxMatchPrio = info.priority;
6912                        }
6913                        // ...and the highest-priority default browser match
6914                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6915                            if (defaultBrowserMatch == null
6916                                    || (defaultBrowserMatch.priority < info.priority)) {
6917                                if (debug) {
6918                                    Slog.v(TAG, "Considering default browser match " + info);
6919                                }
6920                                defaultBrowserMatch = info;
6921                            }
6922                        }
6923                    }
6924                    if (defaultBrowserMatch != null
6925                            && defaultBrowserMatch.priority >= maxMatchPrio
6926                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6927                    {
6928                        if (debug) {
6929                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6930                        }
6931                        result.add(defaultBrowserMatch);
6932                    } else {
6933                        result.addAll(matchAllList);
6934                    }
6935                }
6936
6937                // If there is nothing selected, add all candidates and remove the ones that the user
6938                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6939                if (result.size() == 0) {
6940                    result.addAll(candidates);
6941                    result.removeAll(neverList);
6942                }
6943            }
6944        }
6945        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6946            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6947                    result.size());
6948            for (ResolveInfo info : result) {
6949                Slog.v(TAG, "  + " + info.activityInfo);
6950            }
6951        }
6952        return result;
6953    }
6954
6955    // Returns a packed value as a long:
6956    //
6957    // high 'int'-sized word: link status: undefined/ask/never/always.
6958    // low 'int'-sized word: relative priority among 'always' results.
6959    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6960        long result = ps.getDomainVerificationStatusForUser(userId);
6961        // if none available, get the master status
6962        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6963            if (ps.getIntentFilterVerificationInfo() != null) {
6964                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6965            }
6966        }
6967        return result;
6968    }
6969
6970    private ResolveInfo querySkipCurrentProfileIntents(
6971            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6972            int flags, int sourceUserId) {
6973        if (matchingFilters != null) {
6974            int size = matchingFilters.size();
6975            for (int i = 0; i < size; i ++) {
6976                CrossProfileIntentFilter filter = matchingFilters.get(i);
6977                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6978                    // Checking if there are activities in the target user that can handle the
6979                    // intent.
6980                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6981                            resolvedType, flags, sourceUserId);
6982                    if (resolveInfo != null) {
6983                        return resolveInfo;
6984                    }
6985                }
6986            }
6987        }
6988        return null;
6989    }
6990
6991    // Return matching ResolveInfo in target user if any.
6992    private ResolveInfo queryCrossProfileIntents(
6993            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6994            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6995        if (matchingFilters != null) {
6996            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6997            // match the same intent. For performance reasons, it is better not to
6998            // run queryIntent twice for the same userId
6999            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7000            int size = matchingFilters.size();
7001            for (int i = 0; i < size; i++) {
7002                CrossProfileIntentFilter filter = matchingFilters.get(i);
7003                int targetUserId = filter.getTargetUserId();
7004                boolean skipCurrentProfile =
7005                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7006                boolean skipCurrentProfileIfNoMatchFound =
7007                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7008                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7009                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7010                    // Checking if there are activities in the target user that can handle the
7011                    // intent.
7012                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7013                            resolvedType, flags, sourceUserId);
7014                    if (resolveInfo != null) return resolveInfo;
7015                    alreadyTriedUserIds.put(targetUserId, true);
7016                }
7017            }
7018        }
7019        return null;
7020    }
7021
7022    /**
7023     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7024     * will forward the intent to the filter's target user.
7025     * Otherwise, returns null.
7026     */
7027    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7028            String resolvedType, int flags, int sourceUserId) {
7029        int targetUserId = filter.getTargetUserId();
7030        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7031                resolvedType, flags, targetUserId);
7032        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7033            // If all the matches in the target profile are suspended, return null.
7034            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7035                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7036                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7037                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7038                            targetUserId);
7039                }
7040            }
7041        }
7042        return null;
7043    }
7044
7045    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7046            int sourceUserId, int targetUserId) {
7047        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7048        long ident = Binder.clearCallingIdentity();
7049        boolean targetIsProfile;
7050        try {
7051            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7052        } finally {
7053            Binder.restoreCallingIdentity(ident);
7054        }
7055        String className;
7056        if (targetIsProfile) {
7057            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7058        } else {
7059            className = FORWARD_INTENT_TO_PARENT;
7060        }
7061        ComponentName forwardingActivityComponentName = new ComponentName(
7062                mAndroidApplication.packageName, className);
7063        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7064                sourceUserId);
7065        if (!targetIsProfile) {
7066            forwardingActivityInfo.showUserIcon = targetUserId;
7067            forwardingResolveInfo.noResourceId = true;
7068        }
7069        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7070        forwardingResolveInfo.priority = 0;
7071        forwardingResolveInfo.preferredOrder = 0;
7072        forwardingResolveInfo.match = 0;
7073        forwardingResolveInfo.isDefault = true;
7074        forwardingResolveInfo.filter = filter;
7075        forwardingResolveInfo.targetUserId = targetUserId;
7076        return forwardingResolveInfo;
7077    }
7078
7079    @Override
7080    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7081            Intent[] specifics, String[] specificTypes, Intent intent,
7082            String resolvedType, int flags, int userId) {
7083        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7084                specificTypes, intent, resolvedType, flags, userId));
7085    }
7086
7087    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7088            Intent[] specifics, String[] specificTypes, Intent intent,
7089            String resolvedType, int flags, int userId) {
7090        if (!sUserManager.exists(userId)) return Collections.emptyList();
7091        final int callingUid = Binder.getCallingUid();
7092        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7093                false /*includeInstantApps*/);
7094        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7095                false /*requireFullPermission*/, false /*checkShell*/,
7096                "query intent activity options");
7097        final String resultsAction = intent.getAction();
7098
7099        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7100                | PackageManager.GET_RESOLVED_FILTER, userId);
7101
7102        if (DEBUG_INTENT_MATCHING) {
7103            Log.v(TAG, "Query " + intent + ": " + results);
7104        }
7105
7106        int specificsPos = 0;
7107        int N;
7108
7109        // todo: note that the algorithm used here is O(N^2).  This
7110        // isn't a problem in our current environment, but if we start running
7111        // into situations where we have more than 5 or 10 matches then this
7112        // should probably be changed to something smarter...
7113
7114        // First we go through and resolve each of the specific items
7115        // that were supplied, taking care of removing any corresponding
7116        // duplicate items in the generic resolve list.
7117        if (specifics != null) {
7118            for (int i=0; i<specifics.length; i++) {
7119                final Intent sintent = specifics[i];
7120                if (sintent == null) {
7121                    continue;
7122                }
7123
7124                if (DEBUG_INTENT_MATCHING) {
7125                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7126                }
7127
7128                String action = sintent.getAction();
7129                if (resultsAction != null && resultsAction.equals(action)) {
7130                    // If this action was explicitly requested, then don't
7131                    // remove things that have it.
7132                    action = null;
7133                }
7134
7135                ResolveInfo ri = null;
7136                ActivityInfo ai = null;
7137
7138                ComponentName comp = sintent.getComponent();
7139                if (comp == null) {
7140                    ri = resolveIntent(
7141                        sintent,
7142                        specificTypes != null ? specificTypes[i] : null,
7143                            flags, userId);
7144                    if (ri == null) {
7145                        continue;
7146                    }
7147                    if (ri == mResolveInfo) {
7148                        // ACK!  Must do something better with this.
7149                    }
7150                    ai = ri.activityInfo;
7151                    comp = new ComponentName(ai.applicationInfo.packageName,
7152                            ai.name);
7153                } else {
7154                    ai = getActivityInfo(comp, flags, userId);
7155                    if (ai == null) {
7156                        continue;
7157                    }
7158                }
7159
7160                // Look for any generic query activities that are duplicates
7161                // of this specific one, and remove them from the results.
7162                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7163                N = results.size();
7164                int j;
7165                for (j=specificsPos; j<N; j++) {
7166                    ResolveInfo sri = results.get(j);
7167                    if ((sri.activityInfo.name.equals(comp.getClassName())
7168                            && sri.activityInfo.applicationInfo.packageName.equals(
7169                                    comp.getPackageName()))
7170                        || (action != null && sri.filter.matchAction(action))) {
7171                        results.remove(j);
7172                        if (DEBUG_INTENT_MATCHING) Log.v(
7173                            TAG, "Removing duplicate item from " + j
7174                            + " due to specific " + specificsPos);
7175                        if (ri == null) {
7176                            ri = sri;
7177                        }
7178                        j--;
7179                        N--;
7180                    }
7181                }
7182
7183                // Add this specific item to its proper place.
7184                if (ri == null) {
7185                    ri = new ResolveInfo();
7186                    ri.activityInfo = ai;
7187                }
7188                results.add(specificsPos, ri);
7189                ri.specificIndex = i;
7190                specificsPos++;
7191            }
7192        }
7193
7194        // Now we go through the remaining generic results and remove any
7195        // duplicate actions that are found here.
7196        N = results.size();
7197        for (int i=specificsPos; i<N-1; i++) {
7198            final ResolveInfo rii = results.get(i);
7199            if (rii.filter == null) {
7200                continue;
7201            }
7202
7203            // Iterate over all of the actions of this result's intent
7204            // filter...  typically this should be just one.
7205            final Iterator<String> it = rii.filter.actionsIterator();
7206            if (it == null) {
7207                continue;
7208            }
7209            while (it.hasNext()) {
7210                final String action = it.next();
7211                if (resultsAction != null && resultsAction.equals(action)) {
7212                    // If this action was explicitly requested, then don't
7213                    // remove things that have it.
7214                    continue;
7215                }
7216                for (int j=i+1; j<N; j++) {
7217                    final ResolveInfo rij = results.get(j);
7218                    if (rij.filter != null && rij.filter.hasAction(action)) {
7219                        results.remove(j);
7220                        if (DEBUG_INTENT_MATCHING) Log.v(
7221                            TAG, "Removing duplicate item from " + j
7222                            + " due to action " + action + " at " + i);
7223                        j--;
7224                        N--;
7225                    }
7226                }
7227            }
7228
7229            // If the caller didn't request filter information, drop it now
7230            // so we don't have to marshall/unmarshall it.
7231            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7232                rii.filter = null;
7233            }
7234        }
7235
7236        // Filter out the caller activity if so requested.
7237        if (caller != null) {
7238            N = results.size();
7239            for (int i=0; i<N; i++) {
7240                ActivityInfo ainfo = results.get(i).activityInfo;
7241                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7242                        && caller.getClassName().equals(ainfo.name)) {
7243                    results.remove(i);
7244                    break;
7245                }
7246            }
7247        }
7248
7249        // If the caller didn't request filter information,
7250        // drop them now so we don't have to
7251        // marshall/unmarshall it.
7252        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7253            N = results.size();
7254            for (int i=0; i<N; i++) {
7255                results.get(i).filter = null;
7256            }
7257        }
7258
7259        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7260        return results;
7261    }
7262
7263    @Override
7264    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7265            String resolvedType, int flags, int userId) {
7266        return new ParceledListSlice<>(
7267                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7268                        false /*allowDynamicSplits*/));
7269    }
7270
7271    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7272            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7273        if (!sUserManager.exists(userId)) return Collections.emptyList();
7274        final int callingUid = Binder.getCallingUid();
7275        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7276                false /*requireFullPermission*/, false /*checkShell*/,
7277                "query intent receivers");
7278        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7279        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7280                false /*includeInstantApps*/);
7281        ComponentName comp = intent.getComponent();
7282        if (comp == null) {
7283            if (intent.getSelector() != null) {
7284                intent = intent.getSelector();
7285                comp = intent.getComponent();
7286            }
7287        }
7288        if (comp != null) {
7289            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7290            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7291            if (ai != null) {
7292                // When specifying an explicit component, we prevent the activity from being
7293                // used when either 1) the calling package is normal and the activity is within
7294                // an instant application or 2) the calling package is ephemeral and the
7295                // activity is not visible to instant applications.
7296                final boolean matchInstantApp =
7297                        (flags & PackageManager.MATCH_INSTANT) != 0;
7298                final boolean matchVisibleToInstantAppOnly =
7299                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7300                final boolean matchExplicitlyVisibleOnly =
7301                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7302                final boolean isCallerInstantApp =
7303                        instantAppPkgName != null;
7304                final boolean isTargetSameInstantApp =
7305                        comp.getPackageName().equals(instantAppPkgName);
7306                final boolean isTargetInstantApp =
7307                        (ai.applicationInfo.privateFlags
7308                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7309                final boolean isTargetVisibleToInstantApp =
7310                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7311                final boolean isTargetExplicitlyVisibleToInstantApp =
7312                        isTargetVisibleToInstantApp
7313                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7314                final boolean isTargetHiddenFromInstantApp =
7315                        !isTargetVisibleToInstantApp
7316                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7317                final boolean blockResolution =
7318                        !isTargetSameInstantApp
7319                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7320                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7321                                        && isTargetHiddenFromInstantApp));
7322                if (!blockResolution) {
7323                    ResolveInfo ri = new ResolveInfo();
7324                    ri.activityInfo = ai;
7325                    list.add(ri);
7326                }
7327            }
7328            return applyPostResolutionFilter(
7329                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7330        }
7331
7332        // reader
7333        synchronized (mPackages) {
7334            String pkgName = intent.getPackage();
7335            if (pkgName == null) {
7336                final List<ResolveInfo> result =
7337                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7338                return applyPostResolutionFilter(
7339                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7340            }
7341            final PackageParser.Package pkg = mPackages.get(pkgName);
7342            if (pkg != null) {
7343                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7344                        intent, resolvedType, flags, pkg.receivers, userId);
7345                return applyPostResolutionFilter(
7346                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7347            }
7348            return Collections.emptyList();
7349        }
7350    }
7351
7352    @Override
7353    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7354        final int callingUid = Binder.getCallingUid();
7355        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7356    }
7357
7358    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7359            int userId, int callingUid) {
7360        if (!sUserManager.exists(userId)) return null;
7361        flags = updateFlagsForResolve(
7362                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7363        List<ResolveInfo> query = queryIntentServicesInternal(
7364                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7365        if (query != null) {
7366            if (query.size() >= 1) {
7367                // If there is more than one service with the same priority,
7368                // just arbitrarily pick the first one.
7369                return query.get(0);
7370            }
7371        }
7372        return null;
7373    }
7374
7375    @Override
7376    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7377            String resolvedType, int flags, int userId) {
7378        final int callingUid = Binder.getCallingUid();
7379        return new ParceledListSlice<>(queryIntentServicesInternal(
7380                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7381    }
7382
7383    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7384            String resolvedType, int flags, int userId, int callingUid,
7385            boolean includeInstantApps) {
7386        if (!sUserManager.exists(userId)) return Collections.emptyList();
7387        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7388                false /*requireFullPermission*/, false /*checkShell*/,
7389                "query intent receivers");
7390        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7391        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7392        ComponentName comp = intent.getComponent();
7393        if (comp == null) {
7394            if (intent.getSelector() != null) {
7395                intent = intent.getSelector();
7396                comp = intent.getComponent();
7397            }
7398        }
7399        if (comp != null) {
7400            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7401            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7402            if (si != null) {
7403                // When specifying an explicit component, we prevent the service from being
7404                // used when either 1) the service is in an instant application and the
7405                // caller is not the same instant application or 2) the calling package is
7406                // ephemeral and the activity is not visible to ephemeral applications.
7407                final boolean matchInstantApp =
7408                        (flags & PackageManager.MATCH_INSTANT) != 0;
7409                final boolean matchVisibleToInstantAppOnly =
7410                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7411                final boolean isCallerInstantApp =
7412                        instantAppPkgName != null;
7413                final boolean isTargetSameInstantApp =
7414                        comp.getPackageName().equals(instantAppPkgName);
7415                final boolean isTargetInstantApp =
7416                        (si.applicationInfo.privateFlags
7417                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7418                final boolean isTargetHiddenFromInstantApp =
7419                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7420                final boolean blockResolution =
7421                        !isTargetSameInstantApp
7422                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7423                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7424                                        && isTargetHiddenFromInstantApp));
7425                if (!blockResolution) {
7426                    final ResolveInfo ri = new ResolveInfo();
7427                    ri.serviceInfo = si;
7428                    list.add(ri);
7429                }
7430            }
7431            return list;
7432        }
7433
7434        // reader
7435        synchronized (mPackages) {
7436            String pkgName = intent.getPackage();
7437            if (pkgName == null) {
7438                return applyPostServiceResolutionFilter(
7439                        mServices.queryIntent(intent, resolvedType, flags, userId),
7440                        instantAppPkgName);
7441            }
7442            final PackageParser.Package pkg = mPackages.get(pkgName);
7443            if (pkg != null) {
7444                return applyPostServiceResolutionFilter(
7445                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7446                                userId),
7447                        instantAppPkgName);
7448            }
7449            return Collections.emptyList();
7450        }
7451    }
7452
7453    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7454            String instantAppPkgName) {
7455        if (instantAppPkgName == null) {
7456            return resolveInfos;
7457        }
7458        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7459            final ResolveInfo info = resolveInfos.get(i);
7460            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7461            // allow services that are defined in the provided package
7462            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7463                if (info.serviceInfo.splitName != null
7464                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7465                                info.serviceInfo.splitName)) {
7466                    // requested service is defined in a split that hasn't been installed yet.
7467                    // add the installer to the resolve list
7468                    if (DEBUG_EPHEMERAL) {
7469                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7470                    }
7471                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7472                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7473                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7474                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
7475                            null /*failureIntent*/);
7476                    // make sure this resolver is the default
7477                    installerInfo.isDefault = true;
7478                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7479                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7480                    // add a non-generic filter
7481                    installerInfo.filter = new IntentFilter();
7482                    // load resources from the correct package
7483                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7484                    resolveInfos.set(i, installerInfo);
7485                }
7486                continue;
7487            }
7488            // allow services that have been explicitly exposed to ephemeral apps
7489            if (!isEphemeralApp
7490                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7491                continue;
7492            }
7493            resolveInfos.remove(i);
7494        }
7495        return resolveInfos;
7496    }
7497
7498    @Override
7499    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7500            String resolvedType, int flags, int userId) {
7501        return new ParceledListSlice<>(
7502                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7503    }
7504
7505    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7506            Intent intent, String resolvedType, int flags, int userId) {
7507        if (!sUserManager.exists(userId)) return Collections.emptyList();
7508        final int callingUid = Binder.getCallingUid();
7509        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7510        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7511                false /*includeInstantApps*/);
7512        ComponentName comp = intent.getComponent();
7513        if (comp == null) {
7514            if (intent.getSelector() != null) {
7515                intent = intent.getSelector();
7516                comp = intent.getComponent();
7517            }
7518        }
7519        if (comp != null) {
7520            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7521            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7522            if (pi != null) {
7523                // When specifying an explicit component, we prevent the provider from being
7524                // used when either 1) the provider is in an instant application and the
7525                // caller is not the same instant application or 2) the calling package is an
7526                // instant application and the provider is not visible to instant applications.
7527                final boolean matchInstantApp =
7528                        (flags & PackageManager.MATCH_INSTANT) != 0;
7529                final boolean matchVisibleToInstantAppOnly =
7530                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7531                final boolean isCallerInstantApp =
7532                        instantAppPkgName != null;
7533                final boolean isTargetSameInstantApp =
7534                        comp.getPackageName().equals(instantAppPkgName);
7535                final boolean isTargetInstantApp =
7536                        (pi.applicationInfo.privateFlags
7537                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7538                final boolean isTargetHiddenFromInstantApp =
7539                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7540                final boolean blockResolution =
7541                        !isTargetSameInstantApp
7542                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7543                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7544                                        && isTargetHiddenFromInstantApp));
7545                if (!blockResolution) {
7546                    final ResolveInfo ri = new ResolveInfo();
7547                    ri.providerInfo = pi;
7548                    list.add(ri);
7549                }
7550            }
7551            return list;
7552        }
7553
7554        // reader
7555        synchronized (mPackages) {
7556            String pkgName = intent.getPackage();
7557            if (pkgName == null) {
7558                return applyPostContentProviderResolutionFilter(
7559                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7560                        instantAppPkgName);
7561            }
7562            final PackageParser.Package pkg = mPackages.get(pkgName);
7563            if (pkg != null) {
7564                return applyPostContentProviderResolutionFilter(
7565                        mProviders.queryIntentForPackage(
7566                        intent, resolvedType, flags, pkg.providers, userId),
7567                        instantAppPkgName);
7568            }
7569            return Collections.emptyList();
7570        }
7571    }
7572
7573    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7574            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7575        if (instantAppPkgName == null) {
7576            return resolveInfos;
7577        }
7578        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7579            final ResolveInfo info = resolveInfos.get(i);
7580            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7581            // allow providers that are defined in the provided package
7582            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7583                if (info.providerInfo.splitName != null
7584                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7585                                info.providerInfo.splitName)) {
7586                    // requested provider is defined in a split that hasn't been installed yet.
7587                    // add the installer to the resolve list
7588                    if (DEBUG_EPHEMERAL) {
7589                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7590                    }
7591                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7592                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7593                            info.providerInfo.packageName, info.providerInfo.splitName,
7594                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
7595                            null /*failureIntent*/);
7596                    // make sure this resolver is the default
7597                    installerInfo.isDefault = true;
7598                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7599                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7600                    // add a non-generic filter
7601                    installerInfo.filter = new IntentFilter();
7602                    // load resources from the correct package
7603                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7604                    resolveInfos.set(i, installerInfo);
7605                }
7606                continue;
7607            }
7608            // allow providers that have been explicitly exposed to instant applications
7609            if (!isEphemeralApp
7610                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7611                continue;
7612            }
7613            resolveInfos.remove(i);
7614        }
7615        return resolveInfos;
7616    }
7617
7618    @Override
7619    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7620        final int callingUid = Binder.getCallingUid();
7621        if (getInstantAppPackageName(callingUid) != null) {
7622            return ParceledListSlice.emptyList();
7623        }
7624        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7625        flags = updateFlagsForPackage(flags, userId, null);
7626        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7627        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7628                true /* requireFullPermission */, false /* checkShell */,
7629                "get installed packages");
7630
7631        // writer
7632        synchronized (mPackages) {
7633            ArrayList<PackageInfo> list;
7634            if (listUninstalled) {
7635                list = new ArrayList<>(mSettings.mPackages.size());
7636                for (PackageSetting ps : mSettings.mPackages.values()) {
7637                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7638                        continue;
7639                    }
7640                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7641                        continue;
7642                    }
7643                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7644                    if (pi != null) {
7645                        list.add(pi);
7646                    }
7647                }
7648            } else {
7649                list = new ArrayList<>(mPackages.size());
7650                for (PackageParser.Package p : mPackages.values()) {
7651                    final PackageSetting ps = (PackageSetting) p.mExtras;
7652                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7653                        continue;
7654                    }
7655                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7656                        continue;
7657                    }
7658                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7659                            p.mExtras, flags, userId);
7660                    if (pi != null) {
7661                        list.add(pi);
7662                    }
7663                }
7664            }
7665
7666            return new ParceledListSlice<>(list);
7667        }
7668    }
7669
7670    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7671            String[] permissions, boolean[] tmp, int flags, int userId) {
7672        int numMatch = 0;
7673        final PermissionsState permissionsState = ps.getPermissionsState();
7674        for (int i=0; i<permissions.length; i++) {
7675            final String permission = permissions[i];
7676            if (permissionsState.hasPermission(permission, userId)) {
7677                tmp[i] = true;
7678                numMatch++;
7679            } else {
7680                tmp[i] = false;
7681            }
7682        }
7683        if (numMatch == 0) {
7684            return;
7685        }
7686        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7687
7688        // The above might return null in cases of uninstalled apps or install-state
7689        // skew across users/profiles.
7690        if (pi != null) {
7691            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7692                if (numMatch == permissions.length) {
7693                    pi.requestedPermissions = permissions;
7694                } else {
7695                    pi.requestedPermissions = new String[numMatch];
7696                    numMatch = 0;
7697                    for (int i=0; i<permissions.length; i++) {
7698                        if (tmp[i]) {
7699                            pi.requestedPermissions[numMatch] = permissions[i];
7700                            numMatch++;
7701                        }
7702                    }
7703                }
7704            }
7705            list.add(pi);
7706        }
7707    }
7708
7709    @Override
7710    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7711            String[] permissions, int flags, int userId) {
7712        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7713        flags = updateFlagsForPackage(flags, userId, permissions);
7714        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7715                true /* requireFullPermission */, false /* checkShell */,
7716                "get packages holding permissions");
7717        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7718
7719        // writer
7720        synchronized (mPackages) {
7721            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7722            boolean[] tmpBools = new boolean[permissions.length];
7723            if (listUninstalled) {
7724                for (PackageSetting ps : mSettings.mPackages.values()) {
7725                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7726                            userId);
7727                }
7728            } else {
7729                for (PackageParser.Package pkg : mPackages.values()) {
7730                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7731                    if (ps != null) {
7732                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7733                                userId);
7734                    }
7735                }
7736            }
7737
7738            return new ParceledListSlice<PackageInfo>(list);
7739        }
7740    }
7741
7742    @Override
7743    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7744        final int callingUid = Binder.getCallingUid();
7745        if (getInstantAppPackageName(callingUid) != null) {
7746            return ParceledListSlice.emptyList();
7747        }
7748        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7749        flags = updateFlagsForApplication(flags, userId, null);
7750        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7751
7752        // writer
7753        synchronized (mPackages) {
7754            ArrayList<ApplicationInfo> list;
7755            if (listUninstalled) {
7756                list = new ArrayList<>(mSettings.mPackages.size());
7757                for (PackageSetting ps : mSettings.mPackages.values()) {
7758                    ApplicationInfo ai;
7759                    int effectiveFlags = flags;
7760                    if (ps.isSystem()) {
7761                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7762                    }
7763                    if (ps.pkg != null) {
7764                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7765                            continue;
7766                        }
7767                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7768                            continue;
7769                        }
7770                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7771                                ps.readUserState(userId), userId);
7772                        if (ai != null) {
7773                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7774                        }
7775                    } else {
7776                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7777                        // and already converts to externally visible package name
7778                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7779                                callingUid, effectiveFlags, userId);
7780                    }
7781                    if (ai != null) {
7782                        list.add(ai);
7783                    }
7784                }
7785            } else {
7786                list = new ArrayList<>(mPackages.size());
7787                for (PackageParser.Package p : mPackages.values()) {
7788                    if (p.mExtras != null) {
7789                        PackageSetting ps = (PackageSetting) p.mExtras;
7790                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7791                            continue;
7792                        }
7793                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7794                            continue;
7795                        }
7796                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7797                                ps.readUserState(userId), userId);
7798                        if (ai != null) {
7799                            ai.packageName = resolveExternalPackageNameLPr(p);
7800                            list.add(ai);
7801                        }
7802                    }
7803                }
7804            }
7805
7806            return new ParceledListSlice<>(list);
7807        }
7808    }
7809
7810    @Override
7811    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7812        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7813            return null;
7814        }
7815        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7816            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7817                    "getEphemeralApplications");
7818        }
7819        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7820                true /* requireFullPermission */, false /* checkShell */,
7821                "getEphemeralApplications");
7822        synchronized (mPackages) {
7823            List<InstantAppInfo> instantApps = mInstantAppRegistry
7824                    .getInstantAppsLPr(userId);
7825            if (instantApps != null) {
7826                return new ParceledListSlice<>(instantApps);
7827            }
7828        }
7829        return null;
7830    }
7831
7832    @Override
7833    public boolean isInstantApp(String packageName, int userId) {
7834        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7835                true /* requireFullPermission */, false /* checkShell */,
7836                "isInstantApp");
7837        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7838            return false;
7839        }
7840
7841        synchronized (mPackages) {
7842            int callingUid = Binder.getCallingUid();
7843            if (Process.isIsolated(callingUid)) {
7844                callingUid = mIsolatedOwners.get(callingUid);
7845            }
7846            final PackageSetting ps = mSettings.mPackages.get(packageName);
7847            PackageParser.Package pkg = mPackages.get(packageName);
7848            final boolean returnAllowed =
7849                    ps != null
7850                    && (isCallerSameApp(packageName, callingUid)
7851                            || canViewInstantApps(callingUid, userId)
7852                            || mInstantAppRegistry.isInstantAccessGranted(
7853                                    userId, UserHandle.getAppId(callingUid), ps.appId));
7854            if (returnAllowed) {
7855                return ps.getInstantApp(userId);
7856            }
7857        }
7858        return false;
7859    }
7860
7861    @Override
7862    public byte[] getInstantAppCookie(String packageName, int userId) {
7863        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7864            return null;
7865        }
7866
7867        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7868                true /* requireFullPermission */, false /* checkShell */,
7869                "getInstantAppCookie");
7870        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7871            return null;
7872        }
7873        synchronized (mPackages) {
7874            return mInstantAppRegistry.getInstantAppCookieLPw(
7875                    packageName, userId);
7876        }
7877    }
7878
7879    @Override
7880    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7881        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7882            return true;
7883        }
7884
7885        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7886                true /* requireFullPermission */, true /* checkShell */,
7887                "setInstantAppCookie");
7888        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7889            return false;
7890        }
7891        synchronized (mPackages) {
7892            return mInstantAppRegistry.setInstantAppCookieLPw(
7893                    packageName, cookie, userId);
7894        }
7895    }
7896
7897    @Override
7898    public Bitmap getInstantAppIcon(String packageName, int userId) {
7899        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7900            return null;
7901        }
7902
7903        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7904            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7905                    "getInstantAppIcon");
7906        }
7907        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7908                true /* requireFullPermission */, false /* checkShell */,
7909                "getInstantAppIcon");
7910
7911        synchronized (mPackages) {
7912            return mInstantAppRegistry.getInstantAppIconLPw(
7913                    packageName, userId);
7914        }
7915    }
7916
7917    private boolean isCallerSameApp(String packageName, int uid) {
7918        PackageParser.Package pkg = mPackages.get(packageName);
7919        return pkg != null
7920                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7921    }
7922
7923    @Override
7924    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7925        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7926            return ParceledListSlice.emptyList();
7927        }
7928        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7929    }
7930
7931    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7932        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7933
7934        // reader
7935        synchronized (mPackages) {
7936            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7937            final int userId = UserHandle.getCallingUserId();
7938            while (i.hasNext()) {
7939                final PackageParser.Package p = i.next();
7940                if (p.applicationInfo == null) continue;
7941
7942                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7943                        && !p.applicationInfo.isDirectBootAware();
7944                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7945                        && p.applicationInfo.isDirectBootAware();
7946
7947                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7948                        && (!mSafeMode || isSystemApp(p))
7949                        && (matchesUnaware || matchesAware)) {
7950                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7951                    if (ps != null) {
7952                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7953                                ps.readUserState(userId), userId);
7954                        if (ai != null) {
7955                            finalList.add(ai);
7956                        }
7957                    }
7958                }
7959            }
7960        }
7961
7962        return finalList;
7963    }
7964
7965    @Override
7966    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7967        return resolveContentProviderInternal(name, flags, userId);
7968    }
7969
7970    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
7971        if (!sUserManager.exists(userId)) return null;
7972        flags = updateFlagsForComponent(flags, userId, name);
7973        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7974        // reader
7975        synchronized (mPackages) {
7976            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7977            PackageSetting ps = provider != null
7978                    ? mSettings.mPackages.get(provider.owner.packageName)
7979                    : null;
7980            if (ps != null) {
7981                final boolean isInstantApp = ps.getInstantApp(userId);
7982                // normal application; filter out instant application provider
7983                if (instantAppPkgName == null && isInstantApp) {
7984                    return null;
7985                }
7986                // instant application; filter out other instant applications
7987                if (instantAppPkgName != null
7988                        && isInstantApp
7989                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7990                    return null;
7991                }
7992                // instant application; filter out non-exposed provider
7993                if (instantAppPkgName != null
7994                        && !isInstantApp
7995                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
7996                    return null;
7997                }
7998                // provider not enabled
7999                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8000                    return null;
8001                }
8002                return PackageParser.generateProviderInfo(
8003                        provider, flags, ps.readUserState(userId), userId);
8004            }
8005            return null;
8006        }
8007    }
8008
8009    /**
8010     * @deprecated
8011     */
8012    @Deprecated
8013    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8014        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8015            return;
8016        }
8017        // reader
8018        synchronized (mPackages) {
8019            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8020                    .entrySet().iterator();
8021            final int userId = UserHandle.getCallingUserId();
8022            while (i.hasNext()) {
8023                Map.Entry<String, PackageParser.Provider> entry = i.next();
8024                PackageParser.Provider p = entry.getValue();
8025                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8026
8027                if (ps != null && p.syncable
8028                        && (!mSafeMode || (p.info.applicationInfo.flags
8029                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8030                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8031                            ps.readUserState(userId), userId);
8032                    if (info != null) {
8033                        outNames.add(entry.getKey());
8034                        outInfo.add(info);
8035                    }
8036                }
8037            }
8038        }
8039    }
8040
8041    @Override
8042    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8043            int uid, int flags, String metaDataKey) {
8044        final int callingUid = Binder.getCallingUid();
8045        final int userId = processName != null ? UserHandle.getUserId(uid)
8046                : UserHandle.getCallingUserId();
8047        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8048        flags = updateFlagsForComponent(flags, userId, processName);
8049        ArrayList<ProviderInfo> finalList = null;
8050        // reader
8051        synchronized (mPackages) {
8052            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8053            while (i.hasNext()) {
8054                final PackageParser.Provider p = i.next();
8055                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8056                if (ps != null && p.info.authority != null
8057                        && (processName == null
8058                                || (p.info.processName.equals(processName)
8059                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8060                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8061
8062                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8063                    // parameter.
8064                    if (metaDataKey != null
8065                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8066                        continue;
8067                    }
8068                    final ComponentName component =
8069                            new ComponentName(p.info.packageName, p.info.name);
8070                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8071                        continue;
8072                    }
8073                    if (finalList == null) {
8074                        finalList = new ArrayList<ProviderInfo>(3);
8075                    }
8076                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8077                            ps.readUserState(userId), userId);
8078                    if (info != null) {
8079                        finalList.add(info);
8080                    }
8081                }
8082            }
8083        }
8084
8085        if (finalList != null) {
8086            Collections.sort(finalList, mProviderInitOrderSorter);
8087            return new ParceledListSlice<ProviderInfo>(finalList);
8088        }
8089
8090        return ParceledListSlice.emptyList();
8091    }
8092
8093    @Override
8094    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8095        // reader
8096        synchronized (mPackages) {
8097            final int callingUid = Binder.getCallingUid();
8098            final int callingUserId = UserHandle.getUserId(callingUid);
8099            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8100            if (ps == null) return null;
8101            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8102                return null;
8103            }
8104            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8105            return PackageParser.generateInstrumentationInfo(i, flags);
8106        }
8107    }
8108
8109    @Override
8110    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8111            String targetPackage, int flags) {
8112        final int callingUid = Binder.getCallingUid();
8113        final int callingUserId = UserHandle.getUserId(callingUid);
8114        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8115        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8116            return ParceledListSlice.emptyList();
8117        }
8118        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8119    }
8120
8121    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8122            int flags) {
8123        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8124
8125        // reader
8126        synchronized (mPackages) {
8127            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8128            while (i.hasNext()) {
8129                final PackageParser.Instrumentation p = i.next();
8130                if (targetPackage == null
8131                        || targetPackage.equals(p.info.targetPackage)) {
8132                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8133                            flags);
8134                    if (ii != null) {
8135                        finalList.add(ii);
8136                    }
8137                }
8138            }
8139        }
8140
8141        return finalList;
8142    }
8143
8144    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8145        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8146        try {
8147            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8148        } finally {
8149            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8150        }
8151    }
8152
8153    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8154        final File[] files = scanDir.listFiles();
8155        if (ArrayUtils.isEmpty(files)) {
8156            Log.d(TAG, "No files in app dir " + scanDir);
8157            return;
8158        }
8159
8160        if (DEBUG_PACKAGE_SCANNING) {
8161            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8162                    + " flags=0x" + Integer.toHexString(parseFlags));
8163        }
8164        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8165                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8166                mParallelPackageParserCallback)) {
8167            // Submit files for parsing in parallel
8168            int fileCount = 0;
8169            for (File file : files) {
8170                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8171                        && !PackageInstallerService.isStageName(file.getName());
8172                if (!isPackage) {
8173                    // Ignore entries which are not packages
8174                    continue;
8175                }
8176                parallelPackageParser.submit(file, parseFlags);
8177                fileCount++;
8178            }
8179
8180            // Process results one by one
8181            for (; fileCount > 0; fileCount--) {
8182                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8183                Throwable throwable = parseResult.throwable;
8184                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8185
8186                if (throwable == null) {
8187                    // TODO(toddke): move lower in the scan chain
8188                    // Static shared libraries have synthetic package names
8189                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8190                        renameStaticSharedLibraryPackage(parseResult.pkg);
8191                    }
8192                    try {
8193                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8194                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8195                                    currentTime, null);
8196                        }
8197                    } catch (PackageManagerException e) {
8198                        errorCode = e.error;
8199                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8200                    }
8201                } else if (throwable instanceof PackageParser.PackageParserException) {
8202                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8203                            throwable;
8204                    errorCode = e.error;
8205                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8206                } else {
8207                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8208                            + parseResult.scanFile, throwable);
8209                }
8210
8211                // Delete invalid userdata apps
8212                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8213                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8214                    logCriticalInfo(Log.WARN,
8215                            "Deleting invalid package at " + parseResult.scanFile);
8216                    removeCodePathLI(parseResult.scanFile);
8217                }
8218            }
8219        }
8220    }
8221
8222    public static void reportSettingsProblem(int priority, String msg) {
8223        logCriticalInfo(priority, msg);
8224    }
8225
8226    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8227            final @ParseFlags int parseFlags, boolean forceCollect) throws PackageManagerException {
8228        // When upgrading from pre-N MR1, verify the package time stamp using the package
8229        // directory and not the APK file.
8230        final long lastModifiedTime = mIsPreNMR1Upgrade
8231                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8232        if (ps != null && !forceCollect
8233                && ps.codePathString.equals(pkg.codePath)
8234                && ps.timeStamp == lastModifiedTime
8235                && !isCompatSignatureUpdateNeeded(pkg)
8236                && !isRecoverSignatureUpdateNeeded(pkg)) {
8237            if (ps.signatures.mSignatures != null
8238                    && ps.signatures.mSignatures.length != 0
8239                    && ps.signatures.mSignatureSchemeVersion != SignatureSchemeVersion.UNKNOWN) {
8240                // Optimization: reuse the existing cached signing data
8241                // if the package appears to be unchanged.
8242                try {
8243                    pkg.mSigningDetails = new PackageParser.SigningDetails(ps.signatures.mSignatures,
8244                            ps.signatures.mSignatureSchemeVersion);
8245                    return;
8246                } catch (CertificateException e) {
8247                    Slog.e(TAG, "Attempt to read public keys from persisted signatures failed for "
8248                                    + ps.name, e);
8249                }
8250            }
8251
8252            Slog.w(TAG, "PackageSetting for " + ps.name
8253                    + " is missing signatures.  Collecting certs again to recover them.");
8254        } else {
8255            Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8256                    (forceCollect ? " (forced)" : ""));
8257        }
8258
8259        try {
8260            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8261            PackageParser.collectCertificates(pkg, parseFlags);
8262        } catch (PackageParserException e) {
8263            throw PackageManagerException.from(e);
8264        } finally {
8265            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8266        }
8267    }
8268
8269    /**
8270     *  Traces a package scan.
8271     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8272     */
8273    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8274            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8275        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8276        try {
8277            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8278        } finally {
8279            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8280        }
8281    }
8282
8283    /**
8284     *  Scans a package and returns the newly parsed package.
8285     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8286     */
8287    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8288            long currentTime, UserHandle user) throws PackageManagerException {
8289        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8290        PackageParser pp = new PackageParser();
8291        pp.setSeparateProcesses(mSeparateProcesses);
8292        pp.setOnlyCoreApps(mOnlyCore);
8293        pp.setDisplayMetrics(mMetrics);
8294        pp.setCallback(mPackageParserCallback);
8295
8296        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8297        final PackageParser.Package pkg;
8298        try {
8299            pkg = pp.parsePackage(scanFile, parseFlags);
8300        } catch (PackageParserException e) {
8301            throw PackageManagerException.from(e);
8302        } finally {
8303            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8304        }
8305
8306        // Static shared libraries have synthetic package names
8307        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8308            renameStaticSharedLibraryPackage(pkg);
8309        }
8310
8311        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8312    }
8313
8314    /**
8315     *  Scans a package and returns the newly parsed package.
8316     *  @throws PackageManagerException on a parse error.
8317     */
8318    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8319            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8320            @Nullable UserHandle user)
8321                    throws PackageManagerException {
8322        // If the package has children and this is the first dive in the function
8323        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8324        // packages (parent and children) would be successfully scanned before the
8325        // actual scan since scanning mutates internal state and we want to atomically
8326        // install the package and its children.
8327        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8328            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8329                scanFlags |= SCAN_CHECK_ONLY;
8330            }
8331        } else {
8332            scanFlags &= ~SCAN_CHECK_ONLY;
8333        }
8334
8335        // Scan the parent
8336        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8337                scanFlags, currentTime, user);
8338
8339        // Scan the children
8340        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8341        for (int i = 0; i < childCount; i++) {
8342            PackageParser.Package childPackage = pkg.childPackages.get(i);
8343            addForInitLI(childPackage, parseFlags, scanFlags,
8344                    currentTime, user);
8345        }
8346
8347
8348        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8349            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8350        }
8351
8352        return scannedPkg;
8353    }
8354
8355    // Temporary to catch potential issues with refactoring
8356    private static boolean REFACTOR_DEBUG = true;
8357    /**
8358     * Adds a new package to the internal data structures during platform initialization.
8359     * <p>After adding, the package is known to the system and available for querying.
8360     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8361     * etc...], additional checks are performed. Basic verification [such as ensuring
8362     * matching signatures, checking version codes, etc...] occurs if the package is
8363     * identical to a previously known package. If the package fails a signature check,
8364     * the version installed on /data will be removed. If the version of the new package
8365     * is less than or equal than the version on /data, it will be ignored.
8366     * <p>Regardless of the package location, the results are applied to the internal
8367     * structures and the package is made available to the rest of the system.
8368     * <p>NOTE: The return value should be removed. It's the passed in package object.
8369     */
8370    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8371            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8372            @Nullable UserHandle user)
8373                    throws PackageManagerException {
8374        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8375        final String renamedPkgName;
8376        final PackageSetting disabledPkgSetting;
8377        final boolean isSystemPkgUpdated;
8378        final boolean pkgAlreadyExists;
8379        PackageSetting pkgSetting;
8380
8381        // NOTE: installPackageLI() has the same code to setup the package's
8382        // application info. This probably should be done lower in the call
8383        // stack [such as scanPackageOnly()]. However, we verify the application
8384        // info prior to that [in scanPackageNew()] and thus have to setup
8385        // the application info early.
8386        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8387        pkg.setApplicationInfoCodePath(pkg.codePath);
8388        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8389        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8390        pkg.setApplicationInfoResourcePath(pkg.codePath);
8391        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8392        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8393
8394        synchronized (mPackages) {
8395            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8396            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8397if (REFACTOR_DEBUG) {
8398Slog.e("TODD",
8399        "Add pkg: " + pkg.packageName + (realPkgName==null?"":", realName: " + realPkgName));
8400}
8401            if (realPkgName != null) {
8402                ensurePackageRenamed(pkg, renamedPkgName);
8403            }
8404            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8405            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8406            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8407            pkgAlreadyExists = pkgSetting != null;
8408            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8409            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8410            isSystemPkgUpdated = disabledPkgSetting != null;
8411
8412            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8413                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8414            }
8415if (REFACTOR_DEBUG) {
8416Slog.e("TODD",
8417        "SSP? " + scanSystemPartition
8418        + ", exists? " + pkgAlreadyExists + (pkgAlreadyExists?" "+pkgSetting.toString():"")
8419        + ", upgraded? " + isSystemPkgUpdated + (isSystemPkgUpdated?" "+disabledPkgSetting.toString():""));
8420}
8421
8422            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8423                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8424                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8425                    : null;
8426            if (DEBUG_PACKAGE_SCANNING
8427                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8428                    && sharedUserSetting != null) {
8429                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8430                        + " (uid=" + sharedUserSetting.userId + "):"
8431                        + " packages=" + sharedUserSetting.packages);
8432if (REFACTOR_DEBUG) {
8433Slog.e("TODD",
8434        "Shared UserID " + pkg.mSharedUserId
8435        + " (uid=" + sharedUserSetting.userId + "):"
8436        + " packages=" + sharedUserSetting.packages);
8437}
8438            }
8439
8440            if (scanSystemPartition) {
8441                // Potentially prune child packages. If the application on the /system
8442                // partition has been updated via OTA, but, is still disabled by a
8443                // version on /data, cycle through all of its children packages and
8444                // remove children that are no longer defined.
8445                if (isSystemPkgUpdated) {
8446if (REFACTOR_DEBUG) {
8447Slog.e("TODD",
8448        "Disable child packages");
8449}
8450                    final int scannedChildCount = (pkg.childPackages != null)
8451                            ? pkg.childPackages.size() : 0;
8452                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8453                            ? disabledPkgSetting.childPackageNames.size() : 0;
8454                    for (int i = 0; i < disabledChildCount; i++) {
8455                        String disabledChildPackageName =
8456                                disabledPkgSetting.childPackageNames.get(i);
8457                        boolean disabledPackageAvailable = false;
8458                        for (int j = 0; j < scannedChildCount; j++) {
8459                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8460                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8461if (REFACTOR_DEBUG) {
8462Slog.e("TODD",
8463        "Ignore " + disabledChildPackageName);
8464}
8465                                disabledPackageAvailable = true;
8466                                break;
8467                            }
8468                        }
8469                        if (!disabledPackageAvailable) {
8470if (REFACTOR_DEBUG) {
8471Slog.e("TODD",
8472        "Disable " + disabledChildPackageName);
8473}
8474                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8475                        }
8476                    }
8477                    // we're updating the disabled package, so, scan it as the package setting
8478                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
8479                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8480                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8481                            (pkg == mPlatformPackage), user);
8482if (REFACTOR_DEBUG) {
8483Slog.e("TODD",
8484        "Scan disabled system package");
8485Slog.e("TODD",
8486        "Pre: " + request.pkgSetting.dumpState_temp());
8487}
8488final ScanResult result =
8489                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8490if (REFACTOR_DEBUG) {
8491Slog.e("TODD",
8492        "Post: " + (result.success?result.pkgSetting.dumpState_temp():"FAILED scan"));
8493}
8494                }
8495            }
8496        }
8497
8498        final boolean newPkgChangedPaths =
8499                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8500if (REFACTOR_DEBUG) {
8501Slog.e("TODD",
8502        "paths changed? " + newPkgChangedPaths
8503        + "; old: " + pkg.codePath
8504        + ", new: " + (pkgSetting==null?"<<NULL>>":pkgSetting.codePathString));
8505}
8506        final boolean newPkgVersionGreater =
8507                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8508if (REFACTOR_DEBUG) {
8509Slog.e("TODD",
8510        "version greater? " + newPkgVersionGreater
8511        + "; old: " + pkg.getLongVersionCode()
8512        + ", new: " + (pkgSetting==null?"<<NULL>>":pkgSetting.versionCode));
8513}
8514        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8515                && newPkgChangedPaths && newPkgVersionGreater;
8516if (REFACTOR_DEBUG) {
8517    Slog.e("TODD",
8518            "system better? " + isSystemPkgBetter);
8519}
8520        if (isSystemPkgBetter) {
8521            // The version of the application on /system is greater than the version on
8522            // /data. Switch back to the application on /system.
8523            // It's safe to assume the application on /system will correctly scan. If not,
8524            // there won't be a working copy of the application.
8525            synchronized (mPackages) {
8526                // just remove the loaded entries from package lists
8527                mPackages.remove(pkgSetting.name);
8528            }
8529
8530            logCriticalInfo(Log.WARN,
8531                    "System package updated;"
8532                    + " name: " + pkgSetting.name
8533                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8534                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8535if (REFACTOR_DEBUG) {
8536Slog.e("TODD",
8537        "System package changed;"
8538        + " name: " + pkgSetting.name
8539        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8540        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8541}
8542
8543            final InstallArgs args = createInstallArgsForExisting(
8544                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8545                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8546            args.cleanUpResourcesLI();
8547            synchronized (mPackages) {
8548                mSettings.enableSystemPackageLPw(pkgSetting.name);
8549            }
8550        }
8551
8552        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8553if (REFACTOR_DEBUG) {
8554Slog.e("TODD",
8555        "THROW exception; system pkg version not good enough");
8556}
8557            // The version of the application on the /system partition is less than or
8558            // equal to the version on the /data partition. Throw an exception and use
8559            // the application already installed on the /data partition.
8560            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8561                    + pkg.codePath + " ignored: updated version " + disabledPkgSetting.versionCode
8562                    + " better than this " + pkg.getLongVersionCode());
8563        }
8564
8565        // Verify certificates against what was last scanned. If it is an updated priv app, we will
8566        // force the verification. Full apk verification will happen unless apk verity is set up for
8567        // the file. In that case, only small part of the apk is verified upfront.
8568        collectCertificatesLI(pkgSetting, pkg, parseFlags,
8569                PackageManagerServiceUtils.isApkVerificationForced(disabledPkgSetting));
8570
8571        boolean shouldHideSystemApp = false;
8572        // A new application appeared on /system, but, we already have a copy of
8573        // the application installed on /data.
8574        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8575                && !pkgSetting.isSystem()) {
8576            // if the signatures don't match, wipe the installed application and its data
8577            if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSigningDetails.signatures)
8578                    != PackageManager.SIGNATURE_MATCH) {
8579                logCriticalInfo(Log.WARN,
8580                        "System package signature mismatch;"
8581                        + " name: " + pkgSetting.name);
8582if (REFACTOR_DEBUG) {
8583Slog.e("TODD",
8584        "System package signature mismatch;"
8585        + " name: " + pkgSetting.name);
8586}
8587                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8588                        "scanPackageInternalLI")) {
8589                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8590                }
8591                pkgSetting = null;
8592            } else if (newPkgVersionGreater) {
8593                // The application on /system is newer than the application on /data.
8594                // Simply remove the application on /data [keeping application data]
8595                // and replace it with the version on /system.
8596                logCriticalInfo(Log.WARN,
8597                        "System package enabled;"
8598                        + " name: " + pkgSetting.name
8599                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8600                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8601if (REFACTOR_DEBUG) {
8602Slog.e("TODD",
8603        "System package enabled;"
8604        + " name: " + pkgSetting.name
8605        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8606        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8607}
8608                InstallArgs args = createInstallArgsForExisting(
8609                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8610                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8611                synchronized (mInstallLock) {
8612                    args.cleanUpResourcesLI();
8613                }
8614            } else {
8615                // The application on /system is older than the application on /data. Hide
8616                // the application on /system and the version on /data will be scanned later
8617                // and re-added like an update.
8618                shouldHideSystemApp = true;
8619                logCriticalInfo(Log.INFO,
8620                        "System package disabled;"
8621                        + " name: " + pkgSetting.name
8622                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8623                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8624if (REFACTOR_DEBUG) {
8625Slog.e("TODD",
8626        "System package disabled;"
8627        + " name: " + pkgSetting.name
8628        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8629        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8630}
8631            }
8632        }
8633
8634if (REFACTOR_DEBUG) {
8635Slog.e("TODD",
8636        "Scan package");
8637Slog.e("TODD",
8638        "Pre: " + (pkgSetting==null?"<<NONE>>":pkgSetting.dumpState_temp()));
8639}
8640        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8641                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8642if (REFACTOR_DEBUG) {
8643pkgSetting = mSettings.getPackageLPr(pkg.packageName);
8644Slog.e("TODD",
8645        "Post: " + (pkgSetting==null?"<<NONE>>":pkgSetting.dumpState_temp()));
8646}
8647
8648        if (shouldHideSystemApp) {
8649if (REFACTOR_DEBUG) {
8650Slog.e("TODD",
8651        "Disable package: " + pkg.packageName);
8652}
8653            synchronized (mPackages) {
8654                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8655            }
8656        }
8657        return scannedPkg;
8658    }
8659
8660    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8661        // Derive the new package synthetic package name
8662        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8663                + pkg.staticSharedLibVersion);
8664    }
8665
8666    private static String fixProcessName(String defProcessName,
8667            String processName) {
8668        if (processName == null) {
8669            return defProcessName;
8670        }
8671        return processName;
8672    }
8673
8674    /**
8675     * Enforces that only the system UID or root's UID can call a method exposed
8676     * via Binder.
8677     *
8678     * @param message used as message if SecurityException is thrown
8679     * @throws SecurityException if the caller is not system or root
8680     */
8681    private static final void enforceSystemOrRoot(String message) {
8682        final int uid = Binder.getCallingUid();
8683        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8684            throw new SecurityException(message);
8685        }
8686    }
8687
8688    @Override
8689    public void performFstrimIfNeeded() {
8690        enforceSystemOrRoot("Only the system can request fstrim");
8691
8692        // Before everything else, see whether we need to fstrim.
8693        try {
8694            IStorageManager sm = PackageHelper.getStorageManager();
8695            if (sm != null) {
8696                boolean doTrim = false;
8697                final long interval = android.provider.Settings.Global.getLong(
8698                        mContext.getContentResolver(),
8699                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8700                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8701                if (interval > 0) {
8702                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8703                    if (timeSinceLast > interval) {
8704                        doTrim = true;
8705                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8706                                + "; running immediately");
8707                    }
8708                }
8709                if (doTrim) {
8710                    final boolean dexOptDialogShown;
8711                    synchronized (mPackages) {
8712                        dexOptDialogShown = mDexOptDialogShown;
8713                    }
8714                    if (!isFirstBoot() && dexOptDialogShown) {
8715                        try {
8716                            ActivityManager.getService().showBootMessage(
8717                                    mContext.getResources().getString(
8718                                            R.string.android_upgrading_fstrim), true);
8719                        } catch (RemoteException e) {
8720                        }
8721                    }
8722                    sm.runMaintenance();
8723                }
8724            } else {
8725                Slog.e(TAG, "storageManager service unavailable!");
8726            }
8727        } catch (RemoteException e) {
8728            // Can't happen; StorageManagerService is local
8729        }
8730    }
8731
8732    @Override
8733    public void updatePackagesIfNeeded() {
8734        enforceSystemOrRoot("Only the system can request package update");
8735
8736        // We need to re-extract after an OTA.
8737        boolean causeUpgrade = isUpgrade();
8738
8739        // First boot or factory reset.
8740        // Note: we also handle devices that are upgrading to N right now as if it is their
8741        //       first boot, as they do not have profile data.
8742        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8743
8744        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8745        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8746
8747        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8748            return;
8749        }
8750
8751        List<PackageParser.Package> pkgs;
8752        synchronized (mPackages) {
8753            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8754        }
8755
8756        final long startTime = System.nanoTime();
8757        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8758                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
8759                    false /* bootComplete */);
8760
8761        final int elapsedTimeSeconds =
8762                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8763
8764        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8765        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8766        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8767        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8768        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8769    }
8770
8771    /*
8772     * Return the prebuilt profile path given a package base code path.
8773     */
8774    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8775        return pkg.baseCodePath + ".prof";
8776    }
8777
8778    /**
8779     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8780     * containing statistics about the invocation. The array consists of three elements,
8781     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8782     * and {@code numberOfPackagesFailed}.
8783     */
8784    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8785            final String compilerFilter, boolean bootComplete) {
8786
8787        int numberOfPackagesVisited = 0;
8788        int numberOfPackagesOptimized = 0;
8789        int numberOfPackagesSkipped = 0;
8790        int numberOfPackagesFailed = 0;
8791        final int numberOfPackagesToDexopt = pkgs.size();
8792
8793        for (PackageParser.Package pkg : pkgs) {
8794            numberOfPackagesVisited++;
8795
8796            boolean useProfileForDexopt = false;
8797
8798            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8799                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8800                // that are already compiled.
8801                File profileFile = new File(getPrebuildProfilePath(pkg));
8802                // Copy profile if it exists.
8803                if (profileFile.exists()) {
8804                    try {
8805                        // We could also do this lazily before calling dexopt in
8806                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8807                        // is that we don't have a good way to say "do this only once".
8808                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8809                                pkg.applicationInfo.uid, pkg.packageName)) {
8810                            Log.e(TAG, "Installer failed to copy system profile!");
8811                        } else {
8812                            // Disabled as this causes speed-profile compilation during first boot
8813                            // even if things are already compiled.
8814                            // useProfileForDexopt = true;
8815                        }
8816                    } catch (Exception e) {
8817                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8818                                e);
8819                    }
8820                } else {
8821                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8822                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8823                    // minimize the number off apps being speed-profile compiled during first boot.
8824                    // The other paths will not change the filter.
8825                    if (disabledPs != null && disabledPs.pkg.isStub) {
8826                        // The package is the stub one, remove the stub suffix to get the normal
8827                        // package and APK names.
8828                        String systemProfilePath =
8829                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8830                        profileFile = new File(systemProfilePath);
8831                        // If we have a profile for a compressed APK, copy it to the reference
8832                        // location.
8833                        // Note that copying the profile here will cause it to override the
8834                        // reference profile every OTA even though the existing reference profile
8835                        // may have more data. We can't copy during decompression since the
8836                        // directories are not set up at that point.
8837                        if (profileFile.exists()) {
8838                            try {
8839                                // We could also do this lazily before calling dexopt in
8840                                // PackageDexOptimizer to prevent this happening on first boot. The
8841                                // issue is that we don't have a good way to say "do this only
8842                                // once".
8843                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8844                                        pkg.applicationInfo.uid, pkg.packageName)) {
8845                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8846                                } else {
8847                                    useProfileForDexopt = true;
8848                                }
8849                            } catch (Exception e) {
8850                                Log.e(TAG, "Failed to copy profile " +
8851                                        profileFile.getAbsolutePath() + " ", e);
8852                            }
8853                        }
8854                    }
8855                }
8856            }
8857
8858            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8859                if (DEBUG_DEXOPT) {
8860                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8861                }
8862                numberOfPackagesSkipped++;
8863                continue;
8864            }
8865
8866            if (DEBUG_DEXOPT) {
8867                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8868                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8869            }
8870
8871            if (showDialog) {
8872                try {
8873                    ActivityManager.getService().showBootMessage(
8874                            mContext.getResources().getString(R.string.android_upgrading_apk,
8875                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8876                } catch (RemoteException e) {
8877                }
8878                synchronized (mPackages) {
8879                    mDexOptDialogShown = true;
8880                }
8881            }
8882
8883            String pkgCompilerFilter = compilerFilter;
8884            if (useProfileForDexopt) {
8885                // Use background dexopt mode to try and use the profile. Note that this does not
8886                // guarantee usage of the profile.
8887                pkgCompilerFilter =
8888                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
8889                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
8890            }
8891
8892            // checkProfiles is false to avoid merging profiles during boot which
8893            // might interfere with background compilation (b/28612421).
8894            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8895            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8896            // trade-off worth doing to save boot time work.
8897            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
8898            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
8899                    pkg.packageName,
8900                    pkgCompilerFilter,
8901                    dexoptFlags));
8902
8903            switch (primaryDexOptStaus) {
8904                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8905                    numberOfPackagesOptimized++;
8906                    break;
8907                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8908                    numberOfPackagesSkipped++;
8909                    break;
8910                case PackageDexOptimizer.DEX_OPT_FAILED:
8911                    numberOfPackagesFailed++;
8912                    break;
8913                default:
8914                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
8915                    break;
8916            }
8917        }
8918
8919        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8920                numberOfPackagesFailed };
8921    }
8922
8923    @Override
8924    public void notifyPackageUse(String packageName, int reason) {
8925        synchronized (mPackages) {
8926            final int callingUid = Binder.getCallingUid();
8927            final int callingUserId = UserHandle.getUserId(callingUid);
8928            if (getInstantAppPackageName(callingUid) != null) {
8929                if (!isCallerSameApp(packageName, callingUid)) {
8930                    return;
8931                }
8932            } else {
8933                if (isInstantApp(packageName, callingUserId)) {
8934                    return;
8935                }
8936            }
8937            notifyPackageUseLocked(packageName, reason);
8938        }
8939    }
8940
8941    private void notifyPackageUseLocked(String packageName, int reason) {
8942        final PackageParser.Package p = mPackages.get(packageName);
8943        if (p == null) {
8944            return;
8945        }
8946        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8947    }
8948
8949    @Override
8950    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
8951            List<String> classPaths, String loaderIsa) {
8952        int userId = UserHandle.getCallingUserId();
8953        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8954        if (ai == null) {
8955            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8956                + loadingPackageName + ", user=" + userId);
8957            return;
8958        }
8959        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
8960    }
8961
8962    @Override
8963    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
8964            IDexModuleRegisterCallback callback) {
8965        int userId = UserHandle.getCallingUserId();
8966        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
8967        DexManager.RegisterDexModuleResult result;
8968        if (ai == null) {
8969            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
8970                     " calling user. package=" + packageName + ", user=" + userId);
8971            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
8972        } else {
8973            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
8974        }
8975
8976        if (callback != null) {
8977            mHandler.post(() -> {
8978                try {
8979                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
8980                } catch (RemoteException e) {
8981                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
8982                }
8983            });
8984        }
8985    }
8986
8987    /**
8988     * Ask the package manager to perform a dex-opt with the given compiler filter.
8989     *
8990     * Note: exposed only for the shell command to allow moving packages explicitly to a
8991     *       definite state.
8992     */
8993    @Override
8994    public boolean performDexOptMode(String packageName,
8995            boolean checkProfiles, String targetCompilerFilter, boolean force,
8996            boolean bootComplete, String splitName) {
8997        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
8998                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
8999                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9000        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
9001                splitName, flags));
9002    }
9003
9004    /**
9005     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9006     * secondary dex files belonging to the given package.
9007     *
9008     * Note: exposed only for the shell command to allow moving packages explicitly to a
9009     *       definite state.
9010     */
9011    @Override
9012    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9013            boolean force) {
9014        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9015                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9016                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9017                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9018        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9019    }
9020
9021    /*package*/ boolean performDexOpt(DexoptOptions options) {
9022        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9023            return false;
9024        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9025            return false;
9026        }
9027
9028        if (options.isDexoptOnlySecondaryDex()) {
9029            return mDexManager.dexoptSecondaryDex(options);
9030        } else {
9031            int dexoptStatus = performDexOptWithStatus(options);
9032            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9033        }
9034    }
9035
9036    /**
9037     * Perform dexopt on the given package and return one of following result:
9038     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9039     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9040     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9041     */
9042    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9043        return performDexOptTraced(options);
9044    }
9045
9046    private int performDexOptTraced(DexoptOptions options) {
9047        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9048        try {
9049            return performDexOptInternal(options);
9050        } finally {
9051            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9052        }
9053    }
9054
9055    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9056    // if the package can now be considered up to date for the given filter.
9057    private int performDexOptInternal(DexoptOptions options) {
9058        PackageParser.Package p;
9059        synchronized (mPackages) {
9060            p = mPackages.get(options.getPackageName());
9061            if (p == null) {
9062                // Package could not be found. Report failure.
9063                return PackageDexOptimizer.DEX_OPT_FAILED;
9064            }
9065            mPackageUsage.maybeWriteAsync(mPackages);
9066            mCompilerStats.maybeWriteAsync();
9067        }
9068        long callingId = Binder.clearCallingIdentity();
9069        try {
9070            synchronized (mInstallLock) {
9071                return performDexOptInternalWithDependenciesLI(p, options);
9072            }
9073        } finally {
9074            Binder.restoreCallingIdentity(callingId);
9075        }
9076    }
9077
9078    public ArraySet<String> getOptimizablePackages() {
9079        ArraySet<String> pkgs = new ArraySet<String>();
9080        synchronized (mPackages) {
9081            for (PackageParser.Package p : mPackages.values()) {
9082                if (PackageDexOptimizer.canOptimizePackage(p)) {
9083                    pkgs.add(p.packageName);
9084                }
9085            }
9086        }
9087        return pkgs;
9088    }
9089
9090    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9091            DexoptOptions options) {
9092        // Select the dex optimizer based on the force parameter.
9093        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9094        //       allocate an object here.
9095        PackageDexOptimizer pdo = options.isForce()
9096                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9097                : mPackageDexOptimizer;
9098
9099        // Dexopt all dependencies first. Note: we ignore the return value and march on
9100        // on errors.
9101        // Note that we are going to call performDexOpt on those libraries as many times as
9102        // they are referenced in packages. When we do a batch of performDexOpt (for example
9103        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9104        // and the first package that uses the library will dexopt it. The
9105        // others will see that the compiled code for the library is up to date.
9106        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9107        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9108        if (!deps.isEmpty()) {
9109            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9110                    options.getCompilerFilter(), options.getSplitName(),
9111                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9112            for (PackageParser.Package depPackage : deps) {
9113                // TODO: Analyze and investigate if we (should) profile libraries.
9114                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9115                        getOrCreateCompilerPackageStats(depPackage),
9116                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9117            }
9118        }
9119        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9120                getOrCreateCompilerPackageStats(p),
9121                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9122    }
9123
9124    /**
9125     * Reconcile the information we have about the secondary dex files belonging to
9126     * {@code packagName} and the actual dex files. For all dex files that were
9127     * deleted, update the internal records and delete the generated oat files.
9128     */
9129    @Override
9130    public void reconcileSecondaryDexFiles(String packageName) {
9131        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9132            return;
9133        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9134            return;
9135        }
9136        mDexManager.reconcileSecondaryDexFiles(packageName);
9137    }
9138
9139    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9140    // a reference there.
9141    /*package*/ DexManager getDexManager() {
9142        return mDexManager;
9143    }
9144
9145    /**
9146     * Execute the background dexopt job immediately.
9147     */
9148    @Override
9149    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9150        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9151            return false;
9152        }
9153        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9154    }
9155
9156    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9157        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9158                || p.usesStaticLibraries != null) {
9159            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9160            Set<String> collectedNames = new HashSet<>();
9161            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9162
9163            retValue.remove(p);
9164
9165            return retValue;
9166        } else {
9167            return Collections.emptyList();
9168        }
9169    }
9170
9171    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9172            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9173        if (!collectedNames.contains(p.packageName)) {
9174            collectedNames.add(p.packageName);
9175            collected.add(p);
9176
9177            if (p.usesLibraries != null) {
9178                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9179                        null, collected, collectedNames);
9180            }
9181            if (p.usesOptionalLibraries != null) {
9182                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9183                        null, collected, collectedNames);
9184            }
9185            if (p.usesStaticLibraries != null) {
9186                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9187                        p.usesStaticLibrariesVersions, collected, collectedNames);
9188            }
9189        }
9190    }
9191
9192    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9193            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9194        final int libNameCount = libs.size();
9195        for (int i = 0; i < libNameCount; i++) {
9196            String libName = libs.get(i);
9197            long version = (versions != null && versions.length == libNameCount)
9198                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9199            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9200            if (libPkg != null) {
9201                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9202            }
9203        }
9204    }
9205
9206    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9207        synchronized (mPackages) {
9208            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9209            if (libEntry != null) {
9210                return mPackages.get(libEntry.apk);
9211            }
9212            return null;
9213        }
9214    }
9215
9216    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9217        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9218        if (versionedLib == null) {
9219            return null;
9220        }
9221        return versionedLib.get(version);
9222    }
9223
9224    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9225        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9226                pkg.staticSharedLibName);
9227        if (versionedLib == null) {
9228            return null;
9229        }
9230        long previousLibVersion = -1;
9231        final int versionCount = versionedLib.size();
9232        for (int i = 0; i < versionCount; i++) {
9233            final long libVersion = versionedLib.keyAt(i);
9234            if (libVersion < pkg.staticSharedLibVersion) {
9235                previousLibVersion = Math.max(previousLibVersion, libVersion);
9236            }
9237        }
9238        if (previousLibVersion >= 0) {
9239            return versionedLib.get(previousLibVersion);
9240        }
9241        return null;
9242    }
9243
9244    public void shutdown() {
9245        mPackageUsage.writeNow(mPackages);
9246        mCompilerStats.writeNow();
9247        mDexManager.writePackageDexUsageNow();
9248    }
9249
9250    @Override
9251    public void dumpProfiles(String packageName) {
9252        PackageParser.Package pkg;
9253        synchronized (mPackages) {
9254            pkg = mPackages.get(packageName);
9255            if (pkg == null) {
9256                throw new IllegalArgumentException("Unknown package: " + packageName);
9257            }
9258        }
9259        /* Only the shell, root, or the app user should be able to dump profiles. */
9260        int callingUid = Binder.getCallingUid();
9261        if (callingUid != Process.SHELL_UID &&
9262            callingUid != Process.ROOT_UID &&
9263            callingUid != pkg.applicationInfo.uid) {
9264            throw new SecurityException("dumpProfiles");
9265        }
9266
9267        synchronized (mInstallLock) {
9268            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9269            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9270            try {
9271                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9272                String codePaths = TextUtils.join(";", allCodePaths);
9273                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9274            } catch (InstallerException e) {
9275                Slog.w(TAG, "Failed to dump profiles", e);
9276            }
9277            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9278        }
9279    }
9280
9281    @Override
9282    public void forceDexOpt(String packageName) {
9283        enforceSystemOrRoot("forceDexOpt");
9284
9285        PackageParser.Package pkg;
9286        synchronized (mPackages) {
9287            pkg = mPackages.get(packageName);
9288            if (pkg == null) {
9289                throw new IllegalArgumentException("Unknown package: " + packageName);
9290            }
9291        }
9292
9293        synchronized (mInstallLock) {
9294            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9295
9296            // Whoever is calling forceDexOpt wants a compiled package.
9297            // Don't use profiles since that may cause compilation to be skipped.
9298            final int res = performDexOptInternalWithDependenciesLI(
9299                    pkg,
9300                    new DexoptOptions(packageName,
9301                            getDefaultCompilerFilter(),
9302                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9303
9304            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9305            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9306                throw new IllegalStateException("Failed to dexopt: " + res);
9307            }
9308        }
9309    }
9310
9311    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9312        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9313            Slog.w(TAG, "Unable to update from " + oldPkg.name
9314                    + " to " + newPkg.packageName
9315                    + ": old package not in system partition");
9316            return false;
9317        } else if (mPackages.get(oldPkg.name) != null) {
9318            Slog.w(TAG, "Unable to update from " + oldPkg.name
9319                    + " to " + newPkg.packageName
9320                    + ": old package still exists");
9321            return false;
9322        }
9323        return true;
9324    }
9325
9326    void removeCodePathLI(File codePath) {
9327        if (codePath.isDirectory()) {
9328            try {
9329                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9330            } catch (InstallerException e) {
9331                Slog.w(TAG, "Failed to remove code path", e);
9332            }
9333        } else {
9334            codePath.delete();
9335        }
9336    }
9337
9338    private int[] resolveUserIds(int userId) {
9339        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9340    }
9341
9342    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9343        if (pkg == null) {
9344            Slog.wtf(TAG, "Package was null!", new Throwable());
9345            return;
9346        }
9347        clearAppDataLeafLIF(pkg, userId, flags);
9348        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9349        for (int i = 0; i < childCount; i++) {
9350            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9351        }
9352    }
9353
9354    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9355        final PackageSetting ps;
9356        synchronized (mPackages) {
9357            ps = mSettings.mPackages.get(pkg.packageName);
9358        }
9359        for (int realUserId : resolveUserIds(userId)) {
9360            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9361            try {
9362                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9363                        ceDataInode);
9364            } catch (InstallerException e) {
9365                Slog.w(TAG, String.valueOf(e));
9366            }
9367        }
9368    }
9369
9370    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9371        if (pkg == null) {
9372            Slog.wtf(TAG, "Package was null!", new Throwable());
9373            return;
9374        }
9375        destroyAppDataLeafLIF(pkg, userId, flags);
9376        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9377        for (int i = 0; i < childCount; i++) {
9378            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9379        }
9380    }
9381
9382    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9383        final PackageSetting ps;
9384        synchronized (mPackages) {
9385            ps = mSettings.mPackages.get(pkg.packageName);
9386        }
9387        for (int realUserId : resolveUserIds(userId)) {
9388            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9389            try {
9390                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9391                        ceDataInode);
9392            } catch (InstallerException e) {
9393                Slog.w(TAG, String.valueOf(e));
9394            }
9395            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9396        }
9397    }
9398
9399    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9400        if (pkg == null) {
9401            Slog.wtf(TAG, "Package was null!", new Throwable());
9402            return;
9403        }
9404        destroyAppProfilesLeafLIF(pkg);
9405        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9406        for (int i = 0; i < childCount; i++) {
9407            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9408        }
9409    }
9410
9411    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9412        try {
9413            mInstaller.destroyAppProfiles(pkg.packageName);
9414        } catch (InstallerException e) {
9415            Slog.w(TAG, String.valueOf(e));
9416        }
9417    }
9418
9419    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9420        if (pkg == null) {
9421            Slog.wtf(TAG, "Package was null!", new Throwable());
9422            return;
9423        }
9424        clearAppProfilesLeafLIF(pkg);
9425        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9426        for (int i = 0; i < childCount; i++) {
9427            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9428        }
9429    }
9430
9431    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9432        try {
9433            mInstaller.clearAppProfiles(pkg.packageName);
9434        } catch (InstallerException e) {
9435            Slog.w(TAG, String.valueOf(e));
9436        }
9437    }
9438
9439    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9440            long lastUpdateTime) {
9441        // Set parent install/update time
9442        PackageSetting ps = (PackageSetting) pkg.mExtras;
9443        if (ps != null) {
9444            ps.firstInstallTime = firstInstallTime;
9445            ps.lastUpdateTime = lastUpdateTime;
9446        }
9447        // Set children install/update time
9448        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9449        for (int i = 0; i < childCount; i++) {
9450            PackageParser.Package childPkg = pkg.childPackages.get(i);
9451            ps = (PackageSetting) childPkg.mExtras;
9452            if (ps != null) {
9453                ps.firstInstallTime = firstInstallTime;
9454                ps.lastUpdateTime = lastUpdateTime;
9455            }
9456        }
9457    }
9458
9459    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9460            SharedLibraryEntry file,
9461            PackageParser.Package changingLib) {
9462        if (file.path != null) {
9463            usesLibraryFiles.add(file.path);
9464            return;
9465        }
9466        PackageParser.Package p = mPackages.get(file.apk);
9467        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9468            // If we are doing this while in the middle of updating a library apk,
9469            // then we need to make sure to use that new apk for determining the
9470            // dependencies here.  (We haven't yet finished committing the new apk
9471            // to the package manager state.)
9472            if (p == null || p.packageName.equals(changingLib.packageName)) {
9473                p = changingLib;
9474            }
9475        }
9476        if (p != null) {
9477            usesLibraryFiles.addAll(p.getAllCodePaths());
9478            if (p.usesLibraryFiles != null) {
9479                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9480            }
9481        }
9482    }
9483
9484    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9485            PackageParser.Package changingLib) throws PackageManagerException {
9486        if (pkg == null) {
9487            return;
9488        }
9489        // The collection used here must maintain the order of addition (so
9490        // that libraries are searched in the correct order) and must have no
9491        // duplicates.
9492        Set<String> usesLibraryFiles = null;
9493        if (pkg.usesLibraries != null) {
9494            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9495                    null, null, pkg.packageName, changingLib, true,
9496                    pkg.applicationInfo.targetSdkVersion, null);
9497        }
9498        if (pkg.usesStaticLibraries != null) {
9499            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9500                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9501                    pkg.packageName, changingLib, true,
9502                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9503        }
9504        if (pkg.usesOptionalLibraries != null) {
9505            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9506                    null, null, pkg.packageName, changingLib, false,
9507                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9508        }
9509        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9510            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9511        } else {
9512            pkg.usesLibraryFiles = null;
9513        }
9514    }
9515
9516    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9517            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9518            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9519            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9520            throws PackageManagerException {
9521        final int libCount = requestedLibraries.size();
9522        for (int i = 0; i < libCount; i++) {
9523            final String libName = requestedLibraries.get(i);
9524            final long libVersion = requiredVersions != null ? requiredVersions[i]
9525                    : SharedLibraryInfo.VERSION_UNDEFINED;
9526            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9527            if (libEntry == null) {
9528                if (required) {
9529                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9530                            "Package " + packageName + " requires unavailable shared library "
9531                                    + libName + "; failing!");
9532                } else if (DEBUG_SHARED_LIBRARIES) {
9533                    Slog.i(TAG, "Package " + packageName
9534                            + " desires unavailable shared library "
9535                            + libName + "; ignoring!");
9536                }
9537            } else {
9538                if (requiredVersions != null && requiredCertDigests != null) {
9539                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9540                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9541                            "Package " + packageName + " requires unavailable static shared"
9542                                    + " library " + libName + " version "
9543                                    + libEntry.info.getLongVersion() + "; failing!");
9544                    }
9545
9546                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9547                    if (libPkg == null) {
9548                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9549                                "Package " + packageName + " requires unavailable static shared"
9550                                        + " library; failing!");
9551                    }
9552
9553                    final String[] expectedCertDigests = requiredCertDigests[i];
9554                    // For apps targeting O MR1 we require explicit enumeration of all certs.
9555                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9556                            ? PackageUtils.computeSignaturesSha256Digests(
9557                            libPkg.mSigningDetails.signatures)
9558                            : PackageUtils.computeSignaturesSha256Digests(
9559                                    new Signature[]{libPkg.mSigningDetails.signatures[0]});
9560
9561                    // Take a shortcut if sizes don't match. Note that if an app doesn't
9562                    // target O we don't parse the "additional-certificate" tags similarly
9563                    // how we only consider all certs only for apps targeting O (see above).
9564                    // Therefore, the size check is safe to make.
9565                    if (expectedCertDigests.length != libCertDigests.length) {
9566                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9567                                "Package " + packageName + " requires differently signed" +
9568                                        " static shared library; failing!");
9569                    }
9570
9571                    // Use a predictable order as signature order may vary
9572                    Arrays.sort(libCertDigests);
9573                    Arrays.sort(expectedCertDigests);
9574
9575                    final int certCount = libCertDigests.length;
9576                    for (int j = 0; j < certCount; j++) {
9577                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9578                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9579                                    "Package " + packageName + " requires differently signed" +
9580                                            " static shared library; failing!");
9581                        }
9582                    }
9583                }
9584
9585                if (outUsedLibraries == null) {
9586                    // Use LinkedHashSet to preserve the order of files added to
9587                    // usesLibraryFiles while eliminating duplicates.
9588                    outUsedLibraries = new LinkedHashSet<>();
9589                }
9590                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9591            }
9592        }
9593        return outUsedLibraries;
9594    }
9595
9596    private static boolean hasString(List<String> list, List<String> which) {
9597        if (list == null) {
9598            return false;
9599        }
9600        for (int i=list.size()-1; i>=0; i--) {
9601            for (int j=which.size()-1; j>=0; j--) {
9602                if (which.get(j).equals(list.get(i))) {
9603                    return true;
9604                }
9605            }
9606        }
9607        return false;
9608    }
9609
9610    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9611            PackageParser.Package changingPkg) {
9612        ArrayList<PackageParser.Package> res = null;
9613        for (PackageParser.Package pkg : mPackages.values()) {
9614            if (changingPkg != null
9615                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9616                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9617                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9618                            changingPkg.staticSharedLibName)) {
9619                return null;
9620            }
9621            if (res == null) {
9622                res = new ArrayList<>();
9623            }
9624            res.add(pkg);
9625            try {
9626                updateSharedLibrariesLPr(pkg, changingPkg);
9627            } catch (PackageManagerException e) {
9628                // If a system app update or an app and a required lib missing we
9629                // delete the package and for updated system apps keep the data as
9630                // it is better for the user to reinstall than to be in an limbo
9631                // state. Also libs disappearing under an app should never happen
9632                // - just in case.
9633                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9634                    final int flags = pkg.isUpdatedSystemApp()
9635                            ? PackageManager.DELETE_KEEP_DATA : 0;
9636                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9637                            flags , null, true, null);
9638                }
9639                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9640            }
9641        }
9642        return res;
9643    }
9644
9645    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9646            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9647            @Nullable UserHandle user) throws PackageManagerException {
9648        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9649        // If the package has children and this is the first dive in the function
9650        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9651        // whether all packages (parent and children) would be successfully scanned
9652        // before the actual scan since scanning mutates internal state and we want
9653        // to atomically install the package and its children.
9654        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9655            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9656                scanFlags |= SCAN_CHECK_ONLY;
9657            }
9658        } else {
9659            scanFlags &= ~SCAN_CHECK_ONLY;
9660        }
9661
9662        final PackageParser.Package scannedPkg;
9663        try {
9664            // Scan the parent
9665            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9666            // Scan the children
9667            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9668            for (int i = 0; i < childCount; i++) {
9669                PackageParser.Package childPkg = pkg.childPackages.get(i);
9670                scanPackageNewLI(childPkg, parseFlags,
9671                        scanFlags, currentTime, user);
9672            }
9673        } finally {
9674            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9675        }
9676
9677        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9678            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9679        }
9680
9681        return scannedPkg;
9682    }
9683
9684    /** The result of a package scan. */
9685    private static class ScanResult {
9686        /** Whether or not the package scan was successful */
9687        public final boolean success;
9688        /**
9689         * The final package settings. This may be the same object passed in
9690         * the {@link ScanRequest}, but, with modified values.
9691         */
9692        @Nullable public final PackageSetting pkgSetting;
9693        /** ABI code paths that have changed in the package scan */
9694        @Nullable public final List<String> changedAbiCodePath;
9695        public ScanResult(
9696                boolean success,
9697                @Nullable PackageSetting pkgSetting,
9698                @Nullable List<String> changedAbiCodePath) {
9699            this.success = success;
9700            this.pkgSetting = pkgSetting;
9701            this.changedAbiCodePath = changedAbiCodePath;
9702        }
9703    }
9704
9705    /** A package to be scanned */
9706    private static class ScanRequest {
9707        /** The parsed package */
9708        @NonNull public final PackageParser.Package pkg;
9709        /** Shared user settings, if the package has a shared user */
9710        @Nullable public final SharedUserSetting sharedUserSetting;
9711        /**
9712         * Package settings of the currently installed version.
9713         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9714         * during scan.
9715         */
9716        @Nullable public final PackageSetting pkgSetting;
9717        /** A copy of the settings for the currently installed version */
9718        @Nullable public final PackageSetting oldPkgSetting;
9719        /** Package settings for the disabled version on the /system partition */
9720        @Nullable public final PackageSetting disabledPkgSetting;
9721        /** Package settings for the installed version under its original package name */
9722        @Nullable public final PackageSetting originalPkgSetting;
9723        /** The real package name of a renamed application */
9724        @Nullable public final String realPkgName;
9725        public final @ParseFlags int parseFlags;
9726        public final @ScanFlags int scanFlags;
9727        /** The user for which the package is being scanned */
9728        @Nullable public final UserHandle user;
9729        /** Whether or not the platform package is being scanned */
9730        public final boolean isPlatformPackage;
9731        public ScanRequest(
9732                @NonNull PackageParser.Package pkg,
9733                @Nullable SharedUserSetting sharedUserSetting,
9734                @Nullable PackageSetting pkgSetting,
9735                @Nullable PackageSetting disabledPkgSetting,
9736                @Nullable PackageSetting originalPkgSetting,
9737                @Nullable String realPkgName,
9738                @ParseFlags int parseFlags,
9739                @ScanFlags int scanFlags,
9740                boolean isPlatformPackage,
9741                @Nullable UserHandle user) {
9742            this.pkg = pkg;
9743            this.pkgSetting = pkgSetting;
9744            this.sharedUserSetting = sharedUserSetting;
9745            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9746            this.disabledPkgSetting = disabledPkgSetting;
9747            this.originalPkgSetting = originalPkgSetting;
9748            this.realPkgName = realPkgName;
9749            this.parseFlags = parseFlags;
9750            this.scanFlags = scanFlags;
9751            this.isPlatformPackage = isPlatformPackage;
9752            this.user = user;
9753        }
9754    }
9755
9756    /**
9757     * Returns the actual scan flags depending upon the state of the other settings.
9758     * <p>Updated system applications will not have the following flags set
9759     * by default and need to be adjusted after the fact:
9760     * <ul>
9761     * <li>{@link #SCAN_AS_SYSTEM}</li>
9762     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
9763     * <li>{@link #SCAN_AS_OEM}</li>
9764     * <li>{@link #SCAN_AS_VENDOR}</li>
9765     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
9766     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
9767     * </ul>
9768     */
9769    private static @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
9770            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user) {
9771        if (disabledPkgSetting != null) {
9772            // updated system application, must at least have SCAN_AS_SYSTEM
9773            scanFlags |= SCAN_AS_SYSTEM;
9774            if ((disabledPkgSetting.pkgPrivateFlags
9775                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9776                scanFlags |= SCAN_AS_PRIVILEGED;
9777            }
9778            if ((disabledPkgSetting.pkgPrivateFlags
9779                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9780                scanFlags |= SCAN_AS_OEM;
9781            }
9782            if ((disabledPkgSetting.pkgPrivateFlags
9783                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
9784                scanFlags |= SCAN_AS_VENDOR;
9785            }
9786        }
9787        if (pkgSetting != null) {
9788            final int userId = ((user == null) ? 0 : user.getIdentifier());
9789            if (pkgSetting.getInstantApp(userId)) {
9790                scanFlags |= SCAN_AS_INSTANT_APP;
9791            }
9792            if (pkgSetting.getVirtulalPreload(userId)) {
9793                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9794            }
9795        }
9796        return scanFlags;
9797    }
9798
9799    @GuardedBy("mInstallLock")
9800    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9801            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9802            @Nullable UserHandle user) throws PackageManagerException {
9803
9804        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9805        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9806        if (realPkgName != null) {
9807            ensurePackageRenamed(pkg, renamedPkgName);
9808        }
9809        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9810        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9811        final PackageSetting disabledPkgSetting =
9812                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9813
9814        if (mTransferedPackages.contains(pkg.packageName)) {
9815            Slog.w(TAG, "Package " + pkg.packageName
9816                    + " was transferred to another, but its .apk remains");
9817        }
9818
9819        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user);
9820        synchronized (mPackages) {
9821            applyPolicy(pkg, parseFlags, scanFlags);
9822            assertPackageIsValid(pkg, parseFlags, scanFlags);
9823
9824            SharedUserSetting sharedUserSetting = null;
9825            if (pkg.mSharedUserId != null) {
9826                // SIDE EFFECTS; may potentially allocate a new shared user
9827                sharedUserSetting = mSettings.getSharedUserLPw(
9828                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9829                if (DEBUG_PACKAGE_SCANNING) {
9830                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9831                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9832                                + " (uid=" + sharedUserSetting.userId + "):"
9833                                + " packages=" + sharedUserSetting.packages);
9834                }
9835            }
9836
9837            boolean scanSucceeded = false;
9838            try {
9839                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
9840                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
9841                        (pkg == mPlatformPackage), user);
9842                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
9843                if (result.success) {
9844                    commitScanResultsLocked(request, result);
9845                }
9846                scanSucceeded = true;
9847            } finally {
9848                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9849                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
9850                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9851                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9852                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9853                  }
9854            }
9855        }
9856        return pkg;
9857    }
9858
9859    /**
9860     * Commits the package scan and modifies system state.
9861     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
9862     * of committing the package, leaving the system in an inconsistent state.
9863     * This needs to be fixed so, once we get to this point, no errors are
9864     * possible and the system is not left in an inconsistent state.
9865     */
9866    @GuardedBy("mPackages")
9867    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
9868            throws PackageManagerException {
9869        final PackageParser.Package pkg = request.pkg;
9870        final @ParseFlags int parseFlags = request.parseFlags;
9871        final @ScanFlags int scanFlags = request.scanFlags;
9872        final PackageSetting oldPkgSetting = request.oldPkgSetting;
9873        final PackageSetting originalPkgSetting = request.originalPkgSetting;
9874        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
9875        final UserHandle user = request.user;
9876        final String realPkgName = request.realPkgName;
9877        final PackageSetting pkgSetting = result.pkgSetting;
9878        final List<String> changedAbiCodePath = result.changedAbiCodePath;
9879        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
9880
9881        if (newPkgSettingCreated) {
9882            if (originalPkgSetting != null) {
9883                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
9884            }
9885            // THROWS: when we can't allocate a user id. add call to check if there's
9886            // enough space to ensure we won't throw; otherwise, don't modify state
9887            mSettings.addUserToSettingLPw(pkgSetting);
9888
9889            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
9890                mTransferedPackages.add(originalPkgSetting.name);
9891            }
9892        }
9893        // TODO(toddke): Consider a method specifically for modifying the Package object
9894        // post scan; or, moving this stuff out of the Package object since it has nothing
9895        // to do with the package on disk.
9896        // We need to have this here because addUserToSettingLPw() is sometimes responsible
9897        // for creating the application ID. If we did this earlier, we would be saving the
9898        // correct ID.
9899        pkg.applicationInfo.uid = pkgSetting.appId;
9900
9901        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9902
9903        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
9904            mTransferedPackages.add(pkg.packageName);
9905        }
9906
9907        // THROWS: when requested libraries that can't be found. it only changes
9908        // the state of the passed in pkg object, so, move to the top of the method
9909        // and allow it to abort
9910        if ((scanFlags & SCAN_BOOTING) == 0
9911                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9912            // Check all shared libraries and map to their actual file path.
9913            // We only do this here for apps not on a system dir, because those
9914            // are the only ones that can fail an install due to this.  We
9915            // will take care of the system apps by updating all of their
9916            // library paths after the scan is done. Also during the initial
9917            // scan don't update any libs as we do this wholesale after all
9918            // apps are scanned to avoid dependency based scanning.
9919            updateSharedLibrariesLPr(pkg, null);
9920        }
9921
9922        // All versions of a static shared library are referenced with the same
9923        // package name. Internally, we use a synthetic package name to allow
9924        // multiple versions of the same shared library to be installed. So,
9925        // we need to generate the synthetic package name of the latest shared
9926        // library in order to compare signatures.
9927        PackageSetting signatureCheckPs = pkgSetting;
9928        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9929            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9930            if (libraryEntry != null) {
9931                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9932            }
9933        }
9934
9935        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
9936        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
9937            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
9938                // We just determined the app is signed correctly, so bring
9939                // over the latest parsed certs.
9940                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9941            } else {
9942                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9943                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9944                            "Package " + pkg.packageName + " upgrade keys do not match the "
9945                                    + "previously installed version");
9946                } else {
9947                    pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9948                    String msg = "System package " + pkg.packageName
9949                            + " signature changed; retaining data.";
9950                    reportSettingsProblem(Log.WARN, msg);
9951                }
9952            }
9953        } else {
9954            try {
9955                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
9956                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
9957                final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
9958                        pkg.mSigningDetails, compareCompat, compareRecover);
9959                // The new KeySets will be re-added later in the scanning process.
9960                if (compatMatch) {
9961                    synchronized (mPackages) {
9962                        ksms.removeAppKeySetDataLPw(pkg.packageName);
9963                    }
9964                }
9965                // We just determined the app is signed correctly, so bring
9966                // over the latest parsed certs.
9967                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9968            } catch (PackageManagerException e) {
9969                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9970                    throw e;
9971                }
9972                // The signature has changed, but this package is in the system
9973                // image...  let's recover!
9974                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9975                // However...  if this package is part of a shared user, but it
9976                // doesn't match the signature of the shared user, let's fail.
9977                // What this means is that you can't change the signatures
9978                // associated with an overall shared user, which doesn't seem all
9979                // that unreasonable.
9980                if (signatureCheckPs.sharedUser != null) {
9981                    if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9982                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
9983                        throw new PackageManagerException(
9984                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9985                                "Signature mismatch for shared user: "
9986                                        + pkgSetting.sharedUser);
9987                    }
9988                }
9989                // File a report about this.
9990                String msg = "System package " + pkg.packageName
9991                        + " signature changed; retaining data.";
9992                reportSettingsProblem(Log.WARN, msg);
9993            }
9994        }
9995
9996        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9997            // This package wants to adopt ownership of permissions from
9998            // another package.
9999            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10000                final String origName = pkg.mAdoptPermissions.get(i);
10001                final PackageSetting orig = mSettings.getPackageLPr(origName);
10002                if (orig != null) {
10003                    if (verifyPackageUpdateLPr(orig, pkg)) {
10004                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
10005                                + pkg.packageName);
10006                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10007                    }
10008                }
10009            }
10010        }
10011
10012        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10013            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
10014                final String codePathString = changedAbiCodePath.get(i);
10015                try {
10016                    mInstaller.rmdex(codePathString,
10017                            getDexCodeInstructionSet(getPreferredInstructionSet()));
10018                } catch (InstallerException ignored) {
10019                }
10020            }
10021        }
10022
10023        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10024            if (oldPkgSetting != null) {
10025                synchronized (mPackages) {
10026                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10027                }
10028            }
10029        } else {
10030            final int userId = user == null ? 0 : user.getIdentifier();
10031            // Modify state for the given package setting
10032            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10033                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10034            if (pkgSetting.getInstantApp(userId)) {
10035                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10036            }
10037        }
10038    }
10039
10040    /**
10041     * Returns the "real" name of the package.
10042     * <p>This may differ from the package's actual name if the application has already
10043     * been installed under one of this package's original names.
10044     */
10045    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10046            @Nullable String renamedPkgName) {
10047        if (isPackageRenamed(pkg, renamedPkgName)) {
10048            return pkg.mRealPackage;
10049        }
10050        return null;
10051    }
10052
10053    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10054    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10055            @Nullable String renamedPkgName) {
10056        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10057    }
10058
10059    /**
10060     * Returns the original package setting.
10061     * <p>A package can migrate its name during an update. In this scenario, a package
10062     * designates a set of names that it considers as one of its original names.
10063     * <p>An original package must be signed identically and it must have the same
10064     * shared user [if any].
10065     */
10066    @GuardedBy("mPackages")
10067    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10068            @Nullable String renamedPkgName) {
10069        if (!isPackageRenamed(pkg, renamedPkgName)) {
10070            return null;
10071        }
10072        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10073            final PackageSetting originalPs =
10074                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10075            if (originalPs != null) {
10076                // the package is already installed under its original name...
10077                // but, should we use it?
10078                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10079                    // the new package is incompatible with the original
10080                    continue;
10081                } else if (originalPs.sharedUser != null) {
10082                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10083                        // the shared user id is incompatible with the original
10084                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10085                                + " to " + pkg.packageName + ": old uid "
10086                                + originalPs.sharedUser.name
10087                                + " differs from " + pkg.mSharedUserId);
10088                        continue;
10089                    }
10090                    // TODO: Add case when shared user id is added [b/28144775]
10091                } else {
10092                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10093                            + pkg.packageName + " to old name " + originalPs.name);
10094                }
10095                return originalPs;
10096            }
10097        }
10098        return null;
10099    }
10100
10101    /**
10102     * Renames the package if it was installed under a different name.
10103     * <p>When we've already installed the package under an original name, update
10104     * the new package so we can continue to have the old name.
10105     */
10106    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10107            @NonNull String renamedPackageName) {
10108        if (pkg.mOriginalPackages == null
10109                || !pkg.mOriginalPackages.contains(renamedPackageName)
10110                || pkg.packageName.equals(renamedPackageName)) {
10111            return;
10112        }
10113        pkg.setPackageName(renamedPackageName);
10114    }
10115
10116    /**
10117     * Just scans the package without any side effects.
10118     * <p>Not entirely true at the moment. There is still one side effect -- this
10119     * method potentially modifies a live {@link PackageSetting} object representing
10120     * the package being scanned. This will be resolved in the future.
10121     *
10122     * @param request Information about the package to be scanned
10123     * @param isUnderFactoryTest Whether or not the device is under factory test
10124     * @param currentTime The current time, in millis
10125     * @return The results of the scan
10126     */
10127    @GuardedBy("mInstallLock")
10128    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10129            boolean isUnderFactoryTest, long currentTime)
10130                    throws PackageManagerException {
10131        final PackageParser.Package pkg = request.pkg;
10132        PackageSetting pkgSetting = request.pkgSetting;
10133        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10134        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10135        final @ParseFlags int parseFlags = request.parseFlags;
10136        final @ScanFlags int scanFlags = request.scanFlags;
10137        final String realPkgName = request.realPkgName;
10138        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10139        final UserHandle user = request.user;
10140        final boolean isPlatformPackage = request.isPlatformPackage;
10141
10142        List<String> changedAbiCodePath = null;
10143
10144        if (DEBUG_PACKAGE_SCANNING) {
10145            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10146                Log.d(TAG, "Scanning package " + pkg.packageName);
10147        }
10148
10149        if (Build.IS_DEBUGGABLE &&
10150                pkg.isPrivileged() &&
10151                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10152            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10153        }
10154
10155        // Initialize package source and resource directories
10156        final File scanFile = new File(pkg.codePath);
10157        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10158        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10159
10160        // We keep references to the derived CPU Abis from settings in oder to reuse
10161        // them in the case where we're not upgrading or booting for the first time.
10162        String primaryCpuAbiFromSettings = null;
10163        String secondaryCpuAbiFromSettings = null;
10164        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10165
10166        if (!needToDeriveAbi) {
10167            if (pkgSetting != null) {
10168                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10169                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10170            } else {
10171                // Re-scanning a system package after uninstalling updates; need to derive ABI
10172                needToDeriveAbi = true;
10173            }
10174        }
10175
10176        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10177            PackageManagerService.reportSettingsProblem(Log.WARN,
10178                    "Package " + pkg.packageName + " shared user changed from "
10179                            + (pkgSetting.sharedUser != null
10180                            ? pkgSetting.sharedUser.name : "<nothing>")
10181                            + " to "
10182                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10183                            + "; replacing with new");
10184            pkgSetting = null;
10185        }
10186
10187        String[] usesStaticLibraries = null;
10188        if (pkg.usesStaticLibraries != null) {
10189            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10190            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10191        }
10192        final boolean createNewPackage = (pkgSetting == null);
10193        if (createNewPackage) {
10194            final String parentPackageName = (pkg.parentPackage != null)
10195                    ? pkg.parentPackage.packageName : null;
10196            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10197            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10198            // REMOVE SharedUserSetting from method; update in a separate call
10199            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10200                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10201                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10202                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10203                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10204                    user, true /*allowInstall*/, instantApp, virtualPreload,
10205                    parentPackageName, pkg.getChildPackageNames(),
10206                    UserManagerService.getInstance(), usesStaticLibraries,
10207                    pkg.usesStaticLibrariesVersions);
10208        } else {
10209            // REMOVE SharedUserSetting from method; update in a separate call.
10210            //
10211            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10212            // secondaryCpuAbi are not known at this point so we always update them
10213            // to null here, only to reset them at a later point.
10214            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10215                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10216                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10217                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10218                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10219                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10220        }
10221        if (createNewPackage && originalPkgSetting != null) {
10222            // This is the initial transition from the original package, so,
10223            // fix up the new package's name now. We must do this after looking
10224            // up the package under its new name, so getPackageLP takes care of
10225            // fiddling things correctly.
10226            pkg.setPackageName(originalPkgSetting.name);
10227
10228            // File a report about this.
10229            String msg = "New package " + pkgSetting.realName
10230                    + " renamed to replace old package " + pkgSetting.name;
10231            reportSettingsProblem(Log.WARN, msg);
10232        }
10233
10234        if (disabledPkgSetting != null) {
10235            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10236        }
10237
10238        SELinuxMMAC.assignSeInfoValue(pkg);
10239
10240        pkg.mExtras = pkgSetting;
10241        pkg.applicationInfo.processName = fixProcessName(
10242                pkg.applicationInfo.packageName,
10243                pkg.applicationInfo.processName);
10244
10245        if (!isPlatformPackage) {
10246            // Get all of our default paths setup
10247            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10248        }
10249
10250        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10251
10252        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10253            if (needToDeriveAbi) {
10254                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10255                final boolean extractNativeLibs = !pkg.isLibrary();
10256                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10257                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10258
10259                // Some system apps still use directory structure for native libraries
10260                // in which case we might end up not detecting abi solely based on apk
10261                // structure. Try to detect abi based on directory structure.
10262                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10263                        pkg.applicationInfo.primaryCpuAbi == null) {
10264                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10265                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10266                }
10267            } else {
10268                // This is not a first boot or an upgrade, don't bother deriving the
10269                // ABI during the scan. Instead, trust the value that was stored in the
10270                // package setting.
10271                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10272                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10273
10274                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10275
10276                if (DEBUG_ABI_SELECTION) {
10277                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10278                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10279                            pkg.applicationInfo.secondaryCpuAbi);
10280                }
10281            }
10282        } else {
10283            if ((scanFlags & SCAN_MOVE) != 0) {
10284                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10285                // but we already have this packages package info in the PackageSetting. We just
10286                // use that and derive the native library path based on the new codepath.
10287                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10288                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10289            }
10290
10291            // Set native library paths again. For moves, the path will be updated based on the
10292            // ABIs we've determined above. For non-moves, the path will be updated based on the
10293            // ABIs we determined during compilation, but the path will depend on the final
10294            // package path (after the rename away from the stage path).
10295            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10296        }
10297
10298        // This is a special case for the "system" package, where the ABI is
10299        // dictated by the zygote configuration (and init.rc). We should keep track
10300        // of this ABI so that we can deal with "normal" applications that run under
10301        // the same UID correctly.
10302        if (isPlatformPackage) {
10303            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10304                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10305        }
10306
10307        // If there's a mismatch between the abi-override in the package setting
10308        // and the abiOverride specified for the install. Warn about this because we
10309        // would've already compiled the app without taking the package setting into
10310        // account.
10311        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10312            if (cpuAbiOverride == null && pkg.packageName != null) {
10313                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10314                        " for package " + pkg.packageName);
10315            }
10316        }
10317
10318        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10319        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10320        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10321
10322        // Copy the derived override back to the parsed package, so that we can
10323        // update the package settings accordingly.
10324        pkg.cpuAbiOverride = cpuAbiOverride;
10325
10326        if (DEBUG_ABI_SELECTION) {
10327            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10328                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10329                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10330        }
10331
10332        // Push the derived path down into PackageSettings so we know what to
10333        // clean up at uninstall time.
10334        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10335
10336        if (DEBUG_ABI_SELECTION) {
10337            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10338                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10339                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10340        }
10341
10342        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10343            // We don't do this here during boot because we can do it all
10344            // at once after scanning all existing packages.
10345            //
10346            // We also do this *before* we perform dexopt on this package, so that
10347            // we can avoid redundant dexopts, and also to make sure we've got the
10348            // code and package path correct.
10349            changedAbiCodePath =
10350                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10351        }
10352
10353        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10354                android.Manifest.permission.FACTORY_TEST)) {
10355            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10356        }
10357
10358        if (isSystemApp(pkg)) {
10359            pkgSetting.isOrphaned = true;
10360        }
10361
10362        // Take care of first install / last update times.
10363        final long scanFileTime = getLastModifiedTime(pkg);
10364        if (currentTime != 0) {
10365            if (pkgSetting.firstInstallTime == 0) {
10366                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10367            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10368                pkgSetting.lastUpdateTime = currentTime;
10369            }
10370        } else if (pkgSetting.firstInstallTime == 0) {
10371            // We need *something*.  Take time time stamp of the file.
10372            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10373        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10374            if (scanFileTime != pkgSetting.timeStamp) {
10375                // A package on the system image has changed; consider this
10376                // to be an update.
10377                pkgSetting.lastUpdateTime = scanFileTime;
10378            }
10379        }
10380        pkgSetting.setTimeStamp(scanFileTime);
10381
10382        pkgSetting.pkg = pkg;
10383        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10384        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10385            pkgSetting.versionCode = pkg.getLongVersionCode();
10386        }
10387        // Update volume if needed
10388        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10389        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10390            Slog.i(PackageManagerService.TAG,
10391                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10392                    + " package " + pkg.packageName
10393                    + " volume from " + pkgSetting.volumeUuid
10394                    + " to " + volumeUuid);
10395            pkgSetting.volumeUuid = volumeUuid;
10396        }
10397
10398        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10399    }
10400
10401    /**
10402     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10403     */
10404    private static boolean apkHasCode(String fileName) {
10405        StrictJarFile jarFile = null;
10406        try {
10407            jarFile = new StrictJarFile(fileName,
10408                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10409            return jarFile.findEntry("classes.dex") != null;
10410        } catch (IOException ignore) {
10411        } finally {
10412            try {
10413                if (jarFile != null) {
10414                    jarFile.close();
10415                }
10416            } catch (IOException ignore) {}
10417        }
10418        return false;
10419    }
10420
10421    /**
10422     * Enforces code policy for the package. This ensures that if an APK has
10423     * declared hasCode="true" in its manifest that the APK actually contains
10424     * code.
10425     *
10426     * @throws PackageManagerException If bytecode could not be found when it should exist
10427     */
10428    private static void assertCodePolicy(PackageParser.Package pkg)
10429            throws PackageManagerException {
10430        final boolean shouldHaveCode =
10431                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10432        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10433            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10434                    "Package " + pkg.baseCodePath + " code is missing");
10435        }
10436
10437        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10438            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10439                final boolean splitShouldHaveCode =
10440                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10441                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10442                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10443                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10444                }
10445            }
10446        }
10447    }
10448
10449    /**
10450     * Applies policy to the parsed package based upon the given policy flags.
10451     * Ensures the package is in a good state.
10452     * <p>
10453     * Implementation detail: This method must NOT have any side effect. It would
10454     * ideally be static, but, it requires locks to read system state.
10455     */
10456    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10457            final @ScanFlags int scanFlags) {
10458        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10459            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10460            if (pkg.applicationInfo.isDirectBootAware()) {
10461                // we're direct boot aware; set for all components
10462                for (PackageParser.Service s : pkg.services) {
10463                    s.info.encryptionAware = s.info.directBootAware = true;
10464                }
10465                for (PackageParser.Provider p : pkg.providers) {
10466                    p.info.encryptionAware = p.info.directBootAware = true;
10467                }
10468                for (PackageParser.Activity a : pkg.activities) {
10469                    a.info.encryptionAware = a.info.directBootAware = true;
10470                }
10471                for (PackageParser.Activity r : pkg.receivers) {
10472                    r.info.encryptionAware = r.info.directBootAware = true;
10473                }
10474            }
10475            if (compressedFileExists(pkg.codePath)) {
10476                pkg.isStub = true;
10477            }
10478        } else {
10479            // non system apps can't be flagged as core
10480            pkg.coreApp = false;
10481            // clear flags not applicable to regular apps
10482            pkg.applicationInfo.flags &=
10483                    ~ApplicationInfo.FLAG_PERSISTENT;
10484            pkg.applicationInfo.privateFlags &=
10485                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10486            pkg.applicationInfo.privateFlags &=
10487                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10488            // clear protected broadcasts
10489            pkg.protectedBroadcasts = null;
10490            // cap permission priorities
10491            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10492                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10493                    pkg.permissionGroups.get(i).info.priority = 0;
10494                }
10495            }
10496        }
10497        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10498            // ignore export request for single user receivers
10499            if (pkg.receivers != null) {
10500                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10501                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10502                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10503                        receiver.info.exported = false;
10504                    }
10505                }
10506            }
10507            // ignore export request for single user services
10508            if (pkg.services != null) {
10509                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10510                    final PackageParser.Service service = pkg.services.get(i);
10511                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10512                        service.info.exported = false;
10513                    }
10514                }
10515            }
10516            // ignore export request for single user providers
10517            if (pkg.providers != null) {
10518                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10519                    final PackageParser.Provider provider = pkg.providers.get(i);
10520                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10521                        provider.info.exported = false;
10522                    }
10523                }
10524            }
10525        }
10526        pkg.mTrustedOverlay = (scanFlags & SCAN_TRUSTED_OVERLAY) != 0;
10527
10528        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10529            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10530        }
10531
10532        if ((scanFlags & SCAN_AS_OEM) != 0) {
10533            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10534        }
10535
10536        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10537            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10538        }
10539
10540        if (!isSystemApp(pkg)) {
10541            // Only system apps can use these features.
10542            pkg.mOriginalPackages = null;
10543            pkg.mRealPackage = null;
10544            pkg.mAdoptPermissions = null;
10545        }
10546    }
10547
10548    /**
10549     * Asserts the parsed package is valid according to the given policy. If the
10550     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10551     * <p>
10552     * Implementation detail: This method must NOT have any side effects. It would
10553     * ideally be static, but, it requires locks to read system state.
10554     *
10555     * @throws PackageManagerException If the package fails any of the validation checks
10556     */
10557    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10558            final @ScanFlags int scanFlags)
10559                    throws PackageManagerException {
10560        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10561            assertCodePolicy(pkg);
10562        }
10563
10564        if (pkg.applicationInfo.getCodePath() == null ||
10565                pkg.applicationInfo.getResourcePath() == null) {
10566            // Bail out. The resource and code paths haven't been set.
10567            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10568                    "Code and resource paths haven't been set correctly");
10569        }
10570
10571        // Make sure we're not adding any bogus keyset info
10572        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10573        ksms.assertScannedPackageValid(pkg);
10574
10575        synchronized (mPackages) {
10576            // The special "android" package can only be defined once
10577            if (pkg.packageName.equals("android")) {
10578                if (mAndroidApplication != null) {
10579                    Slog.w(TAG, "*************************************************");
10580                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10581                    Slog.w(TAG, " codePath=" + pkg.codePath);
10582                    Slog.w(TAG, "*************************************************");
10583                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10584                            "Core android package being redefined.  Skipping.");
10585                }
10586            }
10587
10588            // A package name must be unique; don't allow duplicates
10589            if (mPackages.containsKey(pkg.packageName)) {
10590                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10591                        "Application package " + pkg.packageName
10592                        + " already installed.  Skipping duplicate.");
10593            }
10594
10595            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10596                // Static libs have a synthetic package name containing the version
10597                // but we still want the base name to be unique.
10598                if (mPackages.containsKey(pkg.manifestPackageName)) {
10599                    throw new PackageManagerException(
10600                            "Duplicate static shared lib provider package");
10601                }
10602
10603                // Static shared libraries should have at least O target SDK
10604                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10605                    throw new PackageManagerException(
10606                            "Packages declaring static-shared libs must target O SDK or higher");
10607                }
10608
10609                // Package declaring static a shared lib cannot be instant apps
10610                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10611                    throw new PackageManagerException(
10612                            "Packages declaring static-shared libs cannot be instant apps");
10613                }
10614
10615                // Package declaring static a shared lib cannot be renamed since the package
10616                // name is synthetic and apps can't code around package manager internals.
10617                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10618                    throw new PackageManagerException(
10619                            "Packages declaring static-shared libs cannot be renamed");
10620                }
10621
10622                // Package declaring static a shared lib cannot declare child packages
10623                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10624                    throw new PackageManagerException(
10625                            "Packages declaring static-shared libs cannot have child packages");
10626                }
10627
10628                // Package declaring static a shared lib cannot declare dynamic libs
10629                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10630                    throw new PackageManagerException(
10631                            "Packages declaring static-shared libs cannot declare dynamic libs");
10632                }
10633
10634                // Package declaring static a shared lib cannot declare shared users
10635                if (pkg.mSharedUserId != null) {
10636                    throw new PackageManagerException(
10637                            "Packages declaring static-shared libs cannot declare shared users");
10638                }
10639
10640                // Static shared libs cannot declare activities
10641                if (!pkg.activities.isEmpty()) {
10642                    throw new PackageManagerException(
10643                            "Static shared libs cannot declare activities");
10644                }
10645
10646                // Static shared libs cannot declare services
10647                if (!pkg.services.isEmpty()) {
10648                    throw new PackageManagerException(
10649                            "Static shared libs cannot declare services");
10650                }
10651
10652                // Static shared libs cannot declare providers
10653                if (!pkg.providers.isEmpty()) {
10654                    throw new PackageManagerException(
10655                            "Static shared libs cannot declare content providers");
10656                }
10657
10658                // Static shared libs cannot declare receivers
10659                if (!pkg.receivers.isEmpty()) {
10660                    throw new PackageManagerException(
10661                            "Static shared libs cannot declare broadcast receivers");
10662                }
10663
10664                // Static shared libs cannot declare permission groups
10665                if (!pkg.permissionGroups.isEmpty()) {
10666                    throw new PackageManagerException(
10667                            "Static shared libs cannot declare permission groups");
10668                }
10669
10670                // Static shared libs cannot declare permissions
10671                if (!pkg.permissions.isEmpty()) {
10672                    throw new PackageManagerException(
10673                            "Static shared libs cannot declare permissions");
10674                }
10675
10676                // Static shared libs cannot declare protected broadcasts
10677                if (pkg.protectedBroadcasts != null) {
10678                    throw new PackageManagerException(
10679                            "Static shared libs cannot declare protected broadcasts");
10680                }
10681
10682                // Static shared libs cannot be overlay targets
10683                if (pkg.mOverlayTarget != null) {
10684                    throw new PackageManagerException(
10685                            "Static shared libs cannot be overlay targets");
10686                }
10687
10688                // The version codes must be ordered as lib versions
10689                long minVersionCode = Long.MIN_VALUE;
10690                long maxVersionCode = Long.MAX_VALUE;
10691
10692                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10693                        pkg.staticSharedLibName);
10694                if (versionedLib != null) {
10695                    final int versionCount = versionedLib.size();
10696                    for (int i = 0; i < versionCount; i++) {
10697                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10698                        final long libVersionCode = libInfo.getDeclaringPackage()
10699                                .getLongVersionCode();
10700                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10701                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10702                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10703                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10704                        } else {
10705                            minVersionCode = maxVersionCode = libVersionCode;
10706                            break;
10707                        }
10708                    }
10709                }
10710                if (pkg.getLongVersionCode() < minVersionCode
10711                        || pkg.getLongVersionCode() > maxVersionCode) {
10712                    throw new PackageManagerException("Static shared"
10713                            + " lib version codes must be ordered as lib versions");
10714                }
10715            }
10716
10717            // Only privileged apps and updated privileged apps can add child packages.
10718            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10719                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10720                    throw new PackageManagerException("Only privileged apps can add child "
10721                            + "packages. Ignoring package " + pkg.packageName);
10722                }
10723                final int childCount = pkg.childPackages.size();
10724                for (int i = 0; i < childCount; i++) {
10725                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10726                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10727                            childPkg.packageName)) {
10728                        throw new PackageManagerException("Can't override child of "
10729                                + "another disabled app. Ignoring package " + pkg.packageName);
10730                    }
10731                }
10732            }
10733
10734            // If we're only installing presumed-existing packages, require that the
10735            // scanned APK is both already known and at the path previously established
10736            // for it.  Previously unknown packages we pick up normally, but if we have an
10737            // a priori expectation about this package's install presence, enforce it.
10738            // With a singular exception for new system packages. When an OTA contains
10739            // a new system package, we allow the codepath to change from a system location
10740            // to the user-installed location. If we don't allow this change, any newer,
10741            // user-installed version of the application will be ignored.
10742            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10743                if (mExpectingBetter.containsKey(pkg.packageName)) {
10744                    logCriticalInfo(Log.WARN,
10745                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10746                } else {
10747                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10748                    if (known != null) {
10749                        if (DEBUG_PACKAGE_SCANNING) {
10750                            Log.d(TAG, "Examining " + pkg.codePath
10751                                    + " and requiring known paths " + known.codePathString
10752                                    + " & " + known.resourcePathString);
10753                        }
10754                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10755                                || !pkg.applicationInfo.getResourcePath().equals(
10756                                        known.resourcePathString)) {
10757                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10758                                    "Application package " + pkg.packageName
10759                                    + " found at " + pkg.applicationInfo.getCodePath()
10760                                    + " but expected at " + known.codePathString
10761                                    + "; ignoring.");
10762                        }
10763                    } else {
10764                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10765                                "Application package " + pkg.packageName
10766                                + " not found; ignoring.");
10767                    }
10768                }
10769            }
10770
10771            // Verify that this new package doesn't have any content providers
10772            // that conflict with existing packages.  Only do this if the
10773            // package isn't already installed, since we don't want to break
10774            // things that are installed.
10775            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10776                final int N = pkg.providers.size();
10777                int i;
10778                for (i=0; i<N; i++) {
10779                    PackageParser.Provider p = pkg.providers.get(i);
10780                    if (p.info.authority != null) {
10781                        String names[] = p.info.authority.split(";");
10782                        for (int j = 0; j < names.length; j++) {
10783                            if (mProvidersByAuthority.containsKey(names[j])) {
10784                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10785                                final String otherPackageName =
10786                                        ((other != null && other.getComponentName() != null) ?
10787                                                other.getComponentName().getPackageName() : "?");
10788                                throw new PackageManagerException(
10789                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10790                                        "Can't install because provider name " + names[j]
10791                                                + " (in package " + pkg.applicationInfo.packageName
10792                                                + ") is already used by " + otherPackageName);
10793                            }
10794                        }
10795                    }
10796                }
10797            }
10798
10799            // Verify that packages sharing a user with a privileged app are marked as privileged.
10800            if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
10801                SharedUserSetting sharedUserSetting = null;
10802                try {
10803                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
10804                } catch (PackageManagerException ignore) {}
10805                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10806                    // Exempt SharedUsers signed with the platform key.
10807                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10808                    if ((platformPkgSetting.signatures.mSignatures != null) &&
10809                            (compareSignatures(platformPkgSetting.signatures.mSignatures,
10810                                pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
10811                        throw new PackageManagerException("Apps that share a user with a " +
10812                                "privileged app must themselves be marked as privileged. " +
10813                                pkg.packageName + " shares privileged user " +
10814                                pkg.mSharedUserId + ".");
10815                    }
10816                }
10817            }
10818        }
10819    }
10820
10821    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
10822            int type, String declaringPackageName, long declaringVersionCode) {
10823        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10824        if (versionedLib == null) {
10825            versionedLib = new LongSparseArray<>();
10826            mSharedLibraries.put(name, versionedLib);
10827            if (type == SharedLibraryInfo.TYPE_STATIC) {
10828                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10829            }
10830        } else if (versionedLib.indexOfKey(version) >= 0) {
10831            return false;
10832        }
10833        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10834                version, type, declaringPackageName, declaringVersionCode);
10835        versionedLib.put(version, libEntry);
10836        return true;
10837    }
10838
10839    private boolean removeSharedLibraryLPw(String name, long version) {
10840        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10841        if (versionedLib == null) {
10842            return false;
10843        }
10844        final int libIdx = versionedLib.indexOfKey(version);
10845        if (libIdx < 0) {
10846            return false;
10847        }
10848        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10849        versionedLib.remove(version);
10850        if (versionedLib.size() <= 0) {
10851            mSharedLibraries.remove(name);
10852            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10853                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10854                        .getPackageName());
10855            }
10856        }
10857        return true;
10858    }
10859
10860    /**
10861     * Adds a scanned package to the system. When this method is finished, the package will
10862     * be available for query, resolution, etc...
10863     */
10864    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10865            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
10866        final String pkgName = pkg.packageName;
10867        if (mCustomResolverComponentName != null &&
10868                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10869            setUpCustomResolverActivity(pkg);
10870        }
10871
10872        if (pkg.packageName.equals("android")) {
10873            synchronized (mPackages) {
10874                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10875                    // Set up information for our fall-back user intent resolution activity.
10876                    mPlatformPackage = pkg;
10877                    pkg.mVersionCode = mSdkVersion;
10878                    pkg.mVersionCodeMajor = 0;
10879                    mAndroidApplication = pkg.applicationInfo;
10880                    if (!mResolverReplaced) {
10881                        mResolveActivity.applicationInfo = mAndroidApplication;
10882                        mResolveActivity.name = ResolverActivity.class.getName();
10883                        mResolveActivity.packageName = mAndroidApplication.packageName;
10884                        mResolveActivity.processName = "system:ui";
10885                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10886                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10887                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10888                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10889                        mResolveActivity.exported = true;
10890                        mResolveActivity.enabled = true;
10891                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10892                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10893                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10894                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10895                                | ActivityInfo.CONFIG_ORIENTATION
10896                                | ActivityInfo.CONFIG_KEYBOARD
10897                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10898                        mResolveInfo.activityInfo = mResolveActivity;
10899                        mResolveInfo.priority = 0;
10900                        mResolveInfo.preferredOrder = 0;
10901                        mResolveInfo.match = 0;
10902                        mResolveComponentName = new ComponentName(
10903                                mAndroidApplication.packageName, mResolveActivity.name);
10904                    }
10905                }
10906            }
10907        }
10908
10909        ArrayList<PackageParser.Package> clientLibPkgs = null;
10910        // writer
10911        synchronized (mPackages) {
10912            boolean hasStaticSharedLibs = false;
10913
10914            // Any app can add new static shared libraries
10915            if (pkg.staticSharedLibName != null) {
10916                // Static shared libs don't allow renaming as they have synthetic package
10917                // names to allow install of multiple versions, so use name from manifest.
10918                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10919                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10920                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
10921                    hasStaticSharedLibs = true;
10922                } else {
10923                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10924                                + pkg.staticSharedLibName + " already exists; skipping");
10925                }
10926                // Static shared libs cannot be updated once installed since they
10927                // use synthetic package name which includes the version code, so
10928                // not need to update other packages's shared lib dependencies.
10929            }
10930
10931            if (!hasStaticSharedLibs
10932                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10933                // Only system apps can add new dynamic shared libraries.
10934                if (pkg.libraryNames != null) {
10935                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10936                        String name = pkg.libraryNames.get(i);
10937                        boolean allowed = false;
10938                        if (pkg.isUpdatedSystemApp()) {
10939                            // New library entries can only be added through the
10940                            // system image.  This is important to get rid of a lot
10941                            // of nasty edge cases: for example if we allowed a non-
10942                            // system update of the app to add a library, then uninstalling
10943                            // the update would make the library go away, and assumptions
10944                            // we made such as through app install filtering would now
10945                            // have allowed apps on the device which aren't compatible
10946                            // with it.  Better to just have the restriction here, be
10947                            // conservative, and create many fewer cases that can negatively
10948                            // impact the user experience.
10949                            final PackageSetting sysPs = mSettings
10950                                    .getDisabledSystemPkgLPr(pkg.packageName);
10951                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10952                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10953                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10954                                        allowed = true;
10955                                        break;
10956                                    }
10957                                }
10958                            }
10959                        } else {
10960                            allowed = true;
10961                        }
10962                        if (allowed) {
10963                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10964                                    SharedLibraryInfo.VERSION_UNDEFINED,
10965                                    SharedLibraryInfo.TYPE_DYNAMIC,
10966                                    pkg.packageName, pkg.getLongVersionCode())) {
10967                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10968                                        + name + " already exists; skipping");
10969                            }
10970                        } else {
10971                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10972                                    + name + " that is not declared on system image; skipping");
10973                        }
10974                    }
10975
10976                    if ((scanFlags & SCAN_BOOTING) == 0) {
10977                        // If we are not booting, we need to update any applications
10978                        // that are clients of our shared library.  If we are booting,
10979                        // this will all be done once the scan is complete.
10980                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10981                    }
10982                }
10983            }
10984        }
10985
10986        if ((scanFlags & SCAN_BOOTING) != 0) {
10987            // No apps can run during boot scan, so they don't need to be frozen
10988        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10989            // Caller asked to not kill app, so it's probably not frozen
10990        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10991            // Caller asked us to ignore frozen check for some reason; they
10992            // probably didn't know the package name
10993        } else {
10994            // We're doing major surgery on this package, so it better be frozen
10995            // right now to keep it from launching
10996            checkPackageFrozen(pkgName);
10997        }
10998
10999        // Also need to kill any apps that are dependent on the library.
11000        if (clientLibPkgs != null) {
11001            for (int i=0; i<clientLibPkgs.size(); i++) {
11002                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11003                killApplication(clientPkg.applicationInfo.packageName,
11004                        clientPkg.applicationInfo.uid, "update lib");
11005            }
11006        }
11007
11008        // writer
11009        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11010
11011        synchronized (mPackages) {
11012            // We don't expect installation to fail beyond this point
11013
11014            // Add the new setting to mSettings
11015            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11016            // Add the new setting to mPackages
11017            mPackages.put(pkg.applicationInfo.packageName, pkg);
11018            // Make sure we don't accidentally delete its data.
11019            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11020            while (iter.hasNext()) {
11021                PackageCleanItem item = iter.next();
11022                if (pkgName.equals(item.packageName)) {
11023                    iter.remove();
11024                }
11025            }
11026
11027            // Add the package's KeySets to the global KeySetManagerService
11028            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11029            ksms.addScannedPackageLPw(pkg);
11030
11031            int N = pkg.providers.size();
11032            StringBuilder r = null;
11033            int i;
11034            for (i=0; i<N; i++) {
11035                PackageParser.Provider p = pkg.providers.get(i);
11036                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11037                        p.info.processName);
11038                mProviders.addProvider(p);
11039                p.syncable = p.info.isSyncable;
11040                if (p.info.authority != null) {
11041                    String names[] = p.info.authority.split(";");
11042                    p.info.authority = null;
11043                    for (int j = 0; j < names.length; j++) {
11044                        if (j == 1 && p.syncable) {
11045                            // We only want the first authority for a provider to possibly be
11046                            // syncable, so if we already added this provider using a different
11047                            // authority clear the syncable flag. We copy the provider before
11048                            // changing it because the mProviders object contains a reference
11049                            // to a provider that we don't want to change.
11050                            // Only do this for the second authority since the resulting provider
11051                            // object can be the same for all future authorities for this provider.
11052                            p = new PackageParser.Provider(p);
11053                            p.syncable = false;
11054                        }
11055                        if (!mProvidersByAuthority.containsKey(names[j])) {
11056                            mProvidersByAuthority.put(names[j], p);
11057                            if (p.info.authority == null) {
11058                                p.info.authority = names[j];
11059                            } else {
11060                                p.info.authority = p.info.authority + ";" + names[j];
11061                            }
11062                            if (DEBUG_PACKAGE_SCANNING) {
11063                                if (chatty)
11064                                    Log.d(TAG, "Registered content provider: " + names[j]
11065                                            + ", className = " + p.info.name + ", isSyncable = "
11066                                            + p.info.isSyncable);
11067                            }
11068                        } else {
11069                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11070                            Slog.w(TAG, "Skipping provider name " + names[j] +
11071                                    " (in package " + pkg.applicationInfo.packageName +
11072                                    "): name already used by "
11073                                    + ((other != null && other.getComponentName() != null)
11074                                            ? other.getComponentName().getPackageName() : "?"));
11075                        }
11076                    }
11077                }
11078                if (chatty) {
11079                    if (r == null) {
11080                        r = new StringBuilder(256);
11081                    } else {
11082                        r.append(' ');
11083                    }
11084                    r.append(p.info.name);
11085                }
11086            }
11087            if (r != null) {
11088                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11089            }
11090
11091            N = pkg.services.size();
11092            r = null;
11093            for (i=0; i<N; i++) {
11094                PackageParser.Service s = pkg.services.get(i);
11095                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11096                        s.info.processName);
11097                mServices.addService(s);
11098                if (chatty) {
11099                    if (r == null) {
11100                        r = new StringBuilder(256);
11101                    } else {
11102                        r.append(' ');
11103                    }
11104                    r.append(s.info.name);
11105                }
11106            }
11107            if (r != null) {
11108                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11109            }
11110
11111            N = pkg.receivers.size();
11112            r = null;
11113            for (i=0; i<N; i++) {
11114                PackageParser.Activity a = pkg.receivers.get(i);
11115                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11116                        a.info.processName);
11117                mReceivers.addActivity(a, "receiver");
11118                if (chatty) {
11119                    if (r == null) {
11120                        r = new StringBuilder(256);
11121                    } else {
11122                        r.append(' ');
11123                    }
11124                    r.append(a.info.name);
11125                }
11126            }
11127            if (r != null) {
11128                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11129            }
11130
11131            N = pkg.activities.size();
11132            r = null;
11133            for (i=0; i<N; i++) {
11134                PackageParser.Activity a = pkg.activities.get(i);
11135                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11136                        a.info.processName);
11137                mActivities.addActivity(a, "activity");
11138                if (chatty) {
11139                    if (r == null) {
11140                        r = new StringBuilder(256);
11141                    } else {
11142                        r.append(' ');
11143                    }
11144                    r.append(a.info.name);
11145                }
11146            }
11147            if (r != null) {
11148                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11149            }
11150
11151            // Don't allow ephemeral applications to define new permissions groups.
11152            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11153                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11154                        + " ignored: instant apps cannot define new permission groups.");
11155            } else {
11156                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11157            }
11158
11159            // Don't allow ephemeral applications to define new permissions.
11160            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11161                Slog.w(TAG, "Permissions from package " + pkg.packageName
11162                        + " ignored: instant apps cannot define new permissions.");
11163            } else {
11164                mPermissionManager.addAllPermissions(pkg, chatty);
11165            }
11166
11167            N = pkg.instrumentation.size();
11168            r = null;
11169            for (i=0; i<N; i++) {
11170                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11171                a.info.packageName = pkg.applicationInfo.packageName;
11172                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11173                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11174                a.info.splitNames = pkg.splitNames;
11175                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11176                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11177                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11178                a.info.dataDir = pkg.applicationInfo.dataDir;
11179                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11180                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11181                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11182                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11183                mInstrumentation.put(a.getComponentName(), a);
11184                if (chatty) {
11185                    if (r == null) {
11186                        r = new StringBuilder(256);
11187                    } else {
11188                        r.append(' ');
11189                    }
11190                    r.append(a.info.name);
11191                }
11192            }
11193            if (r != null) {
11194                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11195            }
11196
11197            if (pkg.protectedBroadcasts != null) {
11198                N = pkg.protectedBroadcasts.size();
11199                synchronized (mProtectedBroadcasts) {
11200                    for (i = 0; i < N; i++) {
11201                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11202                    }
11203                }
11204            }
11205        }
11206
11207        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11208    }
11209
11210    /**
11211     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11212     * is derived purely on the basis of the contents of {@code scanFile} and
11213     * {@code cpuAbiOverride}.
11214     *
11215     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11216     */
11217    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11218            boolean extractLibs)
11219                    throws PackageManagerException {
11220        // Give ourselves some initial paths; we'll come back for another
11221        // pass once we've determined ABI below.
11222        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11223
11224        // We would never need to extract libs for forward-locked and external packages,
11225        // since the container service will do it for us. We shouldn't attempt to
11226        // extract libs from system app when it was not updated.
11227        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11228                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11229            extractLibs = false;
11230        }
11231
11232        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11233        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11234
11235        NativeLibraryHelper.Handle handle = null;
11236        try {
11237            handle = NativeLibraryHelper.Handle.create(pkg);
11238            // TODO(multiArch): This can be null for apps that didn't go through the
11239            // usual installation process. We can calculate it again, like we
11240            // do during install time.
11241            //
11242            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11243            // unnecessary.
11244            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11245
11246            // Null out the abis so that they can be recalculated.
11247            pkg.applicationInfo.primaryCpuAbi = null;
11248            pkg.applicationInfo.secondaryCpuAbi = null;
11249            if (isMultiArch(pkg.applicationInfo)) {
11250                // Warn if we've set an abiOverride for multi-lib packages..
11251                // By definition, we need to copy both 32 and 64 bit libraries for
11252                // such packages.
11253                if (pkg.cpuAbiOverride != null
11254                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11255                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11256                }
11257
11258                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11259                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11260                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11261                    if (extractLibs) {
11262                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11263                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11264                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11265                                useIsaSpecificSubdirs);
11266                    } else {
11267                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11268                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11269                    }
11270                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11271                }
11272
11273                // Shared library native code should be in the APK zip aligned
11274                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11275                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11276                            "Shared library native lib extraction not supported");
11277                }
11278
11279                maybeThrowExceptionForMultiArchCopy(
11280                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11281
11282                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11283                    if (extractLibs) {
11284                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11285                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11286                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11287                                useIsaSpecificSubdirs);
11288                    } else {
11289                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11290                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11291                    }
11292                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11293                }
11294
11295                maybeThrowExceptionForMultiArchCopy(
11296                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11297
11298                if (abi64 >= 0) {
11299                    // Shared library native libs should be in the APK zip aligned
11300                    if (extractLibs && pkg.isLibrary()) {
11301                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11302                                "Shared library native lib extraction not supported");
11303                    }
11304                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11305                }
11306
11307                if (abi32 >= 0) {
11308                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11309                    if (abi64 >= 0) {
11310                        if (pkg.use32bitAbi) {
11311                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11312                            pkg.applicationInfo.primaryCpuAbi = abi;
11313                        } else {
11314                            pkg.applicationInfo.secondaryCpuAbi = abi;
11315                        }
11316                    } else {
11317                        pkg.applicationInfo.primaryCpuAbi = abi;
11318                    }
11319                }
11320            } else {
11321                String[] abiList = (cpuAbiOverride != null) ?
11322                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11323
11324                // Enable gross and lame hacks for apps that are built with old
11325                // SDK tools. We must scan their APKs for renderscript bitcode and
11326                // not launch them if it's present. Don't bother checking on devices
11327                // that don't have 64 bit support.
11328                boolean needsRenderScriptOverride = false;
11329                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11330                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11331                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11332                    needsRenderScriptOverride = true;
11333                }
11334
11335                final int copyRet;
11336                if (extractLibs) {
11337                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11338                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11339                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11340                } else {
11341                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11342                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11343                }
11344                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11345
11346                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11347                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11348                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11349                }
11350
11351                if (copyRet >= 0) {
11352                    // Shared libraries that have native libs must be multi-architecture
11353                    if (pkg.isLibrary()) {
11354                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11355                                "Shared library with native libs must be multiarch");
11356                    }
11357                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11358                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11359                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11360                } else if (needsRenderScriptOverride) {
11361                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11362                }
11363            }
11364        } catch (IOException ioe) {
11365            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11366        } finally {
11367            IoUtils.closeQuietly(handle);
11368        }
11369
11370        // Now that we've calculated the ABIs and determined if it's an internal app,
11371        // we will go ahead and populate the nativeLibraryPath.
11372        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11373    }
11374
11375    /**
11376     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11377     * i.e, so that all packages can be run inside a single process if required.
11378     *
11379     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11380     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11381     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11382     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11383     * updating a package that belongs to a shared user.
11384     *
11385     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11386     * adds unnecessary complexity.
11387     */
11388    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11389            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11390        List<String> changedAbiCodePath = null;
11391        String requiredInstructionSet = null;
11392        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11393            requiredInstructionSet = VMRuntime.getInstructionSet(
11394                     scannedPackage.applicationInfo.primaryCpuAbi);
11395        }
11396
11397        PackageSetting requirer = null;
11398        for (PackageSetting ps : packagesForUser) {
11399            // If packagesForUser contains scannedPackage, we skip it. This will happen
11400            // when scannedPackage is an update of an existing package. Without this check,
11401            // we will never be able to change the ABI of any package belonging to a shared
11402            // user, even if it's compatible with other packages.
11403            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11404                if (ps.primaryCpuAbiString == null) {
11405                    continue;
11406                }
11407
11408                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11409                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11410                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11411                    // this but there's not much we can do.
11412                    String errorMessage = "Instruction set mismatch, "
11413                            + ((requirer == null) ? "[caller]" : requirer)
11414                            + " requires " + requiredInstructionSet + " whereas " + ps
11415                            + " requires " + instructionSet;
11416                    Slog.w(TAG, errorMessage);
11417                }
11418
11419                if (requiredInstructionSet == null) {
11420                    requiredInstructionSet = instructionSet;
11421                    requirer = ps;
11422                }
11423            }
11424        }
11425
11426        if (requiredInstructionSet != null) {
11427            String adjustedAbi;
11428            if (requirer != null) {
11429                // requirer != null implies that either scannedPackage was null or that scannedPackage
11430                // did not require an ABI, in which case we have to adjust scannedPackage to match
11431                // the ABI of the set (which is the same as requirer's ABI)
11432                adjustedAbi = requirer.primaryCpuAbiString;
11433                if (scannedPackage != null) {
11434                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11435                }
11436            } else {
11437                // requirer == null implies that we're updating all ABIs in the set to
11438                // match scannedPackage.
11439                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11440            }
11441
11442            for (PackageSetting ps : packagesForUser) {
11443                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11444                    if (ps.primaryCpuAbiString != null) {
11445                        continue;
11446                    }
11447
11448                    ps.primaryCpuAbiString = adjustedAbi;
11449                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11450                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11451                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11452                        if (DEBUG_ABI_SELECTION) {
11453                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11454                                    + " (requirer="
11455                                    + (requirer != null ? requirer.pkg : "null")
11456                                    + ", scannedPackage="
11457                                    + (scannedPackage != null ? scannedPackage : "null")
11458                                    + ")");
11459                        }
11460                        if (changedAbiCodePath == null) {
11461                            changedAbiCodePath = new ArrayList<>();
11462                        }
11463                        changedAbiCodePath.add(ps.codePathString);
11464                    }
11465                }
11466            }
11467        }
11468        return changedAbiCodePath;
11469    }
11470
11471    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11472        synchronized (mPackages) {
11473            mResolverReplaced = true;
11474            // Set up information for custom user intent resolution activity.
11475            mResolveActivity.applicationInfo = pkg.applicationInfo;
11476            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11477            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11478            mResolveActivity.processName = pkg.applicationInfo.packageName;
11479            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11480            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11481                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11482            mResolveActivity.theme = 0;
11483            mResolveActivity.exported = true;
11484            mResolveActivity.enabled = true;
11485            mResolveInfo.activityInfo = mResolveActivity;
11486            mResolveInfo.priority = 0;
11487            mResolveInfo.preferredOrder = 0;
11488            mResolveInfo.match = 0;
11489            mResolveComponentName = mCustomResolverComponentName;
11490            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11491                    mResolveComponentName);
11492        }
11493    }
11494
11495    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11496        if (installerActivity == null) {
11497            if (DEBUG_EPHEMERAL) {
11498                Slog.d(TAG, "Clear ephemeral installer activity");
11499            }
11500            mInstantAppInstallerActivity = null;
11501            return;
11502        }
11503
11504        if (DEBUG_EPHEMERAL) {
11505            Slog.d(TAG, "Set ephemeral installer activity: "
11506                    + installerActivity.getComponentName());
11507        }
11508        // Set up information for ephemeral installer activity
11509        mInstantAppInstallerActivity = installerActivity;
11510        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11511                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11512        mInstantAppInstallerActivity.exported = true;
11513        mInstantAppInstallerActivity.enabled = true;
11514        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11515        mInstantAppInstallerInfo.priority = 0;
11516        mInstantAppInstallerInfo.preferredOrder = 1;
11517        mInstantAppInstallerInfo.isDefault = true;
11518        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11519                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11520    }
11521
11522    private static String calculateBundledApkRoot(final String codePathString) {
11523        final File codePath = new File(codePathString);
11524        final File codeRoot;
11525        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11526            codeRoot = Environment.getRootDirectory();
11527        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11528            codeRoot = Environment.getOemDirectory();
11529        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11530            codeRoot = Environment.getVendorDirectory();
11531        } else {
11532            // Unrecognized code path; take its top real segment as the apk root:
11533            // e.g. /something/app/blah.apk => /something
11534            try {
11535                File f = codePath.getCanonicalFile();
11536                File parent = f.getParentFile();    // non-null because codePath is a file
11537                File tmp;
11538                while ((tmp = parent.getParentFile()) != null) {
11539                    f = parent;
11540                    parent = tmp;
11541                }
11542                codeRoot = f;
11543                Slog.w(TAG, "Unrecognized code path "
11544                        + codePath + " - using " + codeRoot);
11545            } catch (IOException e) {
11546                // Can't canonicalize the code path -- shenanigans?
11547                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11548                return Environment.getRootDirectory().getPath();
11549            }
11550        }
11551        return codeRoot.getPath();
11552    }
11553
11554    /**
11555     * Derive and set the location of native libraries for the given package,
11556     * which varies depending on where and how the package was installed.
11557     */
11558    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11559        final ApplicationInfo info = pkg.applicationInfo;
11560        final String codePath = pkg.codePath;
11561        final File codeFile = new File(codePath);
11562        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11563        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11564
11565        info.nativeLibraryRootDir = null;
11566        info.nativeLibraryRootRequiresIsa = false;
11567        info.nativeLibraryDir = null;
11568        info.secondaryNativeLibraryDir = null;
11569
11570        if (isApkFile(codeFile)) {
11571            // Monolithic install
11572            if (bundledApp) {
11573                // If "/system/lib64/apkname" exists, assume that is the per-package
11574                // native library directory to use; otherwise use "/system/lib/apkname".
11575                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11576                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11577                        getPrimaryInstructionSet(info));
11578
11579                // This is a bundled system app so choose the path based on the ABI.
11580                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11581                // is just the default path.
11582                final String apkName = deriveCodePathName(codePath);
11583                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11584                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11585                        apkName).getAbsolutePath();
11586
11587                if (info.secondaryCpuAbi != null) {
11588                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11589                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11590                            secondaryLibDir, apkName).getAbsolutePath();
11591                }
11592            } else if (asecApp) {
11593                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11594                        .getAbsolutePath();
11595            } else {
11596                final String apkName = deriveCodePathName(codePath);
11597                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11598                        .getAbsolutePath();
11599            }
11600
11601            info.nativeLibraryRootRequiresIsa = false;
11602            info.nativeLibraryDir = info.nativeLibraryRootDir;
11603        } else {
11604            // Cluster install
11605            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11606            info.nativeLibraryRootRequiresIsa = true;
11607
11608            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11609                    getPrimaryInstructionSet(info)).getAbsolutePath();
11610
11611            if (info.secondaryCpuAbi != null) {
11612                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11613                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11614            }
11615        }
11616    }
11617
11618    /**
11619     * Calculate the abis and roots for a bundled app. These can uniquely
11620     * be determined from the contents of the system partition, i.e whether
11621     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11622     * of this information, and instead assume that the system was built
11623     * sensibly.
11624     */
11625    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11626                                           PackageSetting pkgSetting) {
11627        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11628
11629        // If "/system/lib64/apkname" exists, assume that is the per-package
11630        // native library directory to use; otherwise use "/system/lib/apkname".
11631        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11632        setBundledAppAbi(pkg, apkRoot, apkName);
11633        // pkgSetting might be null during rescan following uninstall of updates
11634        // to a bundled app, so accommodate that possibility.  The settings in
11635        // that case will be established later from the parsed package.
11636        //
11637        // If the settings aren't null, sync them up with what we've just derived.
11638        // note that apkRoot isn't stored in the package settings.
11639        if (pkgSetting != null) {
11640            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11641            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11642        }
11643    }
11644
11645    /**
11646     * Deduces the ABI of a bundled app and sets the relevant fields on the
11647     * parsed pkg object.
11648     *
11649     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11650     *        under which system libraries are installed.
11651     * @param apkName the name of the installed package.
11652     */
11653    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11654        final File codeFile = new File(pkg.codePath);
11655
11656        final boolean has64BitLibs;
11657        final boolean has32BitLibs;
11658        if (isApkFile(codeFile)) {
11659            // Monolithic install
11660            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11661            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11662        } else {
11663            // Cluster install
11664            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11665            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11666                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11667                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11668                has64BitLibs = (new File(rootDir, isa)).exists();
11669            } else {
11670                has64BitLibs = false;
11671            }
11672            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11673                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11674                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11675                has32BitLibs = (new File(rootDir, isa)).exists();
11676            } else {
11677                has32BitLibs = false;
11678            }
11679        }
11680
11681        if (has64BitLibs && !has32BitLibs) {
11682            // The package has 64 bit libs, but not 32 bit libs. Its primary
11683            // ABI should be 64 bit. We can safely assume here that the bundled
11684            // native libraries correspond to the most preferred ABI in the list.
11685
11686            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11687            pkg.applicationInfo.secondaryCpuAbi = null;
11688        } else if (has32BitLibs && !has64BitLibs) {
11689            // The package has 32 bit libs but not 64 bit libs. Its primary
11690            // ABI should be 32 bit.
11691
11692            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11693            pkg.applicationInfo.secondaryCpuAbi = null;
11694        } else if (has32BitLibs && has64BitLibs) {
11695            // The application has both 64 and 32 bit bundled libraries. We check
11696            // here that the app declares multiArch support, and warn if it doesn't.
11697            //
11698            // We will be lenient here and record both ABIs. The primary will be the
11699            // ABI that's higher on the list, i.e, a device that's configured to prefer
11700            // 64 bit apps will see a 64 bit primary ABI,
11701
11702            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11703                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11704            }
11705
11706            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11707                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11708                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11709            } else {
11710                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11711                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11712            }
11713        } else {
11714            pkg.applicationInfo.primaryCpuAbi = null;
11715            pkg.applicationInfo.secondaryCpuAbi = null;
11716        }
11717    }
11718
11719    private void killApplication(String pkgName, int appId, String reason) {
11720        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11721    }
11722
11723    private void killApplication(String pkgName, int appId, int userId, String reason) {
11724        // Request the ActivityManager to kill the process(only for existing packages)
11725        // so that we do not end up in a confused state while the user is still using the older
11726        // version of the application while the new one gets installed.
11727        final long token = Binder.clearCallingIdentity();
11728        try {
11729            IActivityManager am = ActivityManager.getService();
11730            if (am != null) {
11731                try {
11732                    am.killApplication(pkgName, appId, userId, reason);
11733                } catch (RemoteException e) {
11734                }
11735            }
11736        } finally {
11737            Binder.restoreCallingIdentity(token);
11738        }
11739    }
11740
11741    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11742        // Remove the parent package setting
11743        PackageSetting ps = (PackageSetting) pkg.mExtras;
11744        if (ps != null) {
11745            removePackageLI(ps, chatty);
11746        }
11747        // Remove the child package setting
11748        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11749        for (int i = 0; i < childCount; i++) {
11750            PackageParser.Package childPkg = pkg.childPackages.get(i);
11751            ps = (PackageSetting) childPkg.mExtras;
11752            if (ps != null) {
11753                removePackageLI(ps, chatty);
11754            }
11755        }
11756    }
11757
11758    void removePackageLI(PackageSetting ps, boolean chatty) {
11759        if (DEBUG_INSTALL) {
11760            if (chatty)
11761                Log.d(TAG, "Removing package " + ps.name);
11762        }
11763
11764        // writer
11765        synchronized (mPackages) {
11766            mPackages.remove(ps.name);
11767            final PackageParser.Package pkg = ps.pkg;
11768            if (pkg != null) {
11769                cleanPackageDataStructuresLILPw(pkg, chatty);
11770            }
11771        }
11772    }
11773
11774    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11775        if (DEBUG_INSTALL) {
11776            if (chatty)
11777                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11778        }
11779
11780        // writer
11781        synchronized (mPackages) {
11782            // Remove the parent package
11783            mPackages.remove(pkg.applicationInfo.packageName);
11784            cleanPackageDataStructuresLILPw(pkg, chatty);
11785
11786            // Remove the child packages
11787            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11788            for (int i = 0; i < childCount; i++) {
11789                PackageParser.Package childPkg = pkg.childPackages.get(i);
11790                mPackages.remove(childPkg.applicationInfo.packageName);
11791                cleanPackageDataStructuresLILPw(childPkg, chatty);
11792            }
11793        }
11794    }
11795
11796    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11797        int N = pkg.providers.size();
11798        StringBuilder r = null;
11799        int i;
11800        for (i=0; i<N; i++) {
11801            PackageParser.Provider p = pkg.providers.get(i);
11802            mProviders.removeProvider(p);
11803            if (p.info.authority == null) {
11804
11805                /* There was another ContentProvider with this authority when
11806                 * this app was installed so this authority is null,
11807                 * Ignore it as we don't have to unregister the provider.
11808                 */
11809                continue;
11810            }
11811            String names[] = p.info.authority.split(";");
11812            for (int j = 0; j < names.length; j++) {
11813                if (mProvidersByAuthority.get(names[j]) == p) {
11814                    mProvidersByAuthority.remove(names[j]);
11815                    if (DEBUG_REMOVE) {
11816                        if (chatty)
11817                            Log.d(TAG, "Unregistered content provider: " + names[j]
11818                                    + ", className = " + p.info.name + ", isSyncable = "
11819                                    + p.info.isSyncable);
11820                    }
11821                }
11822            }
11823            if (DEBUG_REMOVE && chatty) {
11824                if (r == null) {
11825                    r = new StringBuilder(256);
11826                } else {
11827                    r.append(' ');
11828                }
11829                r.append(p.info.name);
11830            }
11831        }
11832        if (r != null) {
11833            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11834        }
11835
11836        N = pkg.services.size();
11837        r = null;
11838        for (i=0; i<N; i++) {
11839            PackageParser.Service s = pkg.services.get(i);
11840            mServices.removeService(s);
11841            if (chatty) {
11842                if (r == null) {
11843                    r = new StringBuilder(256);
11844                } else {
11845                    r.append(' ');
11846                }
11847                r.append(s.info.name);
11848            }
11849        }
11850        if (r != null) {
11851            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11852        }
11853
11854        N = pkg.receivers.size();
11855        r = null;
11856        for (i=0; i<N; i++) {
11857            PackageParser.Activity a = pkg.receivers.get(i);
11858            mReceivers.removeActivity(a, "receiver");
11859            if (DEBUG_REMOVE && chatty) {
11860                if (r == null) {
11861                    r = new StringBuilder(256);
11862                } else {
11863                    r.append(' ');
11864                }
11865                r.append(a.info.name);
11866            }
11867        }
11868        if (r != null) {
11869            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11870        }
11871
11872        N = pkg.activities.size();
11873        r = null;
11874        for (i=0; i<N; i++) {
11875            PackageParser.Activity a = pkg.activities.get(i);
11876            mActivities.removeActivity(a, "activity");
11877            if (DEBUG_REMOVE && chatty) {
11878                if (r == null) {
11879                    r = new StringBuilder(256);
11880                } else {
11881                    r.append(' ');
11882                }
11883                r.append(a.info.name);
11884            }
11885        }
11886        if (r != null) {
11887            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11888        }
11889
11890        mPermissionManager.removeAllPermissions(pkg, chatty);
11891
11892        N = pkg.instrumentation.size();
11893        r = null;
11894        for (i=0; i<N; i++) {
11895            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11896            mInstrumentation.remove(a.getComponentName());
11897            if (DEBUG_REMOVE && chatty) {
11898                if (r == null) {
11899                    r = new StringBuilder(256);
11900                } else {
11901                    r.append(' ');
11902                }
11903                r.append(a.info.name);
11904            }
11905        }
11906        if (r != null) {
11907            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11908        }
11909
11910        r = null;
11911        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11912            // Only system apps can hold shared libraries.
11913            if (pkg.libraryNames != null) {
11914                for (i = 0; i < pkg.libraryNames.size(); i++) {
11915                    String name = pkg.libraryNames.get(i);
11916                    if (removeSharedLibraryLPw(name, 0)) {
11917                        if (DEBUG_REMOVE && chatty) {
11918                            if (r == null) {
11919                                r = new StringBuilder(256);
11920                            } else {
11921                                r.append(' ');
11922                            }
11923                            r.append(name);
11924                        }
11925                    }
11926                }
11927            }
11928        }
11929
11930        r = null;
11931
11932        // Any package can hold static shared libraries.
11933        if (pkg.staticSharedLibName != null) {
11934            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11935                if (DEBUG_REMOVE && chatty) {
11936                    if (r == null) {
11937                        r = new StringBuilder(256);
11938                    } else {
11939                        r.append(' ');
11940                    }
11941                    r.append(pkg.staticSharedLibName);
11942                }
11943            }
11944        }
11945
11946        if (r != null) {
11947            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11948        }
11949    }
11950
11951
11952    final class ActivityIntentResolver
11953            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11954        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11955                boolean defaultOnly, int userId) {
11956            if (!sUserManager.exists(userId)) return null;
11957            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11958            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11959        }
11960
11961        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11962                int userId) {
11963            if (!sUserManager.exists(userId)) return null;
11964            mFlags = flags;
11965            return super.queryIntent(intent, resolvedType,
11966                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11967                    userId);
11968        }
11969
11970        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11971                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11972            if (!sUserManager.exists(userId)) return null;
11973            if (packageActivities == null) {
11974                return null;
11975            }
11976            mFlags = flags;
11977            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11978            final int N = packageActivities.size();
11979            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11980                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11981
11982            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11983            for (int i = 0; i < N; ++i) {
11984                intentFilters = packageActivities.get(i).intents;
11985                if (intentFilters != null && intentFilters.size() > 0) {
11986                    PackageParser.ActivityIntentInfo[] array =
11987                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
11988                    intentFilters.toArray(array);
11989                    listCut.add(array);
11990                }
11991            }
11992            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11993        }
11994
11995        /**
11996         * Finds a privileged activity that matches the specified activity names.
11997         */
11998        private PackageParser.Activity findMatchingActivity(
11999                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12000            for (PackageParser.Activity sysActivity : activityList) {
12001                if (sysActivity.info.name.equals(activityInfo.name)) {
12002                    return sysActivity;
12003                }
12004                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12005                    return sysActivity;
12006                }
12007                if (sysActivity.info.targetActivity != null) {
12008                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12009                        return sysActivity;
12010                    }
12011                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12012                        return sysActivity;
12013                    }
12014                }
12015            }
12016            return null;
12017        }
12018
12019        public class IterGenerator<E> {
12020            public Iterator<E> generate(ActivityIntentInfo info) {
12021                return null;
12022            }
12023        }
12024
12025        public class ActionIterGenerator extends IterGenerator<String> {
12026            @Override
12027            public Iterator<String> generate(ActivityIntentInfo info) {
12028                return info.actionsIterator();
12029            }
12030        }
12031
12032        public class CategoriesIterGenerator extends IterGenerator<String> {
12033            @Override
12034            public Iterator<String> generate(ActivityIntentInfo info) {
12035                return info.categoriesIterator();
12036            }
12037        }
12038
12039        public class SchemesIterGenerator extends IterGenerator<String> {
12040            @Override
12041            public Iterator<String> generate(ActivityIntentInfo info) {
12042                return info.schemesIterator();
12043            }
12044        }
12045
12046        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12047            @Override
12048            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12049                return info.authoritiesIterator();
12050            }
12051        }
12052
12053        /**
12054         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12055         * MODIFIED. Do not pass in a list that should not be changed.
12056         */
12057        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12058                IterGenerator<T> generator, Iterator<T> searchIterator) {
12059            // loop through the set of actions; every one must be found in the intent filter
12060            while (searchIterator.hasNext()) {
12061                // we must have at least one filter in the list to consider a match
12062                if (intentList.size() == 0) {
12063                    break;
12064                }
12065
12066                final T searchAction = searchIterator.next();
12067
12068                // loop through the set of intent filters
12069                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12070                while (intentIter.hasNext()) {
12071                    final ActivityIntentInfo intentInfo = intentIter.next();
12072                    boolean selectionFound = false;
12073
12074                    // loop through the intent filter's selection criteria; at least one
12075                    // of them must match the searched criteria
12076                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12077                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12078                        final T intentSelection = intentSelectionIter.next();
12079                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12080                            selectionFound = true;
12081                            break;
12082                        }
12083                    }
12084
12085                    // the selection criteria wasn't found in this filter's set; this filter
12086                    // is not a potential match
12087                    if (!selectionFound) {
12088                        intentIter.remove();
12089                    }
12090                }
12091            }
12092        }
12093
12094        private boolean isProtectedAction(ActivityIntentInfo filter) {
12095            final Iterator<String> actionsIter = filter.actionsIterator();
12096            while (actionsIter != null && actionsIter.hasNext()) {
12097                final String filterAction = actionsIter.next();
12098                if (PROTECTED_ACTIONS.contains(filterAction)) {
12099                    return true;
12100                }
12101            }
12102            return false;
12103        }
12104
12105        /**
12106         * Adjusts the priority of the given intent filter according to policy.
12107         * <p>
12108         * <ul>
12109         * <li>The priority for non privileged applications is capped to '0'</li>
12110         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12111         * <li>The priority for unbundled updates to privileged applications is capped to the
12112         *      priority defined on the system partition</li>
12113         * </ul>
12114         * <p>
12115         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12116         * allowed to obtain any priority on any action.
12117         */
12118        private void adjustPriority(
12119                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12120            // nothing to do; priority is fine as-is
12121            if (intent.getPriority() <= 0) {
12122                return;
12123            }
12124
12125            final ActivityInfo activityInfo = intent.activity.info;
12126            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12127
12128            final boolean privilegedApp =
12129                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12130            if (!privilegedApp) {
12131                // non-privileged applications can never define a priority >0
12132                if (DEBUG_FILTERS) {
12133                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12134                            + " package: " + applicationInfo.packageName
12135                            + " activity: " + intent.activity.className
12136                            + " origPrio: " + intent.getPriority());
12137                }
12138                intent.setPriority(0);
12139                return;
12140            }
12141
12142            if (systemActivities == null) {
12143                // the system package is not disabled; we're parsing the system partition
12144                if (isProtectedAction(intent)) {
12145                    if (mDeferProtectedFilters) {
12146                        // We can't deal with these just yet. No component should ever obtain a
12147                        // >0 priority for a protected actions, with ONE exception -- the setup
12148                        // wizard. The setup wizard, however, cannot be known until we're able to
12149                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12150                        // until all intent filters have been processed. Chicken, meet egg.
12151                        // Let the filter temporarily have a high priority and rectify the
12152                        // priorities after all system packages have been scanned.
12153                        mProtectedFilters.add(intent);
12154                        if (DEBUG_FILTERS) {
12155                            Slog.i(TAG, "Protected action; save for later;"
12156                                    + " package: " + applicationInfo.packageName
12157                                    + " activity: " + intent.activity.className
12158                                    + " origPrio: " + intent.getPriority());
12159                        }
12160                        return;
12161                    } else {
12162                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12163                            Slog.i(TAG, "No setup wizard;"
12164                                + " All protected intents capped to priority 0");
12165                        }
12166                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12167                            if (DEBUG_FILTERS) {
12168                                Slog.i(TAG, "Found setup wizard;"
12169                                    + " allow priority " + intent.getPriority() + ";"
12170                                    + " package: " + intent.activity.info.packageName
12171                                    + " activity: " + intent.activity.className
12172                                    + " priority: " + intent.getPriority());
12173                            }
12174                            // setup wizard gets whatever it wants
12175                            return;
12176                        }
12177                        if (DEBUG_FILTERS) {
12178                            Slog.i(TAG, "Protected action; cap priority to 0;"
12179                                    + " package: " + intent.activity.info.packageName
12180                                    + " activity: " + intent.activity.className
12181                                    + " origPrio: " + intent.getPriority());
12182                        }
12183                        intent.setPriority(0);
12184                        return;
12185                    }
12186                }
12187                // privileged apps on the system image get whatever priority they request
12188                return;
12189            }
12190
12191            // privileged app unbundled update ... try to find the same activity
12192            final PackageParser.Activity foundActivity =
12193                    findMatchingActivity(systemActivities, activityInfo);
12194            if (foundActivity == null) {
12195                // this is a new activity; it cannot obtain >0 priority
12196                if (DEBUG_FILTERS) {
12197                    Slog.i(TAG, "New activity; cap priority to 0;"
12198                            + " package: " + applicationInfo.packageName
12199                            + " activity: " + intent.activity.className
12200                            + " origPrio: " + intent.getPriority());
12201                }
12202                intent.setPriority(0);
12203                return;
12204            }
12205
12206            // found activity, now check for filter equivalence
12207
12208            // a shallow copy is enough; we modify the list, not its contents
12209            final List<ActivityIntentInfo> intentListCopy =
12210                    new ArrayList<>(foundActivity.intents);
12211            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12212
12213            // find matching action subsets
12214            final Iterator<String> actionsIterator = intent.actionsIterator();
12215            if (actionsIterator != null) {
12216                getIntentListSubset(
12217                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12218                if (intentListCopy.size() == 0) {
12219                    // no more intents to match; we're not equivalent
12220                    if (DEBUG_FILTERS) {
12221                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12222                                + " package: " + applicationInfo.packageName
12223                                + " activity: " + intent.activity.className
12224                                + " origPrio: " + intent.getPriority());
12225                    }
12226                    intent.setPriority(0);
12227                    return;
12228                }
12229            }
12230
12231            // find matching category subsets
12232            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12233            if (categoriesIterator != null) {
12234                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12235                        categoriesIterator);
12236                if (intentListCopy.size() == 0) {
12237                    // no more intents to match; we're not equivalent
12238                    if (DEBUG_FILTERS) {
12239                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12240                                + " package: " + applicationInfo.packageName
12241                                + " activity: " + intent.activity.className
12242                                + " origPrio: " + intent.getPriority());
12243                    }
12244                    intent.setPriority(0);
12245                    return;
12246                }
12247            }
12248
12249            // find matching schemes subsets
12250            final Iterator<String> schemesIterator = intent.schemesIterator();
12251            if (schemesIterator != null) {
12252                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12253                        schemesIterator);
12254                if (intentListCopy.size() == 0) {
12255                    // no more intents to match; we're not equivalent
12256                    if (DEBUG_FILTERS) {
12257                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12258                                + " package: " + applicationInfo.packageName
12259                                + " activity: " + intent.activity.className
12260                                + " origPrio: " + intent.getPriority());
12261                    }
12262                    intent.setPriority(0);
12263                    return;
12264                }
12265            }
12266
12267            // find matching authorities subsets
12268            final Iterator<IntentFilter.AuthorityEntry>
12269                    authoritiesIterator = intent.authoritiesIterator();
12270            if (authoritiesIterator != null) {
12271                getIntentListSubset(intentListCopy,
12272                        new AuthoritiesIterGenerator(),
12273                        authoritiesIterator);
12274                if (intentListCopy.size() == 0) {
12275                    // no more intents to match; we're not equivalent
12276                    if (DEBUG_FILTERS) {
12277                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12278                                + " package: " + applicationInfo.packageName
12279                                + " activity: " + intent.activity.className
12280                                + " origPrio: " + intent.getPriority());
12281                    }
12282                    intent.setPriority(0);
12283                    return;
12284                }
12285            }
12286
12287            // we found matching filter(s); app gets the max priority of all intents
12288            int cappedPriority = 0;
12289            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12290                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12291            }
12292            if (intent.getPriority() > cappedPriority) {
12293                if (DEBUG_FILTERS) {
12294                    Slog.i(TAG, "Found matching filter(s);"
12295                            + " cap priority to " + cappedPriority + ";"
12296                            + " package: " + applicationInfo.packageName
12297                            + " activity: " + intent.activity.className
12298                            + " origPrio: " + intent.getPriority());
12299                }
12300                intent.setPriority(cappedPriority);
12301                return;
12302            }
12303            // all this for nothing; the requested priority was <= what was on the system
12304        }
12305
12306        public final void addActivity(PackageParser.Activity a, String type) {
12307            mActivities.put(a.getComponentName(), a);
12308            if (DEBUG_SHOW_INFO)
12309                Log.v(
12310                TAG, "  " + type + " " +
12311                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12312            if (DEBUG_SHOW_INFO)
12313                Log.v(TAG, "    Class=" + a.info.name);
12314            final int NI = a.intents.size();
12315            for (int j=0; j<NI; j++) {
12316                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12317                if ("activity".equals(type)) {
12318                    final PackageSetting ps =
12319                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12320                    final List<PackageParser.Activity> systemActivities =
12321                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12322                    adjustPriority(systemActivities, intent);
12323                }
12324                if (DEBUG_SHOW_INFO) {
12325                    Log.v(TAG, "    IntentFilter:");
12326                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12327                }
12328                if (!intent.debugCheck()) {
12329                    Log.w(TAG, "==> For Activity " + a.info.name);
12330                }
12331                addFilter(intent);
12332            }
12333        }
12334
12335        public final void removeActivity(PackageParser.Activity a, String type) {
12336            mActivities.remove(a.getComponentName());
12337            if (DEBUG_SHOW_INFO) {
12338                Log.v(TAG, "  " + type + " "
12339                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12340                                : a.info.name) + ":");
12341                Log.v(TAG, "    Class=" + a.info.name);
12342            }
12343            final int NI = a.intents.size();
12344            for (int j=0; j<NI; j++) {
12345                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12346                if (DEBUG_SHOW_INFO) {
12347                    Log.v(TAG, "    IntentFilter:");
12348                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12349                }
12350                removeFilter(intent);
12351            }
12352        }
12353
12354        @Override
12355        protected boolean allowFilterResult(
12356                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12357            ActivityInfo filterAi = filter.activity.info;
12358            for (int i=dest.size()-1; i>=0; i--) {
12359                ActivityInfo destAi = dest.get(i).activityInfo;
12360                if (destAi.name == filterAi.name
12361                        && destAi.packageName == filterAi.packageName) {
12362                    return false;
12363                }
12364            }
12365            return true;
12366        }
12367
12368        @Override
12369        protected ActivityIntentInfo[] newArray(int size) {
12370            return new ActivityIntentInfo[size];
12371        }
12372
12373        @Override
12374        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12375            if (!sUserManager.exists(userId)) return true;
12376            PackageParser.Package p = filter.activity.owner;
12377            if (p != null) {
12378                PackageSetting ps = (PackageSetting)p.mExtras;
12379                if (ps != null) {
12380                    // System apps are never considered stopped for purposes of
12381                    // filtering, because there may be no way for the user to
12382                    // actually re-launch them.
12383                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12384                            && ps.getStopped(userId);
12385                }
12386            }
12387            return false;
12388        }
12389
12390        @Override
12391        protected boolean isPackageForFilter(String packageName,
12392                PackageParser.ActivityIntentInfo info) {
12393            return packageName.equals(info.activity.owner.packageName);
12394        }
12395
12396        @Override
12397        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12398                int match, int userId) {
12399            if (!sUserManager.exists(userId)) return null;
12400            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12401                return null;
12402            }
12403            final PackageParser.Activity activity = info.activity;
12404            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12405            if (ps == null) {
12406                return null;
12407            }
12408            final PackageUserState userState = ps.readUserState(userId);
12409            ActivityInfo ai =
12410                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12411            if (ai == null) {
12412                return null;
12413            }
12414            final boolean matchExplicitlyVisibleOnly =
12415                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12416            final boolean matchVisibleToInstantApp =
12417                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12418            final boolean componentVisible =
12419                    matchVisibleToInstantApp
12420                    && info.isVisibleToInstantApp()
12421                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12422            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12423            // throw out filters that aren't visible to ephemeral apps
12424            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12425                return null;
12426            }
12427            // throw out instant app filters if we're not explicitly requesting them
12428            if (!matchInstantApp && userState.instantApp) {
12429                return null;
12430            }
12431            // throw out instant app filters if updates are available; will trigger
12432            // instant app resolution
12433            if (userState.instantApp && ps.isUpdateAvailable()) {
12434                return null;
12435            }
12436            final ResolveInfo res = new ResolveInfo();
12437            res.activityInfo = ai;
12438            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12439                res.filter = info;
12440            }
12441            if (info != null) {
12442                res.handleAllWebDataURI = info.handleAllWebDataURI();
12443            }
12444            res.priority = info.getPriority();
12445            res.preferredOrder = activity.owner.mPreferredOrder;
12446            //System.out.println("Result: " + res.activityInfo.className +
12447            //                   " = " + res.priority);
12448            res.match = match;
12449            res.isDefault = info.hasDefault;
12450            res.labelRes = info.labelRes;
12451            res.nonLocalizedLabel = info.nonLocalizedLabel;
12452            if (userNeedsBadging(userId)) {
12453                res.noResourceId = true;
12454            } else {
12455                res.icon = info.icon;
12456            }
12457            res.iconResourceId = info.icon;
12458            res.system = res.activityInfo.applicationInfo.isSystemApp();
12459            res.isInstantAppAvailable = userState.instantApp;
12460            return res;
12461        }
12462
12463        @Override
12464        protected void sortResults(List<ResolveInfo> results) {
12465            Collections.sort(results, mResolvePrioritySorter);
12466        }
12467
12468        @Override
12469        protected void dumpFilter(PrintWriter out, String prefix,
12470                PackageParser.ActivityIntentInfo filter) {
12471            out.print(prefix); out.print(
12472                    Integer.toHexString(System.identityHashCode(filter.activity)));
12473                    out.print(' ');
12474                    filter.activity.printComponentShortName(out);
12475                    out.print(" filter ");
12476                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12477        }
12478
12479        @Override
12480        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12481            return filter.activity;
12482        }
12483
12484        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12485            PackageParser.Activity activity = (PackageParser.Activity)label;
12486            out.print(prefix); out.print(
12487                    Integer.toHexString(System.identityHashCode(activity)));
12488                    out.print(' ');
12489                    activity.printComponentShortName(out);
12490            if (count > 1) {
12491                out.print(" ("); out.print(count); out.print(" filters)");
12492            }
12493            out.println();
12494        }
12495
12496        // Keys are String (activity class name), values are Activity.
12497        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12498                = new ArrayMap<ComponentName, PackageParser.Activity>();
12499        private int mFlags;
12500    }
12501
12502    private final class ServiceIntentResolver
12503            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12504        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12505                boolean defaultOnly, int userId) {
12506            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12507            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12508        }
12509
12510        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12511                int userId) {
12512            if (!sUserManager.exists(userId)) return null;
12513            mFlags = flags;
12514            return super.queryIntent(intent, resolvedType,
12515                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12516                    userId);
12517        }
12518
12519        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12520                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12521            if (!sUserManager.exists(userId)) return null;
12522            if (packageServices == null) {
12523                return null;
12524            }
12525            mFlags = flags;
12526            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12527            final int N = packageServices.size();
12528            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12529                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12530
12531            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12532            for (int i = 0; i < N; ++i) {
12533                intentFilters = packageServices.get(i).intents;
12534                if (intentFilters != null && intentFilters.size() > 0) {
12535                    PackageParser.ServiceIntentInfo[] array =
12536                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12537                    intentFilters.toArray(array);
12538                    listCut.add(array);
12539                }
12540            }
12541            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12542        }
12543
12544        public final void addService(PackageParser.Service s) {
12545            mServices.put(s.getComponentName(), s);
12546            if (DEBUG_SHOW_INFO) {
12547                Log.v(TAG, "  "
12548                        + (s.info.nonLocalizedLabel != null
12549                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12550                Log.v(TAG, "    Class=" + s.info.name);
12551            }
12552            final int NI = s.intents.size();
12553            int j;
12554            for (j=0; j<NI; j++) {
12555                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12556                if (DEBUG_SHOW_INFO) {
12557                    Log.v(TAG, "    IntentFilter:");
12558                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12559                }
12560                if (!intent.debugCheck()) {
12561                    Log.w(TAG, "==> For Service " + s.info.name);
12562                }
12563                addFilter(intent);
12564            }
12565        }
12566
12567        public final void removeService(PackageParser.Service s) {
12568            mServices.remove(s.getComponentName());
12569            if (DEBUG_SHOW_INFO) {
12570                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12571                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12572                Log.v(TAG, "    Class=" + s.info.name);
12573            }
12574            final int NI = s.intents.size();
12575            int j;
12576            for (j=0; j<NI; j++) {
12577                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12578                if (DEBUG_SHOW_INFO) {
12579                    Log.v(TAG, "    IntentFilter:");
12580                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12581                }
12582                removeFilter(intent);
12583            }
12584        }
12585
12586        @Override
12587        protected boolean allowFilterResult(
12588                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12589            ServiceInfo filterSi = filter.service.info;
12590            for (int i=dest.size()-1; i>=0; i--) {
12591                ServiceInfo destAi = dest.get(i).serviceInfo;
12592                if (destAi.name == filterSi.name
12593                        && destAi.packageName == filterSi.packageName) {
12594                    return false;
12595                }
12596            }
12597            return true;
12598        }
12599
12600        @Override
12601        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12602            return new PackageParser.ServiceIntentInfo[size];
12603        }
12604
12605        @Override
12606        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12607            if (!sUserManager.exists(userId)) return true;
12608            PackageParser.Package p = filter.service.owner;
12609            if (p != null) {
12610                PackageSetting ps = (PackageSetting)p.mExtras;
12611                if (ps != null) {
12612                    // System apps are never considered stopped for purposes of
12613                    // filtering, because there may be no way for the user to
12614                    // actually re-launch them.
12615                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12616                            && ps.getStopped(userId);
12617                }
12618            }
12619            return false;
12620        }
12621
12622        @Override
12623        protected boolean isPackageForFilter(String packageName,
12624                PackageParser.ServiceIntentInfo info) {
12625            return packageName.equals(info.service.owner.packageName);
12626        }
12627
12628        @Override
12629        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12630                int match, int userId) {
12631            if (!sUserManager.exists(userId)) return null;
12632            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12633            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12634                return null;
12635            }
12636            final PackageParser.Service service = info.service;
12637            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12638            if (ps == null) {
12639                return null;
12640            }
12641            final PackageUserState userState = ps.readUserState(userId);
12642            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12643                    userState, userId);
12644            if (si == null) {
12645                return null;
12646            }
12647            final boolean matchVisibleToInstantApp =
12648                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12649            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12650            // throw out filters that aren't visible to ephemeral apps
12651            if (matchVisibleToInstantApp
12652                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12653                return null;
12654            }
12655            // throw out ephemeral filters if we're not explicitly requesting them
12656            if (!isInstantApp && userState.instantApp) {
12657                return null;
12658            }
12659            // throw out instant app filters if updates are available; will trigger
12660            // instant app resolution
12661            if (userState.instantApp && ps.isUpdateAvailable()) {
12662                return null;
12663            }
12664            final ResolveInfo res = new ResolveInfo();
12665            res.serviceInfo = si;
12666            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12667                res.filter = filter;
12668            }
12669            res.priority = info.getPriority();
12670            res.preferredOrder = service.owner.mPreferredOrder;
12671            res.match = match;
12672            res.isDefault = info.hasDefault;
12673            res.labelRes = info.labelRes;
12674            res.nonLocalizedLabel = info.nonLocalizedLabel;
12675            res.icon = info.icon;
12676            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12677            return res;
12678        }
12679
12680        @Override
12681        protected void sortResults(List<ResolveInfo> results) {
12682            Collections.sort(results, mResolvePrioritySorter);
12683        }
12684
12685        @Override
12686        protected void dumpFilter(PrintWriter out, String prefix,
12687                PackageParser.ServiceIntentInfo filter) {
12688            out.print(prefix); out.print(
12689                    Integer.toHexString(System.identityHashCode(filter.service)));
12690                    out.print(' ');
12691                    filter.service.printComponentShortName(out);
12692                    out.print(" filter ");
12693                    out.print(Integer.toHexString(System.identityHashCode(filter)));
12694                    if (filter.service.info.permission != null) {
12695                        out.print(" permission "); out.println(filter.service.info.permission);
12696                    } else {
12697                        out.println();
12698                    }
12699        }
12700
12701        @Override
12702        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12703            return filter.service;
12704        }
12705
12706        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12707            PackageParser.Service service = (PackageParser.Service)label;
12708            out.print(prefix); out.print(
12709                    Integer.toHexString(System.identityHashCode(service)));
12710                    out.print(' ');
12711                    service.printComponentShortName(out);
12712            if (count > 1) {
12713                out.print(" ("); out.print(count); out.print(" filters)");
12714            }
12715            out.println();
12716        }
12717
12718//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12719//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12720//            final List<ResolveInfo> retList = Lists.newArrayList();
12721//            while (i.hasNext()) {
12722//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12723//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12724//                    retList.add(resolveInfo);
12725//                }
12726//            }
12727//            return retList;
12728//        }
12729
12730        // Keys are String (activity class name), values are Activity.
12731        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12732                = new ArrayMap<ComponentName, PackageParser.Service>();
12733        private int mFlags;
12734    }
12735
12736    private final class ProviderIntentResolver
12737            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12738        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12739                boolean defaultOnly, int userId) {
12740            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12741            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12742        }
12743
12744        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12745                int userId) {
12746            if (!sUserManager.exists(userId))
12747                return null;
12748            mFlags = flags;
12749            return super.queryIntent(intent, resolvedType,
12750                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12751                    userId);
12752        }
12753
12754        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12755                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12756            if (!sUserManager.exists(userId))
12757                return null;
12758            if (packageProviders == null) {
12759                return null;
12760            }
12761            mFlags = flags;
12762            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12763            final int N = packageProviders.size();
12764            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12765                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12766
12767            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12768            for (int i = 0; i < N; ++i) {
12769                intentFilters = packageProviders.get(i).intents;
12770                if (intentFilters != null && intentFilters.size() > 0) {
12771                    PackageParser.ProviderIntentInfo[] array =
12772                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12773                    intentFilters.toArray(array);
12774                    listCut.add(array);
12775                }
12776            }
12777            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12778        }
12779
12780        public final void addProvider(PackageParser.Provider p) {
12781            if (mProviders.containsKey(p.getComponentName())) {
12782                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12783                return;
12784            }
12785
12786            mProviders.put(p.getComponentName(), p);
12787            if (DEBUG_SHOW_INFO) {
12788                Log.v(TAG, "  "
12789                        + (p.info.nonLocalizedLabel != null
12790                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12791                Log.v(TAG, "    Class=" + p.info.name);
12792            }
12793            final int NI = p.intents.size();
12794            int j;
12795            for (j = 0; j < NI; j++) {
12796                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12797                if (DEBUG_SHOW_INFO) {
12798                    Log.v(TAG, "    IntentFilter:");
12799                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12800                }
12801                if (!intent.debugCheck()) {
12802                    Log.w(TAG, "==> For Provider " + p.info.name);
12803                }
12804                addFilter(intent);
12805            }
12806        }
12807
12808        public final void removeProvider(PackageParser.Provider p) {
12809            mProviders.remove(p.getComponentName());
12810            if (DEBUG_SHOW_INFO) {
12811                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12812                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12813                Log.v(TAG, "    Class=" + p.info.name);
12814            }
12815            final int NI = p.intents.size();
12816            int j;
12817            for (j = 0; j < NI; j++) {
12818                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12819                if (DEBUG_SHOW_INFO) {
12820                    Log.v(TAG, "    IntentFilter:");
12821                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12822                }
12823                removeFilter(intent);
12824            }
12825        }
12826
12827        @Override
12828        protected boolean allowFilterResult(
12829                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12830            ProviderInfo filterPi = filter.provider.info;
12831            for (int i = dest.size() - 1; i >= 0; i--) {
12832                ProviderInfo destPi = dest.get(i).providerInfo;
12833                if (destPi.name == filterPi.name
12834                        && destPi.packageName == filterPi.packageName) {
12835                    return false;
12836                }
12837            }
12838            return true;
12839        }
12840
12841        @Override
12842        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12843            return new PackageParser.ProviderIntentInfo[size];
12844        }
12845
12846        @Override
12847        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12848            if (!sUserManager.exists(userId))
12849                return true;
12850            PackageParser.Package p = filter.provider.owner;
12851            if (p != null) {
12852                PackageSetting ps = (PackageSetting) p.mExtras;
12853                if (ps != null) {
12854                    // System apps are never considered stopped for purposes of
12855                    // filtering, because there may be no way for the user to
12856                    // actually re-launch them.
12857                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12858                            && ps.getStopped(userId);
12859                }
12860            }
12861            return false;
12862        }
12863
12864        @Override
12865        protected boolean isPackageForFilter(String packageName,
12866                PackageParser.ProviderIntentInfo info) {
12867            return packageName.equals(info.provider.owner.packageName);
12868        }
12869
12870        @Override
12871        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12872                int match, int userId) {
12873            if (!sUserManager.exists(userId))
12874                return null;
12875            final PackageParser.ProviderIntentInfo info = filter;
12876            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12877                return null;
12878            }
12879            final PackageParser.Provider provider = info.provider;
12880            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12881            if (ps == null) {
12882                return null;
12883            }
12884            final PackageUserState userState = ps.readUserState(userId);
12885            final boolean matchVisibleToInstantApp =
12886                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12887            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12888            // throw out filters that aren't visible to instant applications
12889            if (matchVisibleToInstantApp
12890                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12891                return null;
12892            }
12893            // throw out instant application filters if we're not explicitly requesting them
12894            if (!isInstantApp && userState.instantApp) {
12895                return null;
12896            }
12897            // throw out instant application filters if updates are available; will trigger
12898            // instant application resolution
12899            if (userState.instantApp && ps.isUpdateAvailable()) {
12900                return null;
12901            }
12902            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12903                    userState, userId);
12904            if (pi == null) {
12905                return null;
12906            }
12907            final ResolveInfo res = new ResolveInfo();
12908            res.providerInfo = pi;
12909            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12910                res.filter = filter;
12911            }
12912            res.priority = info.getPriority();
12913            res.preferredOrder = provider.owner.mPreferredOrder;
12914            res.match = match;
12915            res.isDefault = info.hasDefault;
12916            res.labelRes = info.labelRes;
12917            res.nonLocalizedLabel = info.nonLocalizedLabel;
12918            res.icon = info.icon;
12919            res.system = res.providerInfo.applicationInfo.isSystemApp();
12920            return res;
12921        }
12922
12923        @Override
12924        protected void sortResults(List<ResolveInfo> results) {
12925            Collections.sort(results, mResolvePrioritySorter);
12926        }
12927
12928        @Override
12929        protected void dumpFilter(PrintWriter out, String prefix,
12930                PackageParser.ProviderIntentInfo filter) {
12931            out.print(prefix);
12932            out.print(
12933                    Integer.toHexString(System.identityHashCode(filter.provider)));
12934            out.print(' ');
12935            filter.provider.printComponentShortName(out);
12936            out.print(" filter ");
12937            out.println(Integer.toHexString(System.identityHashCode(filter)));
12938        }
12939
12940        @Override
12941        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12942            return filter.provider;
12943        }
12944
12945        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12946            PackageParser.Provider provider = (PackageParser.Provider)label;
12947            out.print(prefix); out.print(
12948                    Integer.toHexString(System.identityHashCode(provider)));
12949                    out.print(' ');
12950                    provider.printComponentShortName(out);
12951            if (count > 1) {
12952                out.print(" ("); out.print(count); out.print(" filters)");
12953            }
12954            out.println();
12955        }
12956
12957        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12958                = new ArrayMap<ComponentName, PackageParser.Provider>();
12959        private int mFlags;
12960    }
12961
12962    static final class EphemeralIntentResolver
12963            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12964        /**
12965         * The result that has the highest defined order. Ordering applies on a
12966         * per-package basis. Mapping is from package name to Pair of order and
12967         * EphemeralResolveInfo.
12968         * <p>
12969         * NOTE: This is implemented as a field variable for convenience and efficiency.
12970         * By having a field variable, we're able to track filter ordering as soon as
12971         * a non-zero order is defined. Otherwise, multiple loops across the result set
12972         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12973         * this needs to be contained entirely within {@link #filterResults}.
12974         */
12975        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12976
12977        @Override
12978        protected AuxiliaryResolveInfo[] newArray(int size) {
12979            return new AuxiliaryResolveInfo[size];
12980        }
12981
12982        @Override
12983        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12984            return true;
12985        }
12986
12987        @Override
12988        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12989                int userId) {
12990            if (!sUserManager.exists(userId)) {
12991                return null;
12992            }
12993            final String packageName = responseObj.resolveInfo.getPackageName();
12994            final Integer order = responseObj.getOrder();
12995            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12996                    mOrderResult.get(packageName);
12997            // ordering is enabled and this item's order isn't high enough
12998            if (lastOrderResult != null && lastOrderResult.first >= order) {
12999                return null;
13000            }
13001            final InstantAppResolveInfo res = responseObj.resolveInfo;
13002            if (order > 0) {
13003                // non-zero order, enable ordering
13004                mOrderResult.put(packageName, new Pair<>(order, res));
13005            }
13006            return responseObj;
13007        }
13008
13009        @Override
13010        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13011            // only do work if ordering is enabled [most of the time it won't be]
13012            if (mOrderResult.size() == 0) {
13013                return;
13014            }
13015            int resultSize = results.size();
13016            for (int i = 0; i < resultSize; i++) {
13017                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13018                final String packageName = info.getPackageName();
13019                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13020                if (savedInfo == null) {
13021                    // package doesn't having ordering
13022                    continue;
13023                }
13024                if (savedInfo.second == info) {
13025                    // circled back to the highest ordered item; remove from order list
13026                    mOrderResult.remove(packageName);
13027                    if (mOrderResult.size() == 0) {
13028                        // no more ordered items
13029                        break;
13030                    }
13031                    continue;
13032                }
13033                // item has a worse order, remove it from the result list
13034                results.remove(i);
13035                resultSize--;
13036                i--;
13037            }
13038        }
13039    }
13040
13041    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13042            new Comparator<ResolveInfo>() {
13043        public int compare(ResolveInfo r1, ResolveInfo r2) {
13044            int v1 = r1.priority;
13045            int v2 = r2.priority;
13046            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13047            if (v1 != v2) {
13048                return (v1 > v2) ? -1 : 1;
13049            }
13050            v1 = r1.preferredOrder;
13051            v2 = r2.preferredOrder;
13052            if (v1 != v2) {
13053                return (v1 > v2) ? -1 : 1;
13054            }
13055            if (r1.isDefault != r2.isDefault) {
13056                return r1.isDefault ? -1 : 1;
13057            }
13058            v1 = r1.match;
13059            v2 = r2.match;
13060            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13061            if (v1 != v2) {
13062                return (v1 > v2) ? -1 : 1;
13063            }
13064            if (r1.system != r2.system) {
13065                return r1.system ? -1 : 1;
13066            }
13067            if (r1.activityInfo != null) {
13068                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13069            }
13070            if (r1.serviceInfo != null) {
13071                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13072            }
13073            if (r1.providerInfo != null) {
13074                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13075            }
13076            return 0;
13077        }
13078    };
13079
13080    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13081            new Comparator<ProviderInfo>() {
13082        public int compare(ProviderInfo p1, ProviderInfo p2) {
13083            final int v1 = p1.initOrder;
13084            final int v2 = p2.initOrder;
13085            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13086        }
13087    };
13088
13089    @Override
13090    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13091            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13092            final int[] userIds, int[] instantUserIds) {
13093        mHandler.post(new Runnable() {
13094            @Override
13095            public void run() {
13096                try {
13097                    final IActivityManager am = ActivityManager.getService();
13098                    if (am == null) return;
13099                    final int[] resolvedUserIds;
13100                    if (userIds == null) {
13101                        resolvedUserIds = am.getRunningUserIds();
13102                    } else {
13103                        resolvedUserIds = userIds;
13104                    }
13105                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13106                            resolvedUserIds, false);
13107                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13108                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13109                                instantUserIds, true);
13110                    }
13111                } catch (RemoteException ex) {
13112                }
13113            }
13114        });
13115    }
13116
13117    @Override
13118    public void notifyPackageAdded(String packageName) {
13119        final PackageListObserver[] observers;
13120        synchronized (mPackages) {
13121            if (mPackageListObservers.size() == 0) {
13122                return;
13123            }
13124            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13125        }
13126        for (int i = observers.length - 1; i >= 0; --i) {
13127            observers[i].onPackageAdded(packageName);
13128        }
13129    }
13130
13131    @Override
13132    public void notifyPackageRemoved(String packageName) {
13133        final PackageListObserver[] observers;
13134        synchronized (mPackages) {
13135            if (mPackageListObservers.size() == 0) {
13136                return;
13137            }
13138            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13139        }
13140        for (int i = observers.length - 1; i >= 0; --i) {
13141            observers[i].onPackageRemoved(packageName);
13142        }
13143    }
13144
13145    /**
13146     * Sends a broadcast for the given action.
13147     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13148     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13149     * the system and applications allowed to see instant applications to receive package
13150     * lifecycle events for instant applications.
13151     */
13152    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13153            int flags, String targetPkg, IIntentReceiver finishedReceiver,
13154            int[] userIds, boolean isInstantApp)
13155                    throws RemoteException {
13156        for (int id : userIds) {
13157            final Intent intent = new Intent(action,
13158                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13159            final String[] requiredPermissions =
13160                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13161            if (extras != null) {
13162                intent.putExtras(extras);
13163            }
13164            if (targetPkg != null) {
13165                intent.setPackage(targetPkg);
13166            }
13167            // Modify the UID when posting to other users
13168            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13169            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13170                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13171                intent.putExtra(Intent.EXTRA_UID, uid);
13172            }
13173            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13174            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13175            if (DEBUG_BROADCASTS) {
13176                RuntimeException here = new RuntimeException("here");
13177                here.fillInStackTrace();
13178                Slog.d(TAG, "Sending to user " + id + ": "
13179                        + intent.toShortString(false, true, false, false)
13180                        + " " + intent.getExtras(), here);
13181            }
13182            am.broadcastIntent(null, intent, null, finishedReceiver,
13183                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13184                    null, finishedReceiver != null, false, id);
13185        }
13186    }
13187
13188    /**
13189     * Check if the external storage media is available. This is true if there
13190     * is a mounted external storage medium or if the external storage is
13191     * emulated.
13192     */
13193    private boolean isExternalMediaAvailable() {
13194        return mMediaMounted || Environment.isExternalStorageEmulated();
13195    }
13196
13197    @Override
13198    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13199        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13200            return null;
13201        }
13202        if (!isExternalMediaAvailable()) {
13203                // If the external storage is no longer mounted at this point,
13204                // the caller may not have been able to delete all of this
13205                // packages files and can not delete any more.  Bail.
13206            return null;
13207        }
13208        synchronized (mPackages) {
13209            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13210            if (lastPackage != null) {
13211                pkgs.remove(lastPackage);
13212            }
13213            if (pkgs.size() > 0) {
13214                return pkgs.get(0);
13215            }
13216        }
13217        return null;
13218    }
13219
13220    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13221        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13222                userId, andCode ? 1 : 0, packageName);
13223        if (mSystemReady) {
13224            msg.sendToTarget();
13225        } else {
13226            if (mPostSystemReadyMessages == null) {
13227                mPostSystemReadyMessages = new ArrayList<>();
13228            }
13229            mPostSystemReadyMessages.add(msg);
13230        }
13231    }
13232
13233    void startCleaningPackages() {
13234        // reader
13235        if (!isExternalMediaAvailable()) {
13236            return;
13237        }
13238        synchronized (mPackages) {
13239            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13240                return;
13241            }
13242        }
13243        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13244        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13245        IActivityManager am = ActivityManager.getService();
13246        if (am != null) {
13247            int dcsUid = -1;
13248            synchronized (mPackages) {
13249                if (!mDefaultContainerWhitelisted) {
13250                    mDefaultContainerWhitelisted = true;
13251                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13252                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13253                }
13254            }
13255            try {
13256                if (dcsUid > 0) {
13257                    am.backgroundWhitelistUid(dcsUid);
13258                }
13259                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13260                        UserHandle.USER_SYSTEM);
13261            } catch (RemoteException e) {
13262            }
13263        }
13264    }
13265
13266    /**
13267     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13268     * it is acting on behalf on an enterprise or the user).
13269     *
13270     * Note that the ordering of the conditionals in this method is important. The checks we perform
13271     * are as follows, in this order:
13272     *
13273     * 1) If the install is being performed by a system app, we can trust the app to have set the
13274     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13275     *    what it is.
13276     * 2) If the install is being performed by a device or profile owner app, the install reason
13277     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13278     *    set the install reason correctly. If the app targets an older SDK version where install
13279     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13280     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13281     * 3) In all other cases, the install is being performed by a regular app that is neither part
13282     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13283     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13284     *    set to enterprise policy and if so, change it to unknown instead.
13285     */
13286    private int fixUpInstallReason(String installerPackageName, int installerUid,
13287            int installReason) {
13288        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13289                == PERMISSION_GRANTED) {
13290            // If the install is being performed by a system app, we trust that app to have set the
13291            // install reason correctly.
13292            return installReason;
13293        }
13294
13295        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13296            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13297        if (dpm != null) {
13298            ComponentName owner = null;
13299            try {
13300                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13301                if (owner == null) {
13302                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13303                }
13304            } catch (RemoteException e) {
13305            }
13306            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13307                // If the install is being performed by a device or profile owner, the install
13308                // reason should be enterprise policy.
13309                return PackageManager.INSTALL_REASON_POLICY;
13310            }
13311        }
13312
13313        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13314            // If the install is being performed by a regular app (i.e. neither system app nor
13315            // device or profile owner), we have no reason to believe that the app is acting on
13316            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13317            // change it to unknown instead.
13318            return PackageManager.INSTALL_REASON_UNKNOWN;
13319        }
13320
13321        // If the install is being performed by a regular app and the install reason was set to any
13322        // value but enterprise policy, leave the install reason unchanged.
13323        return installReason;
13324    }
13325
13326    void installStage(String packageName, File stagedDir,
13327            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13328            String installerPackageName, int installerUid, UserHandle user,
13329            PackageParser.SigningDetails signingDetails) {
13330        if (DEBUG_EPHEMERAL) {
13331            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13332                Slog.d(TAG, "Ephemeral install of " + packageName);
13333            }
13334        }
13335        final VerificationInfo verificationInfo = new VerificationInfo(
13336                sessionParams.originatingUri, sessionParams.referrerUri,
13337                sessionParams.originatingUid, installerUid);
13338
13339        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13340
13341        final Message msg = mHandler.obtainMessage(INIT_COPY);
13342        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13343                sessionParams.installReason);
13344        final InstallParams params = new InstallParams(origin, null, observer,
13345                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13346                verificationInfo, user, sessionParams.abiOverride,
13347                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13348        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13349        msg.obj = params;
13350
13351        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13352                System.identityHashCode(msg.obj));
13353        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13354                System.identityHashCode(msg.obj));
13355
13356        mHandler.sendMessage(msg);
13357    }
13358
13359    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13360            int userId) {
13361        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13362        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13363        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13364        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13365        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13366                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13367
13368        // Send a session commit broadcast
13369        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13370        info.installReason = pkgSetting.getInstallReason(userId);
13371        info.appPackageName = packageName;
13372        sendSessionCommitBroadcast(info, userId);
13373    }
13374
13375    @Override
13376    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13377            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13378        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13379            return;
13380        }
13381        Bundle extras = new Bundle(1);
13382        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13383        final int uid = UserHandle.getUid(
13384                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13385        extras.putInt(Intent.EXTRA_UID, uid);
13386
13387        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13388                packageName, extras, 0, null, null, userIds, instantUserIds);
13389        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13390            mHandler.post(() -> {
13391                        for (int userId : userIds) {
13392                            sendBootCompletedBroadcastToSystemApp(
13393                                    packageName, includeStopped, userId);
13394                        }
13395                    }
13396            );
13397        }
13398    }
13399
13400    /**
13401     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13402     * automatically without needing an explicit launch.
13403     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13404     */
13405    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13406            int userId) {
13407        // If user is not running, the app didn't miss any broadcast
13408        if (!mUserManagerInternal.isUserRunning(userId)) {
13409            return;
13410        }
13411        final IActivityManager am = ActivityManager.getService();
13412        try {
13413            // Deliver LOCKED_BOOT_COMPLETED first
13414            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13415                    .setPackage(packageName);
13416            if (includeStopped) {
13417                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13418            }
13419            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13420            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13421                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13422
13423            // Deliver BOOT_COMPLETED only if user is unlocked
13424            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13425                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13426                if (includeStopped) {
13427                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13428                }
13429                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13430                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13431            }
13432        } catch (RemoteException e) {
13433            throw e.rethrowFromSystemServer();
13434        }
13435    }
13436
13437    @Override
13438    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13439            int userId) {
13440        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13441        PackageSetting pkgSetting;
13442        final int callingUid = Binder.getCallingUid();
13443        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13444                true /* requireFullPermission */, true /* checkShell */,
13445                "setApplicationHiddenSetting for user " + userId);
13446
13447        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13448            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13449            return false;
13450        }
13451
13452        long callingId = Binder.clearCallingIdentity();
13453        try {
13454            boolean sendAdded = false;
13455            boolean sendRemoved = false;
13456            // writer
13457            synchronized (mPackages) {
13458                pkgSetting = mSettings.mPackages.get(packageName);
13459                if (pkgSetting == null) {
13460                    return false;
13461                }
13462                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13463                    return false;
13464                }
13465                // Do not allow "android" is being disabled
13466                if ("android".equals(packageName)) {
13467                    Slog.w(TAG, "Cannot hide package: android");
13468                    return false;
13469                }
13470                // Cannot hide static shared libs as they are considered
13471                // a part of the using app (emulating static linking). Also
13472                // static libs are installed always on internal storage.
13473                PackageParser.Package pkg = mPackages.get(packageName);
13474                if (pkg != null && pkg.staticSharedLibName != null) {
13475                    Slog.w(TAG, "Cannot hide package: " + packageName
13476                            + " providing static shared library: "
13477                            + pkg.staticSharedLibName);
13478                    return false;
13479                }
13480                // Only allow protected packages to hide themselves.
13481                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13482                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13483                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13484                    return false;
13485                }
13486
13487                if (pkgSetting.getHidden(userId) != hidden) {
13488                    pkgSetting.setHidden(hidden, userId);
13489                    mSettings.writePackageRestrictionsLPr(userId);
13490                    if (hidden) {
13491                        sendRemoved = true;
13492                    } else {
13493                        sendAdded = true;
13494                    }
13495                }
13496            }
13497            if (sendAdded) {
13498                sendPackageAddedForUser(packageName, pkgSetting, userId);
13499                return true;
13500            }
13501            if (sendRemoved) {
13502                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13503                        "hiding pkg");
13504                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13505                return true;
13506            }
13507        } finally {
13508            Binder.restoreCallingIdentity(callingId);
13509        }
13510        return false;
13511    }
13512
13513    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13514            int userId) {
13515        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13516        info.removedPackage = packageName;
13517        info.installerPackageName = pkgSetting.installerPackageName;
13518        info.removedUsers = new int[] {userId};
13519        info.broadcastUsers = new int[] {userId};
13520        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13521        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13522    }
13523
13524    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13525        if (pkgList.length > 0) {
13526            Bundle extras = new Bundle(1);
13527            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13528
13529            sendPackageBroadcast(
13530                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13531                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13532                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13533                    new int[] {userId}, null);
13534        }
13535    }
13536
13537    /**
13538     * Returns true if application is not found or there was an error. Otherwise it returns
13539     * the hidden state of the package for the given user.
13540     */
13541    @Override
13542    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13543        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13544        final int callingUid = Binder.getCallingUid();
13545        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13546                true /* requireFullPermission */, false /* checkShell */,
13547                "getApplicationHidden for user " + userId);
13548        PackageSetting ps;
13549        long callingId = Binder.clearCallingIdentity();
13550        try {
13551            // writer
13552            synchronized (mPackages) {
13553                ps = mSettings.mPackages.get(packageName);
13554                if (ps == null) {
13555                    return true;
13556                }
13557                if (filterAppAccessLPr(ps, callingUid, userId)) {
13558                    return true;
13559                }
13560                return ps.getHidden(userId);
13561            }
13562        } finally {
13563            Binder.restoreCallingIdentity(callingId);
13564        }
13565    }
13566
13567    /**
13568     * @hide
13569     */
13570    @Override
13571    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13572            int installReason) {
13573        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13574                null);
13575        PackageSetting pkgSetting;
13576        final int callingUid = Binder.getCallingUid();
13577        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13578                true /* requireFullPermission */, true /* checkShell */,
13579                "installExistingPackage for user " + userId);
13580        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13581            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13582        }
13583
13584        long callingId = Binder.clearCallingIdentity();
13585        try {
13586            boolean installed = false;
13587            final boolean instantApp =
13588                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13589            final boolean fullApp =
13590                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13591
13592            // writer
13593            synchronized (mPackages) {
13594                pkgSetting = mSettings.mPackages.get(packageName);
13595                if (pkgSetting == null) {
13596                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13597                }
13598                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13599                    // only allow the existing package to be used if it's installed as a full
13600                    // application for at least one user
13601                    boolean installAllowed = false;
13602                    for (int checkUserId : sUserManager.getUserIds()) {
13603                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13604                        if (installAllowed) {
13605                            break;
13606                        }
13607                    }
13608                    if (!installAllowed) {
13609                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13610                    }
13611                }
13612                if (!pkgSetting.getInstalled(userId)) {
13613                    pkgSetting.setInstalled(true, userId);
13614                    pkgSetting.setHidden(false, userId);
13615                    pkgSetting.setInstallReason(installReason, userId);
13616                    mSettings.writePackageRestrictionsLPr(userId);
13617                    mSettings.writeKernelMappingLPr(pkgSetting);
13618                    installed = true;
13619                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13620                    // upgrade app from instant to full; we don't allow app downgrade
13621                    installed = true;
13622                }
13623                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13624            }
13625
13626            if (installed) {
13627                if (pkgSetting.pkg != null) {
13628                    synchronized (mInstallLock) {
13629                        // We don't need to freeze for a brand new install
13630                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13631                    }
13632                }
13633                sendPackageAddedForUser(packageName, pkgSetting, userId);
13634                synchronized (mPackages) {
13635                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13636                }
13637            }
13638        } finally {
13639            Binder.restoreCallingIdentity(callingId);
13640        }
13641
13642        return PackageManager.INSTALL_SUCCEEDED;
13643    }
13644
13645    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13646            boolean instantApp, boolean fullApp) {
13647        // no state specified; do nothing
13648        if (!instantApp && !fullApp) {
13649            return;
13650        }
13651        if (userId != UserHandle.USER_ALL) {
13652            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13653                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13654            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13655                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13656            }
13657        } else {
13658            for (int currentUserId : sUserManager.getUserIds()) {
13659                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13660                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13661                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13662                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13663                }
13664            }
13665        }
13666    }
13667
13668    boolean isUserRestricted(int userId, String restrictionKey) {
13669        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13670        if (restrictions.getBoolean(restrictionKey, false)) {
13671            Log.w(TAG, "User is restricted: " + restrictionKey);
13672            return true;
13673        }
13674        return false;
13675    }
13676
13677    @Override
13678    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13679            int userId) {
13680        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13681        final int callingUid = Binder.getCallingUid();
13682        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13683                true /* requireFullPermission */, true /* checkShell */,
13684                "setPackagesSuspended for user " + userId);
13685
13686        if (ArrayUtils.isEmpty(packageNames)) {
13687            return packageNames;
13688        }
13689
13690        // List of package names for whom the suspended state has changed.
13691        List<String> changedPackages = new ArrayList<>(packageNames.length);
13692        // List of package names for whom the suspended state is not set as requested in this
13693        // method.
13694        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13695        long callingId = Binder.clearCallingIdentity();
13696        try {
13697            for (int i = 0; i < packageNames.length; i++) {
13698                String packageName = packageNames[i];
13699                boolean changed = false;
13700                final int appId;
13701                synchronized (mPackages) {
13702                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13703                    if (pkgSetting == null
13704                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13705                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13706                                + "\". Skipping suspending/un-suspending.");
13707                        unactionedPackages.add(packageName);
13708                        continue;
13709                    }
13710                    appId = pkgSetting.appId;
13711                    if (pkgSetting.getSuspended(userId) != suspended) {
13712                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13713                            unactionedPackages.add(packageName);
13714                            continue;
13715                        }
13716                        pkgSetting.setSuspended(suspended, userId);
13717                        mSettings.writePackageRestrictionsLPr(userId);
13718                        changed = true;
13719                        changedPackages.add(packageName);
13720                    }
13721                }
13722
13723                if (changed && suspended) {
13724                    killApplication(packageName, UserHandle.getUid(userId, appId),
13725                            "suspending package");
13726                }
13727            }
13728        } finally {
13729            Binder.restoreCallingIdentity(callingId);
13730        }
13731
13732        if (!changedPackages.isEmpty()) {
13733            sendPackagesSuspendedForUser(changedPackages.toArray(
13734                    new String[changedPackages.size()]), userId, suspended);
13735        }
13736
13737        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13738    }
13739
13740    @Override
13741    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13742        final int callingUid = Binder.getCallingUid();
13743        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13744                true /* requireFullPermission */, false /* checkShell */,
13745                "isPackageSuspendedForUser for user " + userId);
13746        synchronized (mPackages) {
13747            final PackageSetting ps = mSettings.mPackages.get(packageName);
13748            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13749                throw new IllegalArgumentException("Unknown target package: " + packageName);
13750            }
13751            return ps.getSuspended(userId);
13752        }
13753    }
13754
13755    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13756        if (isPackageDeviceAdmin(packageName, userId)) {
13757            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13758                    + "\": has an active device admin");
13759            return false;
13760        }
13761
13762        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13763        if (packageName.equals(activeLauncherPackageName)) {
13764            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13765                    + "\": contains the active launcher");
13766            return false;
13767        }
13768
13769        if (packageName.equals(mRequiredInstallerPackage)) {
13770            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13771                    + "\": required for package installation");
13772            return false;
13773        }
13774
13775        if (packageName.equals(mRequiredUninstallerPackage)) {
13776            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13777                    + "\": required for package uninstallation");
13778            return false;
13779        }
13780
13781        if (packageName.equals(mRequiredVerifierPackage)) {
13782            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13783                    + "\": required for package verification");
13784            return false;
13785        }
13786
13787        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13788            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13789                    + "\": is the default dialer");
13790            return false;
13791        }
13792
13793        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13794            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13795                    + "\": protected package");
13796            return false;
13797        }
13798
13799        // Cannot suspend static shared libs as they are considered
13800        // a part of the using app (emulating static linking). Also
13801        // static libs are installed always on internal storage.
13802        PackageParser.Package pkg = mPackages.get(packageName);
13803        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13804            Slog.w(TAG, "Cannot suspend package: " + packageName
13805                    + " providing static shared library: "
13806                    + pkg.staticSharedLibName);
13807            return false;
13808        }
13809
13810        return true;
13811    }
13812
13813    private String getActiveLauncherPackageName(int userId) {
13814        Intent intent = new Intent(Intent.ACTION_MAIN);
13815        intent.addCategory(Intent.CATEGORY_HOME);
13816        ResolveInfo resolveInfo = resolveIntent(
13817                intent,
13818                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13819                PackageManager.MATCH_DEFAULT_ONLY,
13820                userId);
13821
13822        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13823    }
13824
13825    private String getDefaultDialerPackageName(int userId) {
13826        synchronized (mPackages) {
13827            return mSettings.getDefaultDialerPackageNameLPw(userId);
13828        }
13829    }
13830
13831    @Override
13832    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13833        mContext.enforceCallingOrSelfPermission(
13834                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13835                "Only package verification agents can verify applications");
13836
13837        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13838        final PackageVerificationResponse response = new PackageVerificationResponse(
13839                verificationCode, Binder.getCallingUid());
13840        msg.arg1 = id;
13841        msg.obj = response;
13842        mHandler.sendMessage(msg);
13843    }
13844
13845    @Override
13846    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13847            long millisecondsToDelay) {
13848        mContext.enforceCallingOrSelfPermission(
13849                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13850                "Only package verification agents can extend verification timeouts");
13851
13852        final PackageVerificationState state = mPendingVerification.get(id);
13853        final PackageVerificationResponse response = new PackageVerificationResponse(
13854                verificationCodeAtTimeout, Binder.getCallingUid());
13855
13856        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13857            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13858        }
13859        if (millisecondsToDelay < 0) {
13860            millisecondsToDelay = 0;
13861        }
13862        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13863                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13864            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13865        }
13866
13867        if ((state != null) && !state.timeoutExtended()) {
13868            state.extendTimeout();
13869
13870            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13871            msg.arg1 = id;
13872            msg.obj = response;
13873            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13874        }
13875    }
13876
13877    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13878            int verificationCode, UserHandle user) {
13879        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13880        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13881        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13882        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13883        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13884
13885        mContext.sendBroadcastAsUser(intent, user,
13886                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13887    }
13888
13889    private ComponentName matchComponentForVerifier(String packageName,
13890            List<ResolveInfo> receivers) {
13891        ActivityInfo targetReceiver = null;
13892
13893        final int NR = receivers.size();
13894        for (int i = 0; i < NR; i++) {
13895            final ResolveInfo info = receivers.get(i);
13896            if (info.activityInfo == null) {
13897                continue;
13898            }
13899
13900            if (packageName.equals(info.activityInfo.packageName)) {
13901                targetReceiver = info.activityInfo;
13902                break;
13903            }
13904        }
13905
13906        if (targetReceiver == null) {
13907            return null;
13908        }
13909
13910        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13911    }
13912
13913    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13914            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13915        if (pkgInfo.verifiers.length == 0) {
13916            return null;
13917        }
13918
13919        final int N = pkgInfo.verifiers.length;
13920        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13921        for (int i = 0; i < N; i++) {
13922            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13923
13924            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13925                    receivers);
13926            if (comp == null) {
13927                continue;
13928            }
13929
13930            final int verifierUid = getUidForVerifier(verifierInfo);
13931            if (verifierUid == -1) {
13932                continue;
13933            }
13934
13935            if (DEBUG_VERIFY) {
13936                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13937                        + " with the correct signature");
13938            }
13939            sufficientVerifiers.add(comp);
13940            verificationState.addSufficientVerifier(verifierUid);
13941        }
13942
13943        return sufficientVerifiers;
13944    }
13945
13946    private int getUidForVerifier(VerifierInfo verifierInfo) {
13947        synchronized (mPackages) {
13948            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13949            if (pkg == null) {
13950                return -1;
13951            } else if (pkg.mSigningDetails.signatures.length != 1) {
13952                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13953                        + " has more than one signature; ignoring");
13954                return -1;
13955            }
13956
13957            /*
13958             * If the public key of the package's signature does not match
13959             * our expected public key, then this is a different package and
13960             * we should skip.
13961             */
13962
13963            final byte[] expectedPublicKey;
13964            try {
13965                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
13966                final PublicKey publicKey = verifierSig.getPublicKey();
13967                expectedPublicKey = publicKey.getEncoded();
13968            } catch (CertificateException e) {
13969                return -1;
13970            }
13971
13972            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13973
13974            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13975                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13976                        + " does not have the expected public key; ignoring");
13977                return -1;
13978            }
13979
13980            return pkg.applicationInfo.uid;
13981        }
13982    }
13983
13984    @Override
13985    public void finishPackageInstall(int token, boolean didLaunch) {
13986        enforceSystemOrRoot("Only the system is allowed to finish installs");
13987
13988        if (DEBUG_INSTALL) {
13989            Slog.v(TAG, "BM finishing package install for " + token);
13990        }
13991        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13992
13993        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13994        mHandler.sendMessage(msg);
13995    }
13996
13997    /**
13998     * Get the verification agent timeout.  Used for both the APK verifier and the
13999     * intent filter verifier.
14000     *
14001     * @return verification timeout in milliseconds
14002     */
14003    private long getVerificationTimeout() {
14004        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14005                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14006                DEFAULT_VERIFICATION_TIMEOUT);
14007    }
14008
14009    /**
14010     * Get the default verification agent response code.
14011     *
14012     * @return default verification response code
14013     */
14014    private int getDefaultVerificationResponse(UserHandle user) {
14015        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14016            return PackageManager.VERIFICATION_REJECT;
14017        }
14018        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14019                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14020                DEFAULT_VERIFICATION_RESPONSE);
14021    }
14022
14023    /**
14024     * Check whether or not package verification has been enabled.
14025     *
14026     * @return true if verification should be performed
14027     */
14028    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14029        if (!DEFAULT_VERIFY_ENABLE) {
14030            return false;
14031        }
14032
14033        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14034
14035        // Check if installing from ADB
14036        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14037            // Do not run verification in a test harness environment
14038            if (ActivityManager.isRunningInTestHarness()) {
14039                return false;
14040            }
14041            if (ensureVerifyAppsEnabled) {
14042                return true;
14043            }
14044            // Check if the developer does not want package verification for ADB installs
14045            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14046                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14047                return false;
14048            }
14049        } else {
14050            // only when not installed from ADB, skip verification for instant apps when
14051            // the installer and verifier are the same.
14052            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14053                if (mInstantAppInstallerActivity != null
14054                        && mInstantAppInstallerActivity.packageName.equals(
14055                                mRequiredVerifierPackage)) {
14056                    try {
14057                        mContext.getSystemService(AppOpsManager.class)
14058                                .checkPackage(installerUid, mRequiredVerifierPackage);
14059                        if (DEBUG_VERIFY) {
14060                            Slog.i(TAG, "disable verification for instant app");
14061                        }
14062                        return false;
14063                    } catch (SecurityException ignore) { }
14064                }
14065            }
14066        }
14067
14068        if (ensureVerifyAppsEnabled) {
14069            return true;
14070        }
14071
14072        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14073                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14074    }
14075
14076    @Override
14077    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14078            throws RemoteException {
14079        mContext.enforceCallingOrSelfPermission(
14080                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14081                "Only intentfilter verification agents can verify applications");
14082
14083        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14084        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14085                Binder.getCallingUid(), verificationCode, failedDomains);
14086        msg.arg1 = id;
14087        msg.obj = response;
14088        mHandler.sendMessage(msg);
14089    }
14090
14091    @Override
14092    public int getIntentVerificationStatus(String packageName, int userId) {
14093        final int callingUid = Binder.getCallingUid();
14094        if (UserHandle.getUserId(callingUid) != userId) {
14095            mContext.enforceCallingOrSelfPermission(
14096                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14097                    "getIntentVerificationStatus" + userId);
14098        }
14099        if (getInstantAppPackageName(callingUid) != null) {
14100            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14101        }
14102        synchronized (mPackages) {
14103            final PackageSetting ps = mSettings.mPackages.get(packageName);
14104            if (ps == null
14105                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14106                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14107            }
14108            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14109        }
14110    }
14111
14112    @Override
14113    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14114        mContext.enforceCallingOrSelfPermission(
14115                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14116
14117        boolean result = false;
14118        synchronized (mPackages) {
14119            final PackageSetting ps = mSettings.mPackages.get(packageName);
14120            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14121                return false;
14122            }
14123            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14124        }
14125        if (result) {
14126            scheduleWritePackageRestrictionsLocked(userId);
14127        }
14128        return result;
14129    }
14130
14131    @Override
14132    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14133            String packageName) {
14134        final int callingUid = Binder.getCallingUid();
14135        if (getInstantAppPackageName(callingUid) != null) {
14136            return ParceledListSlice.emptyList();
14137        }
14138        synchronized (mPackages) {
14139            final PackageSetting ps = mSettings.mPackages.get(packageName);
14140            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14141                return ParceledListSlice.emptyList();
14142            }
14143            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14144        }
14145    }
14146
14147    @Override
14148    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14149        if (TextUtils.isEmpty(packageName)) {
14150            return ParceledListSlice.emptyList();
14151        }
14152        final int callingUid = Binder.getCallingUid();
14153        final int callingUserId = UserHandle.getUserId(callingUid);
14154        synchronized (mPackages) {
14155            PackageParser.Package pkg = mPackages.get(packageName);
14156            if (pkg == null || pkg.activities == null) {
14157                return ParceledListSlice.emptyList();
14158            }
14159            if (pkg.mExtras == null) {
14160                return ParceledListSlice.emptyList();
14161            }
14162            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14163            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14164                return ParceledListSlice.emptyList();
14165            }
14166            final int count = pkg.activities.size();
14167            ArrayList<IntentFilter> result = new ArrayList<>();
14168            for (int n=0; n<count; n++) {
14169                PackageParser.Activity activity = pkg.activities.get(n);
14170                if (activity.intents != null && activity.intents.size() > 0) {
14171                    result.addAll(activity.intents);
14172                }
14173            }
14174            return new ParceledListSlice<>(result);
14175        }
14176    }
14177
14178    @Override
14179    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14180        mContext.enforceCallingOrSelfPermission(
14181                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14182        if (UserHandle.getCallingUserId() != userId) {
14183            mContext.enforceCallingOrSelfPermission(
14184                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14185        }
14186
14187        synchronized (mPackages) {
14188            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14189            if (packageName != null) {
14190                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14191                        packageName, userId);
14192            }
14193            return result;
14194        }
14195    }
14196
14197    @Override
14198    public String getDefaultBrowserPackageName(int userId) {
14199        if (UserHandle.getCallingUserId() != userId) {
14200            mContext.enforceCallingOrSelfPermission(
14201                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14202        }
14203        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14204            return null;
14205        }
14206        synchronized (mPackages) {
14207            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14208        }
14209    }
14210
14211    /**
14212     * Get the "allow unknown sources" setting.
14213     *
14214     * @return the current "allow unknown sources" setting
14215     */
14216    private int getUnknownSourcesSettings() {
14217        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14218                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14219                -1);
14220    }
14221
14222    @Override
14223    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14224        final int callingUid = Binder.getCallingUid();
14225        if (getInstantAppPackageName(callingUid) != null) {
14226            return;
14227        }
14228        // writer
14229        synchronized (mPackages) {
14230            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14231            if (targetPackageSetting == null
14232                    || filterAppAccessLPr(
14233                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14234                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14235            }
14236
14237            PackageSetting installerPackageSetting;
14238            if (installerPackageName != null) {
14239                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14240                if (installerPackageSetting == null) {
14241                    throw new IllegalArgumentException("Unknown installer package: "
14242                            + installerPackageName);
14243                }
14244            } else {
14245                installerPackageSetting = null;
14246            }
14247
14248            Signature[] callerSignature;
14249            Object obj = mSettings.getUserIdLPr(callingUid);
14250            if (obj != null) {
14251                if (obj instanceof SharedUserSetting) {
14252                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14253                } else if (obj instanceof PackageSetting) {
14254                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14255                } else {
14256                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14257                }
14258            } else {
14259                throw new SecurityException("Unknown calling UID: " + callingUid);
14260            }
14261
14262            // Verify: can't set installerPackageName to a package that is
14263            // not signed with the same cert as the caller.
14264            if (installerPackageSetting != null) {
14265                if (compareSignatures(callerSignature,
14266                        installerPackageSetting.signatures.mSignatures)
14267                        != PackageManager.SIGNATURE_MATCH) {
14268                    throw new SecurityException(
14269                            "Caller does not have same cert as new installer package "
14270                            + installerPackageName);
14271                }
14272            }
14273
14274            // Verify: if target already has an installer package, it must
14275            // be signed with the same cert as the caller.
14276            if (targetPackageSetting.installerPackageName != null) {
14277                PackageSetting setting = mSettings.mPackages.get(
14278                        targetPackageSetting.installerPackageName);
14279                // If the currently set package isn't valid, then it's always
14280                // okay to change it.
14281                if (setting != null) {
14282                    if (compareSignatures(callerSignature,
14283                            setting.signatures.mSignatures)
14284                            != PackageManager.SIGNATURE_MATCH) {
14285                        throw new SecurityException(
14286                                "Caller does not have same cert as old installer package "
14287                                + targetPackageSetting.installerPackageName);
14288                    }
14289                }
14290            }
14291
14292            // Okay!
14293            targetPackageSetting.installerPackageName = installerPackageName;
14294            if (installerPackageName != null) {
14295                mSettings.mInstallerPackages.add(installerPackageName);
14296            }
14297            scheduleWriteSettingsLocked();
14298        }
14299    }
14300
14301    @Override
14302    public void setApplicationCategoryHint(String packageName, int categoryHint,
14303            String callerPackageName) {
14304        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14305            throw new SecurityException("Instant applications don't have access to this method");
14306        }
14307        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14308                callerPackageName);
14309        synchronized (mPackages) {
14310            PackageSetting ps = mSettings.mPackages.get(packageName);
14311            if (ps == null) {
14312                throw new IllegalArgumentException("Unknown target package " + packageName);
14313            }
14314            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14315                throw new IllegalArgumentException("Unknown target package " + packageName);
14316            }
14317            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14318                throw new IllegalArgumentException("Calling package " + callerPackageName
14319                        + " is not installer for " + packageName);
14320            }
14321
14322            if (ps.categoryHint != categoryHint) {
14323                ps.categoryHint = categoryHint;
14324                scheduleWriteSettingsLocked();
14325            }
14326        }
14327    }
14328
14329    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14330        // Queue up an async operation since the package installation may take a little while.
14331        mHandler.post(new Runnable() {
14332            public void run() {
14333                mHandler.removeCallbacks(this);
14334                 // Result object to be returned
14335                PackageInstalledInfo res = new PackageInstalledInfo();
14336                res.setReturnCode(currentStatus);
14337                res.uid = -1;
14338                res.pkg = null;
14339                res.removedInfo = null;
14340                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14341                    args.doPreInstall(res.returnCode);
14342                    synchronized (mInstallLock) {
14343                        installPackageTracedLI(args, res);
14344                    }
14345                    args.doPostInstall(res.returnCode, res.uid);
14346                }
14347
14348                // A restore should be performed at this point if (a) the install
14349                // succeeded, (b) the operation is not an update, and (c) the new
14350                // package has not opted out of backup participation.
14351                final boolean update = res.removedInfo != null
14352                        && res.removedInfo.removedPackage != null;
14353                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14354                boolean doRestore = !update
14355                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14356
14357                // Set up the post-install work request bookkeeping.  This will be used
14358                // and cleaned up by the post-install event handling regardless of whether
14359                // there's a restore pass performed.  Token values are >= 1.
14360                int token;
14361                if (mNextInstallToken < 0) mNextInstallToken = 1;
14362                token = mNextInstallToken++;
14363
14364                PostInstallData data = new PostInstallData(args, res);
14365                mRunningInstalls.put(token, data);
14366                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14367
14368                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14369                    // Pass responsibility to the Backup Manager.  It will perform a
14370                    // restore if appropriate, then pass responsibility back to the
14371                    // Package Manager to run the post-install observer callbacks
14372                    // and broadcasts.
14373                    IBackupManager bm = IBackupManager.Stub.asInterface(
14374                            ServiceManager.getService(Context.BACKUP_SERVICE));
14375                    if (bm != null) {
14376                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14377                                + " to BM for possible restore");
14378                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14379                        try {
14380                            // TODO: http://b/22388012
14381                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14382                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14383                            } else {
14384                                doRestore = false;
14385                            }
14386                        } catch (RemoteException e) {
14387                            // can't happen; the backup manager is local
14388                        } catch (Exception e) {
14389                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14390                            doRestore = false;
14391                        }
14392                    } else {
14393                        Slog.e(TAG, "Backup Manager not found!");
14394                        doRestore = false;
14395                    }
14396                }
14397
14398                if (!doRestore) {
14399                    // No restore possible, or the Backup Manager was mysteriously not
14400                    // available -- just fire the post-install work request directly.
14401                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14402
14403                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14404
14405                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14406                    mHandler.sendMessage(msg);
14407                }
14408            }
14409        });
14410    }
14411
14412    /**
14413     * Callback from PackageSettings whenever an app is first transitioned out of the
14414     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14415     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14416     * here whether the app is the target of an ongoing install, and only send the
14417     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14418     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14419     * handling.
14420     */
14421    void notifyFirstLaunch(final String packageName, final String installerPackage,
14422            final int userId) {
14423        // Serialize this with the rest of the install-process message chain.  In the
14424        // restore-at-install case, this Runnable will necessarily run before the
14425        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14426        // are coherent.  In the non-restore case, the app has already completed install
14427        // and been launched through some other means, so it is not in a problematic
14428        // state for observers to see the FIRST_LAUNCH signal.
14429        mHandler.post(new Runnable() {
14430            @Override
14431            public void run() {
14432                for (int i = 0; i < mRunningInstalls.size(); i++) {
14433                    final PostInstallData data = mRunningInstalls.valueAt(i);
14434                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14435                        continue;
14436                    }
14437                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14438                        // right package; but is it for the right user?
14439                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14440                            if (userId == data.res.newUsers[uIndex]) {
14441                                if (DEBUG_BACKUP) {
14442                                    Slog.i(TAG, "Package " + packageName
14443                                            + " being restored so deferring FIRST_LAUNCH");
14444                                }
14445                                return;
14446                            }
14447                        }
14448                    }
14449                }
14450                // didn't find it, so not being restored
14451                if (DEBUG_BACKUP) {
14452                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14453                }
14454                final boolean isInstantApp = isInstantApp(packageName, userId);
14455                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14456                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14457                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14458            }
14459        });
14460    }
14461
14462    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14463            int[] userIds, int[] instantUserIds) {
14464        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14465                installerPkg, null, userIds, instantUserIds);
14466    }
14467
14468    private abstract class HandlerParams {
14469        private static final int MAX_RETRIES = 4;
14470
14471        /**
14472         * Number of times startCopy() has been attempted and had a non-fatal
14473         * error.
14474         */
14475        private int mRetries = 0;
14476
14477        /** User handle for the user requesting the information or installation. */
14478        private final UserHandle mUser;
14479        String traceMethod;
14480        int traceCookie;
14481
14482        HandlerParams(UserHandle user) {
14483            mUser = user;
14484        }
14485
14486        UserHandle getUser() {
14487            return mUser;
14488        }
14489
14490        HandlerParams setTraceMethod(String traceMethod) {
14491            this.traceMethod = traceMethod;
14492            return this;
14493        }
14494
14495        HandlerParams setTraceCookie(int traceCookie) {
14496            this.traceCookie = traceCookie;
14497            return this;
14498        }
14499
14500        final boolean startCopy() {
14501            boolean res;
14502            try {
14503                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14504
14505                if (++mRetries > MAX_RETRIES) {
14506                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14507                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14508                    handleServiceError();
14509                    return false;
14510                } else {
14511                    handleStartCopy();
14512                    res = true;
14513                }
14514            } catch (RemoteException e) {
14515                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14516                mHandler.sendEmptyMessage(MCS_RECONNECT);
14517                res = false;
14518            }
14519            handleReturnCode();
14520            return res;
14521        }
14522
14523        final void serviceError() {
14524            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14525            handleServiceError();
14526            handleReturnCode();
14527        }
14528
14529        abstract void handleStartCopy() throws RemoteException;
14530        abstract void handleServiceError();
14531        abstract void handleReturnCode();
14532    }
14533
14534    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14535        for (File path : paths) {
14536            try {
14537                mcs.clearDirectory(path.getAbsolutePath());
14538            } catch (RemoteException e) {
14539            }
14540        }
14541    }
14542
14543    static class OriginInfo {
14544        /**
14545         * Location where install is coming from, before it has been
14546         * copied/renamed into place. This could be a single monolithic APK
14547         * file, or a cluster directory. This location may be untrusted.
14548         */
14549        final File file;
14550
14551        /**
14552         * Flag indicating that {@link #file} or {@link #cid} has already been
14553         * staged, meaning downstream users don't need to defensively copy the
14554         * contents.
14555         */
14556        final boolean staged;
14557
14558        /**
14559         * Flag indicating that {@link #file} or {@link #cid} is an already
14560         * installed app that is being moved.
14561         */
14562        final boolean existing;
14563
14564        final String resolvedPath;
14565        final File resolvedFile;
14566
14567        static OriginInfo fromNothing() {
14568            return new OriginInfo(null, false, false);
14569        }
14570
14571        static OriginInfo fromUntrustedFile(File file) {
14572            return new OriginInfo(file, false, false);
14573        }
14574
14575        static OriginInfo fromExistingFile(File file) {
14576            return new OriginInfo(file, false, true);
14577        }
14578
14579        static OriginInfo fromStagedFile(File file) {
14580            return new OriginInfo(file, true, false);
14581        }
14582
14583        private OriginInfo(File file, boolean staged, boolean existing) {
14584            this.file = file;
14585            this.staged = staged;
14586            this.existing = existing;
14587
14588            if (file != null) {
14589                resolvedPath = file.getAbsolutePath();
14590                resolvedFile = file;
14591            } else {
14592                resolvedPath = null;
14593                resolvedFile = null;
14594            }
14595        }
14596    }
14597
14598    static class MoveInfo {
14599        final int moveId;
14600        final String fromUuid;
14601        final String toUuid;
14602        final String packageName;
14603        final String dataAppName;
14604        final int appId;
14605        final String seinfo;
14606        final int targetSdkVersion;
14607
14608        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14609                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14610            this.moveId = moveId;
14611            this.fromUuid = fromUuid;
14612            this.toUuid = toUuid;
14613            this.packageName = packageName;
14614            this.dataAppName = dataAppName;
14615            this.appId = appId;
14616            this.seinfo = seinfo;
14617            this.targetSdkVersion = targetSdkVersion;
14618        }
14619    }
14620
14621    static class VerificationInfo {
14622        /** A constant used to indicate that a uid value is not present. */
14623        public static final int NO_UID = -1;
14624
14625        /** URI referencing where the package was downloaded from. */
14626        final Uri originatingUri;
14627
14628        /** HTTP referrer URI associated with the originatingURI. */
14629        final Uri referrer;
14630
14631        /** UID of the application that the install request originated from. */
14632        final int originatingUid;
14633
14634        /** UID of application requesting the install */
14635        final int installerUid;
14636
14637        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14638            this.originatingUri = originatingUri;
14639            this.referrer = referrer;
14640            this.originatingUid = originatingUid;
14641            this.installerUid = installerUid;
14642        }
14643    }
14644
14645    class InstallParams extends HandlerParams {
14646        final OriginInfo origin;
14647        final MoveInfo move;
14648        final IPackageInstallObserver2 observer;
14649        int installFlags;
14650        final String installerPackageName;
14651        final String volumeUuid;
14652        private InstallArgs mArgs;
14653        private int mRet;
14654        final String packageAbiOverride;
14655        final String[] grantedRuntimePermissions;
14656        final VerificationInfo verificationInfo;
14657        final PackageParser.SigningDetails signingDetails;
14658        final int installReason;
14659
14660        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14661                int installFlags, String installerPackageName, String volumeUuid,
14662                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14663                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
14664            super(user);
14665            this.origin = origin;
14666            this.move = move;
14667            this.observer = observer;
14668            this.installFlags = installFlags;
14669            this.installerPackageName = installerPackageName;
14670            this.volumeUuid = volumeUuid;
14671            this.verificationInfo = verificationInfo;
14672            this.packageAbiOverride = packageAbiOverride;
14673            this.grantedRuntimePermissions = grantedPermissions;
14674            this.signingDetails = signingDetails;
14675            this.installReason = installReason;
14676        }
14677
14678        @Override
14679        public String toString() {
14680            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14681                    + " file=" + origin.file + "}";
14682        }
14683
14684        private int installLocationPolicy(PackageInfoLite pkgLite) {
14685            String packageName = pkgLite.packageName;
14686            int installLocation = pkgLite.installLocation;
14687            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14688            // reader
14689            synchronized (mPackages) {
14690                // Currently installed package which the new package is attempting to replace or
14691                // null if no such package is installed.
14692                PackageParser.Package installedPkg = mPackages.get(packageName);
14693                // Package which currently owns the data which the new package will own if installed.
14694                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14695                // will be null whereas dataOwnerPkg will contain information about the package
14696                // which was uninstalled while keeping its data.
14697                PackageParser.Package dataOwnerPkg = installedPkg;
14698                if (dataOwnerPkg  == null) {
14699                    PackageSetting ps = mSettings.mPackages.get(packageName);
14700                    if (ps != null) {
14701                        dataOwnerPkg = ps.pkg;
14702                    }
14703                }
14704
14705                if (dataOwnerPkg != null) {
14706                    // If installed, the package will get access to data left on the device by its
14707                    // predecessor. As a security measure, this is permited only if this is not a
14708                    // version downgrade or if the predecessor package is marked as debuggable and
14709                    // a downgrade is explicitly requested.
14710                    //
14711                    // On debuggable platform builds, downgrades are permitted even for
14712                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14713                    // not offer security guarantees and thus it's OK to disable some security
14714                    // mechanisms to make debugging/testing easier on those builds. However, even on
14715                    // debuggable builds downgrades of packages are permitted only if requested via
14716                    // installFlags. This is because we aim to keep the behavior of debuggable
14717                    // platform builds as close as possible to the behavior of non-debuggable
14718                    // platform builds.
14719                    final boolean downgradeRequested =
14720                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14721                    final boolean packageDebuggable =
14722                                (dataOwnerPkg.applicationInfo.flags
14723                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14724                    final boolean downgradePermitted =
14725                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14726                    if (!downgradePermitted) {
14727                        try {
14728                            checkDowngrade(dataOwnerPkg, pkgLite);
14729                        } catch (PackageManagerException e) {
14730                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14731                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14732                        }
14733                    }
14734                }
14735
14736                if (installedPkg != null) {
14737                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14738                        // Check for updated system application.
14739                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14740                            if (onSd) {
14741                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14742                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14743                            }
14744                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14745                        } else {
14746                            if (onSd) {
14747                                // Install flag overrides everything.
14748                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14749                            }
14750                            // If current upgrade specifies particular preference
14751                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14752                                // Application explicitly specified internal.
14753                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14754                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14755                                // App explictly prefers external. Let policy decide
14756                            } else {
14757                                // Prefer previous location
14758                                if (isExternal(installedPkg)) {
14759                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14760                                }
14761                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14762                            }
14763                        }
14764                    } else {
14765                        // Invalid install. Return error code
14766                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14767                    }
14768                }
14769            }
14770            // All the special cases have been taken care of.
14771            // Return result based on recommended install location.
14772            if (onSd) {
14773                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14774            }
14775            return pkgLite.recommendedInstallLocation;
14776        }
14777
14778        /*
14779         * Invoke remote method to get package information and install
14780         * location values. Override install location based on default
14781         * policy if needed and then create install arguments based
14782         * on the install location.
14783         */
14784        public void handleStartCopy() throws RemoteException {
14785            int ret = PackageManager.INSTALL_SUCCEEDED;
14786
14787            // If we're already staged, we've firmly committed to an install location
14788            if (origin.staged) {
14789                if (origin.file != null) {
14790                    installFlags |= PackageManager.INSTALL_INTERNAL;
14791                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14792                } else {
14793                    throw new IllegalStateException("Invalid stage location");
14794                }
14795            }
14796
14797            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14798            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14799            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14800            PackageInfoLite pkgLite = null;
14801
14802            if (onInt && onSd) {
14803                // Check if both bits are set.
14804                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14805                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14806            } else if (onSd && ephemeral) {
14807                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14808                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14809            } else {
14810                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14811                        packageAbiOverride);
14812
14813                if (DEBUG_EPHEMERAL && ephemeral) {
14814                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14815                }
14816
14817                /*
14818                 * If we have too little free space, try to free cache
14819                 * before giving up.
14820                 */
14821                if (!origin.staged && pkgLite.recommendedInstallLocation
14822                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14823                    // TODO: focus freeing disk space on the target device
14824                    final StorageManager storage = StorageManager.from(mContext);
14825                    final long lowThreshold = storage.getStorageLowBytes(
14826                            Environment.getDataDirectory());
14827
14828                    final long sizeBytes = mContainerService.calculateInstalledSize(
14829                            origin.resolvedPath, packageAbiOverride);
14830
14831                    try {
14832                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14833                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14834                                installFlags, packageAbiOverride);
14835                    } catch (InstallerException e) {
14836                        Slog.w(TAG, "Failed to free cache", e);
14837                    }
14838
14839                    /*
14840                     * The cache free must have deleted the file we
14841                     * downloaded to install.
14842                     *
14843                     * TODO: fix the "freeCache" call to not delete
14844                     *       the file we care about.
14845                     */
14846                    if (pkgLite.recommendedInstallLocation
14847                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14848                        pkgLite.recommendedInstallLocation
14849                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14850                    }
14851                }
14852            }
14853
14854            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14855                int loc = pkgLite.recommendedInstallLocation;
14856                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14857                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14858                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14859                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14860                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14861                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14862                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14863                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14864                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14865                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14866                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14867                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14868                } else {
14869                    // Override with defaults if needed.
14870                    loc = installLocationPolicy(pkgLite);
14871                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14872                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14873                    } else if (!onSd && !onInt) {
14874                        // Override install location with flags
14875                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14876                            // Set the flag to install on external media.
14877                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14878                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14879                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14880                            if (DEBUG_EPHEMERAL) {
14881                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14882                            }
14883                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14884                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14885                                    |PackageManager.INSTALL_INTERNAL);
14886                        } else {
14887                            // Make sure the flag for installing on external
14888                            // media is unset
14889                            installFlags |= PackageManager.INSTALL_INTERNAL;
14890                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14891                        }
14892                    }
14893                }
14894            }
14895
14896            final InstallArgs args = createInstallArgs(this);
14897            mArgs = args;
14898
14899            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14900                // TODO: http://b/22976637
14901                // Apps installed for "all" users use the device owner to verify the app
14902                UserHandle verifierUser = getUser();
14903                if (verifierUser == UserHandle.ALL) {
14904                    verifierUser = UserHandle.SYSTEM;
14905                }
14906
14907                /*
14908                 * Determine if we have any installed package verifiers. If we
14909                 * do, then we'll defer to them to verify the packages.
14910                 */
14911                final int requiredUid = mRequiredVerifierPackage == null ? -1
14912                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14913                                verifierUser.getIdentifier());
14914                final int installerUid =
14915                        verificationInfo == null ? -1 : verificationInfo.installerUid;
14916                if (!origin.existing && requiredUid != -1
14917                        && isVerificationEnabled(
14918                                verifierUser.getIdentifier(), installFlags, installerUid)) {
14919                    final Intent verification = new Intent(
14920                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14921                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14922                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14923                            PACKAGE_MIME_TYPE);
14924                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14925
14926                    // Query all live verifiers based on current user state
14927                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14928                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14929                            false /*allowDynamicSplits*/);
14930
14931                    if (DEBUG_VERIFY) {
14932                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14933                                + verification.toString() + " with " + pkgLite.verifiers.length
14934                                + " optional verifiers");
14935                    }
14936
14937                    final int verificationId = mPendingVerificationToken++;
14938
14939                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14940
14941                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14942                            installerPackageName);
14943
14944                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14945                            installFlags);
14946
14947                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14948                            pkgLite.packageName);
14949
14950                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14951                            pkgLite.versionCode);
14952
14953                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14954                            pkgLite.getLongVersionCode());
14955
14956                    if (verificationInfo != null) {
14957                        if (verificationInfo.originatingUri != null) {
14958                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14959                                    verificationInfo.originatingUri);
14960                        }
14961                        if (verificationInfo.referrer != null) {
14962                            verification.putExtra(Intent.EXTRA_REFERRER,
14963                                    verificationInfo.referrer);
14964                        }
14965                        if (verificationInfo.originatingUid >= 0) {
14966                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14967                                    verificationInfo.originatingUid);
14968                        }
14969                        if (verificationInfo.installerUid >= 0) {
14970                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14971                                    verificationInfo.installerUid);
14972                        }
14973                    }
14974
14975                    final PackageVerificationState verificationState = new PackageVerificationState(
14976                            requiredUid, args);
14977
14978                    mPendingVerification.append(verificationId, verificationState);
14979
14980                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14981                            receivers, verificationState);
14982
14983                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14984                    final long idleDuration = getVerificationTimeout();
14985
14986                    /*
14987                     * If any sufficient verifiers were listed in the package
14988                     * manifest, attempt to ask them.
14989                     */
14990                    if (sufficientVerifiers != null) {
14991                        final int N = sufficientVerifiers.size();
14992                        if (N == 0) {
14993                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14994                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14995                        } else {
14996                            for (int i = 0; i < N; i++) {
14997                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14998                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14999                                        verifierComponent.getPackageName(), idleDuration,
15000                                        verifierUser.getIdentifier(), false, "package verifier");
15001
15002                                final Intent sufficientIntent = new Intent(verification);
15003                                sufficientIntent.setComponent(verifierComponent);
15004                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15005                            }
15006                        }
15007                    }
15008
15009                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15010                            mRequiredVerifierPackage, receivers);
15011                    if (ret == PackageManager.INSTALL_SUCCEEDED
15012                            && mRequiredVerifierPackage != null) {
15013                        Trace.asyncTraceBegin(
15014                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15015                        /*
15016                         * Send the intent to the required verification agent,
15017                         * but only start the verification timeout after the
15018                         * target BroadcastReceivers have run.
15019                         */
15020                        verification.setComponent(requiredVerifierComponent);
15021                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15022                                mRequiredVerifierPackage, idleDuration,
15023                                verifierUser.getIdentifier(), false, "package verifier");
15024                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15025                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15026                                new BroadcastReceiver() {
15027                                    @Override
15028                                    public void onReceive(Context context, Intent intent) {
15029                                        final Message msg = mHandler
15030                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15031                                        msg.arg1 = verificationId;
15032                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15033                                    }
15034                                }, null, 0, null, null);
15035
15036                        /*
15037                         * We don't want the copy to proceed until verification
15038                         * succeeds, so null out this field.
15039                         */
15040                        mArgs = null;
15041                    }
15042                } else {
15043                    /*
15044                     * No package verification is enabled, so immediately start
15045                     * the remote call to initiate copy using temporary file.
15046                     */
15047                    ret = args.copyApk(mContainerService, true);
15048                }
15049            }
15050
15051            mRet = ret;
15052        }
15053
15054        @Override
15055        void handleReturnCode() {
15056            // If mArgs is null, then MCS couldn't be reached. When it
15057            // reconnects, it will try again to install. At that point, this
15058            // will succeed.
15059            if (mArgs != null) {
15060                processPendingInstall(mArgs, mRet);
15061            }
15062        }
15063
15064        @Override
15065        void handleServiceError() {
15066            mArgs = createInstallArgs(this);
15067            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15068        }
15069    }
15070
15071    private InstallArgs createInstallArgs(InstallParams params) {
15072        if (params.move != null) {
15073            return new MoveInstallArgs(params);
15074        } else {
15075            return new FileInstallArgs(params);
15076        }
15077    }
15078
15079    /**
15080     * Create args that describe an existing installed package. Typically used
15081     * when cleaning up old installs, or used as a move source.
15082     */
15083    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15084            String resourcePath, String[] instructionSets) {
15085        return new FileInstallArgs(codePath, resourcePath, instructionSets);
15086    }
15087
15088    static abstract class InstallArgs {
15089        /** @see InstallParams#origin */
15090        final OriginInfo origin;
15091        /** @see InstallParams#move */
15092        final MoveInfo move;
15093
15094        final IPackageInstallObserver2 observer;
15095        // Always refers to PackageManager flags only
15096        final int installFlags;
15097        final String installerPackageName;
15098        final String volumeUuid;
15099        final UserHandle user;
15100        final String abiOverride;
15101        final String[] installGrantPermissions;
15102        /** If non-null, drop an async trace when the install completes */
15103        final String traceMethod;
15104        final int traceCookie;
15105        final PackageParser.SigningDetails signingDetails;
15106        final int installReason;
15107
15108        // The list of instruction sets supported by this app. This is currently
15109        // only used during the rmdex() phase to clean up resources. We can get rid of this
15110        // if we move dex files under the common app path.
15111        /* nullable */ String[] instructionSets;
15112
15113        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15114                int installFlags, String installerPackageName, String volumeUuid,
15115                UserHandle user, String[] instructionSets,
15116                String abiOverride, String[] installGrantPermissions,
15117                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15118                int installReason) {
15119            this.origin = origin;
15120            this.move = move;
15121            this.installFlags = installFlags;
15122            this.observer = observer;
15123            this.installerPackageName = installerPackageName;
15124            this.volumeUuid = volumeUuid;
15125            this.user = user;
15126            this.instructionSets = instructionSets;
15127            this.abiOverride = abiOverride;
15128            this.installGrantPermissions = installGrantPermissions;
15129            this.traceMethod = traceMethod;
15130            this.traceCookie = traceCookie;
15131            this.signingDetails = signingDetails;
15132            this.installReason = installReason;
15133        }
15134
15135        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15136        abstract int doPreInstall(int status);
15137
15138        /**
15139         * Rename package into final resting place. All paths on the given
15140         * scanned package should be updated to reflect the rename.
15141         */
15142        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15143        abstract int doPostInstall(int status, int uid);
15144
15145        /** @see PackageSettingBase#codePathString */
15146        abstract String getCodePath();
15147        /** @see PackageSettingBase#resourcePathString */
15148        abstract String getResourcePath();
15149
15150        // Need installer lock especially for dex file removal.
15151        abstract void cleanUpResourcesLI();
15152        abstract boolean doPostDeleteLI(boolean delete);
15153
15154        /**
15155         * Called before the source arguments are copied. This is used mostly
15156         * for MoveParams when it needs to read the source file to put it in the
15157         * destination.
15158         */
15159        int doPreCopy() {
15160            return PackageManager.INSTALL_SUCCEEDED;
15161        }
15162
15163        /**
15164         * Called after the source arguments are copied. This is used mostly for
15165         * MoveParams when it needs to read the source file to put it in the
15166         * destination.
15167         */
15168        int doPostCopy(int uid) {
15169            return PackageManager.INSTALL_SUCCEEDED;
15170        }
15171
15172        protected boolean isFwdLocked() {
15173            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15174        }
15175
15176        protected boolean isExternalAsec() {
15177            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15178        }
15179
15180        protected boolean isEphemeral() {
15181            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15182        }
15183
15184        UserHandle getUser() {
15185            return user;
15186        }
15187    }
15188
15189    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15190        if (!allCodePaths.isEmpty()) {
15191            if (instructionSets == null) {
15192                throw new IllegalStateException("instructionSet == null");
15193            }
15194            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15195            for (String codePath : allCodePaths) {
15196                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15197                    try {
15198                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15199                    } catch (InstallerException ignored) {
15200                    }
15201                }
15202            }
15203        }
15204    }
15205
15206    /**
15207     * Logic to handle installation of non-ASEC applications, including copying
15208     * and renaming logic.
15209     */
15210    class FileInstallArgs extends InstallArgs {
15211        private File codeFile;
15212        private File resourceFile;
15213
15214        // Example topology:
15215        // /data/app/com.example/base.apk
15216        // /data/app/com.example/split_foo.apk
15217        // /data/app/com.example/lib/arm/libfoo.so
15218        // /data/app/com.example/lib/arm64/libfoo.so
15219        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15220
15221        /** New install */
15222        FileInstallArgs(InstallParams params) {
15223            super(params.origin, params.move, params.observer, params.installFlags,
15224                    params.installerPackageName, params.volumeUuid,
15225                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15226                    params.grantedRuntimePermissions,
15227                    params.traceMethod, params.traceCookie, params.signingDetails,
15228                    params.installReason);
15229            if (isFwdLocked()) {
15230                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15231            }
15232        }
15233
15234        /** Existing install */
15235        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15236            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15237                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15238                    PackageManager.INSTALL_REASON_UNKNOWN);
15239            this.codeFile = (codePath != null) ? new File(codePath) : null;
15240            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15241        }
15242
15243        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15244            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15245            try {
15246                return doCopyApk(imcs, temp);
15247            } finally {
15248                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15249            }
15250        }
15251
15252        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15253            if (origin.staged) {
15254                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15255                codeFile = origin.file;
15256                resourceFile = origin.file;
15257                return PackageManager.INSTALL_SUCCEEDED;
15258            }
15259
15260            try {
15261                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15262                final File tempDir =
15263                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15264                codeFile = tempDir;
15265                resourceFile = tempDir;
15266            } catch (IOException e) {
15267                Slog.w(TAG, "Failed to create copy file: " + e);
15268                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15269            }
15270
15271            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15272                @Override
15273                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15274                    if (!FileUtils.isValidExtFilename(name)) {
15275                        throw new IllegalArgumentException("Invalid filename: " + name);
15276                    }
15277                    try {
15278                        final File file = new File(codeFile, name);
15279                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15280                                O_RDWR | O_CREAT, 0644);
15281                        Os.chmod(file.getAbsolutePath(), 0644);
15282                        return new ParcelFileDescriptor(fd);
15283                    } catch (ErrnoException e) {
15284                        throw new RemoteException("Failed to open: " + e.getMessage());
15285                    }
15286                }
15287            };
15288
15289            int ret = PackageManager.INSTALL_SUCCEEDED;
15290            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15291            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15292                Slog.e(TAG, "Failed to copy package");
15293                return ret;
15294            }
15295
15296            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15297            NativeLibraryHelper.Handle handle = null;
15298            try {
15299                handle = NativeLibraryHelper.Handle.create(codeFile);
15300                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15301                        abiOverride);
15302            } catch (IOException e) {
15303                Slog.e(TAG, "Copying native libraries failed", e);
15304                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15305            } finally {
15306                IoUtils.closeQuietly(handle);
15307            }
15308
15309            return ret;
15310        }
15311
15312        int doPreInstall(int status) {
15313            if (status != PackageManager.INSTALL_SUCCEEDED) {
15314                cleanUp();
15315            }
15316            return status;
15317        }
15318
15319        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15320            if (status != PackageManager.INSTALL_SUCCEEDED) {
15321                cleanUp();
15322                return false;
15323            }
15324
15325            final File targetDir = codeFile.getParentFile();
15326            final File beforeCodeFile = codeFile;
15327            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15328
15329            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15330            try {
15331                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15332            } catch (ErrnoException e) {
15333                Slog.w(TAG, "Failed to rename", e);
15334                return false;
15335            }
15336
15337            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15338                Slog.w(TAG, "Failed to restorecon");
15339                return false;
15340            }
15341
15342            // Reflect the rename internally
15343            codeFile = afterCodeFile;
15344            resourceFile = afterCodeFile;
15345
15346            // Reflect the rename in scanned details
15347            try {
15348                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15349            } catch (IOException e) {
15350                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15351                return false;
15352            }
15353            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15354                    afterCodeFile, pkg.baseCodePath));
15355            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15356                    afterCodeFile, pkg.splitCodePaths));
15357
15358            // Reflect the rename in app info
15359            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15360            pkg.setApplicationInfoCodePath(pkg.codePath);
15361            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15362            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15363            pkg.setApplicationInfoResourcePath(pkg.codePath);
15364            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15365            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15366
15367            return true;
15368        }
15369
15370        int doPostInstall(int status, int uid) {
15371            if (status != PackageManager.INSTALL_SUCCEEDED) {
15372                cleanUp();
15373            }
15374            return status;
15375        }
15376
15377        @Override
15378        String getCodePath() {
15379            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15380        }
15381
15382        @Override
15383        String getResourcePath() {
15384            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15385        }
15386
15387        private boolean cleanUp() {
15388            if (codeFile == null || !codeFile.exists()) {
15389                return false;
15390            }
15391
15392            removeCodePathLI(codeFile);
15393
15394            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15395                resourceFile.delete();
15396            }
15397
15398            return true;
15399        }
15400
15401        void cleanUpResourcesLI() {
15402            // Try enumerating all code paths before deleting
15403            List<String> allCodePaths = Collections.EMPTY_LIST;
15404            if (codeFile != null && codeFile.exists()) {
15405                try {
15406                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15407                    allCodePaths = pkg.getAllCodePaths();
15408                } catch (PackageParserException e) {
15409                    // Ignored; we tried our best
15410                }
15411            }
15412
15413            cleanUp();
15414            removeDexFiles(allCodePaths, instructionSets);
15415        }
15416
15417        boolean doPostDeleteLI(boolean delete) {
15418            // XXX err, shouldn't we respect the delete flag?
15419            cleanUpResourcesLI();
15420            return true;
15421        }
15422    }
15423
15424    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15425            PackageManagerException {
15426        if (copyRet < 0) {
15427            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15428                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15429                throw new PackageManagerException(copyRet, message);
15430            }
15431        }
15432    }
15433
15434    /**
15435     * Extract the StorageManagerService "container ID" from the full code path of an
15436     * .apk.
15437     */
15438    static String cidFromCodePath(String fullCodePath) {
15439        int eidx = fullCodePath.lastIndexOf("/");
15440        String subStr1 = fullCodePath.substring(0, eidx);
15441        int sidx = subStr1.lastIndexOf("/");
15442        return subStr1.substring(sidx+1, eidx);
15443    }
15444
15445    /**
15446     * Logic to handle movement of existing installed applications.
15447     */
15448    class MoveInstallArgs extends InstallArgs {
15449        private File codeFile;
15450        private File resourceFile;
15451
15452        /** New install */
15453        MoveInstallArgs(InstallParams params) {
15454            super(params.origin, params.move, params.observer, params.installFlags,
15455                    params.installerPackageName, params.volumeUuid,
15456                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15457                    params.grantedRuntimePermissions,
15458                    params.traceMethod, params.traceCookie, params.signingDetails,
15459                    params.installReason);
15460        }
15461
15462        int copyApk(IMediaContainerService imcs, boolean temp) {
15463            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15464                    + move.fromUuid + " to " + move.toUuid);
15465            synchronized (mInstaller) {
15466                try {
15467                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15468                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15469                } catch (InstallerException e) {
15470                    Slog.w(TAG, "Failed to move app", e);
15471                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15472                }
15473            }
15474
15475            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15476            resourceFile = codeFile;
15477            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15478
15479            return PackageManager.INSTALL_SUCCEEDED;
15480        }
15481
15482        int doPreInstall(int status) {
15483            if (status != PackageManager.INSTALL_SUCCEEDED) {
15484                cleanUp(move.toUuid);
15485            }
15486            return status;
15487        }
15488
15489        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15490            if (status != PackageManager.INSTALL_SUCCEEDED) {
15491                cleanUp(move.toUuid);
15492                return false;
15493            }
15494
15495            // Reflect the move in app info
15496            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15497            pkg.setApplicationInfoCodePath(pkg.codePath);
15498            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15499            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15500            pkg.setApplicationInfoResourcePath(pkg.codePath);
15501            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15502            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15503
15504            return true;
15505        }
15506
15507        int doPostInstall(int status, int uid) {
15508            if (status == PackageManager.INSTALL_SUCCEEDED) {
15509                cleanUp(move.fromUuid);
15510            } else {
15511                cleanUp(move.toUuid);
15512            }
15513            return status;
15514        }
15515
15516        @Override
15517        String getCodePath() {
15518            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15519        }
15520
15521        @Override
15522        String getResourcePath() {
15523            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15524        }
15525
15526        private boolean cleanUp(String volumeUuid) {
15527            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15528                    move.dataAppName);
15529            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15530            final int[] userIds = sUserManager.getUserIds();
15531            synchronized (mInstallLock) {
15532                // Clean up both app data and code
15533                // All package moves are frozen until finished
15534                for (int userId : userIds) {
15535                    try {
15536                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15537                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15538                    } catch (InstallerException e) {
15539                        Slog.w(TAG, String.valueOf(e));
15540                    }
15541                }
15542                removeCodePathLI(codeFile);
15543            }
15544            return true;
15545        }
15546
15547        void cleanUpResourcesLI() {
15548            throw new UnsupportedOperationException();
15549        }
15550
15551        boolean doPostDeleteLI(boolean delete) {
15552            throw new UnsupportedOperationException();
15553        }
15554    }
15555
15556    static String getAsecPackageName(String packageCid) {
15557        int idx = packageCid.lastIndexOf("-");
15558        if (idx == -1) {
15559            return packageCid;
15560        }
15561        return packageCid.substring(0, idx);
15562    }
15563
15564    // Utility method used to create code paths based on package name and available index.
15565    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15566        String idxStr = "";
15567        int idx = 1;
15568        // Fall back to default value of idx=1 if prefix is not
15569        // part of oldCodePath
15570        if (oldCodePath != null) {
15571            String subStr = oldCodePath;
15572            // Drop the suffix right away
15573            if (suffix != null && subStr.endsWith(suffix)) {
15574                subStr = subStr.substring(0, subStr.length() - suffix.length());
15575            }
15576            // If oldCodePath already contains prefix find out the
15577            // ending index to either increment or decrement.
15578            int sidx = subStr.lastIndexOf(prefix);
15579            if (sidx != -1) {
15580                subStr = subStr.substring(sidx + prefix.length());
15581                if (subStr != null) {
15582                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15583                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15584                    }
15585                    try {
15586                        idx = Integer.parseInt(subStr);
15587                        if (idx <= 1) {
15588                            idx++;
15589                        } else {
15590                            idx--;
15591                        }
15592                    } catch(NumberFormatException e) {
15593                    }
15594                }
15595            }
15596        }
15597        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15598        return prefix + idxStr;
15599    }
15600
15601    private File getNextCodePath(File targetDir, String packageName) {
15602        File result;
15603        SecureRandom random = new SecureRandom();
15604        byte[] bytes = new byte[16];
15605        do {
15606            random.nextBytes(bytes);
15607            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15608            result = new File(targetDir, packageName + "-" + suffix);
15609        } while (result.exists());
15610        return result;
15611    }
15612
15613    // Utility method that returns the relative package path with respect
15614    // to the installation directory. Like say for /data/data/com.test-1.apk
15615    // string com.test-1 is returned.
15616    static String deriveCodePathName(String codePath) {
15617        if (codePath == null) {
15618            return null;
15619        }
15620        final File codeFile = new File(codePath);
15621        final String name = codeFile.getName();
15622        if (codeFile.isDirectory()) {
15623            return name;
15624        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15625            final int lastDot = name.lastIndexOf('.');
15626            return name.substring(0, lastDot);
15627        } else {
15628            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15629            return null;
15630        }
15631    }
15632
15633    static class PackageInstalledInfo {
15634        String name;
15635        int uid;
15636        // The set of users that originally had this package installed.
15637        int[] origUsers;
15638        // The set of users that now have this package installed.
15639        int[] newUsers;
15640        PackageParser.Package pkg;
15641        int returnCode;
15642        String returnMsg;
15643        String installerPackageName;
15644        PackageRemovedInfo removedInfo;
15645        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15646
15647        public void setError(int code, String msg) {
15648            setReturnCode(code);
15649            setReturnMessage(msg);
15650            Slog.w(TAG, msg);
15651        }
15652
15653        public void setError(String msg, PackageParserException e) {
15654            setReturnCode(e.error);
15655            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15656            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15657            for (int i = 0; i < childCount; i++) {
15658                addedChildPackages.valueAt(i).setError(msg, e);
15659            }
15660            Slog.w(TAG, msg, e);
15661        }
15662
15663        public void setError(String msg, PackageManagerException e) {
15664            returnCode = e.error;
15665            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15666            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15667            for (int i = 0; i < childCount; i++) {
15668                addedChildPackages.valueAt(i).setError(msg, e);
15669            }
15670            Slog.w(TAG, msg, e);
15671        }
15672
15673        public void setReturnCode(int returnCode) {
15674            this.returnCode = returnCode;
15675            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15676            for (int i = 0; i < childCount; i++) {
15677                addedChildPackages.valueAt(i).returnCode = returnCode;
15678            }
15679        }
15680
15681        private void setReturnMessage(String returnMsg) {
15682            this.returnMsg = returnMsg;
15683            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15684            for (int i = 0; i < childCount; i++) {
15685                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15686            }
15687        }
15688
15689        // In some error cases we want to convey more info back to the observer
15690        String origPackage;
15691        String origPermission;
15692    }
15693
15694    /*
15695     * Install a non-existing package.
15696     */
15697    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15698            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15699            String volumeUuid, PackageInstalledInfo res, int installReason) {
15700        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15701
15702        // Remember this for later, in case we need to rollback this install
15703        String pkgName = pkg.packageName;
15704
15705        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15706
15707        synchronized(mPackages) {
15708            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15709            if (renamedPackage != null) {
15710                // A package with the same name is already installed, though
15711                // it has been renamed to an older name.  The package we
15712                // are trying to install should be installed as an update to
15713                // the existing one, but that has not been requested, so bail.
15714                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15715                        + " without first uninstalling package running as "
15716                        + renamedPackage);
15717                return;
15718            }
15719            if (mPackages.containsKey(pkgName)) {
15720                // Don't allow installation over an existing package with the same name.
15721                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15722                        + " without first uninstalling.");
15723                return;
15724            }
15725        }
15726
15727        try {
15728            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15729                    System.currentTimeMillis(), user);
15730
15731            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15732
15733            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15734                prepareAppDataAfterInstallLIF(newPackage);
15735
15736            } else {
15737                // Remove package from internal structures, but keep around any
15738                // data that might have already existed
15739                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15740                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15741            }
15742        } catch (PackageManagerException e) {
15743            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15744        }
15745
15746        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15747    }
15748
15749    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15750        try (DigestInputStream digestStream =
15751                new DigestInputStream(new FileInputStream(file), digest)) {
15752            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15753        }
15754    }
15755
15756    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15757            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15758            PackageInstalledInfo res, int installReason) {
15759        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15760
15761        final PackageParser.Package oldPackage;
15762        final PackageSetting ps;
15763        final String pkgName = pkg.packageName;
15764        final int[] allUsers;
15765        final int[] installedUsers;
15766
15767        synchronized(mPackages) {
15768            oldPackage = mPackages.get(pkgName);
15769            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15770
15771            // don't allow upgrade to target a release SDK from a pre-release SDK
15772            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15773                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15774            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15775                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15776            if (oldTargetsPreRelease
15777                    && !newTargetsPreRelease
15778                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15779                Slog.w(TAG, "Can't install package targeting released sdk");
15780                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15781                return;
15782            }
15783
15784            ps = mSettings.mPackages.get(pkgName);
15785
15786            // verify signatures are valid
15787            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
15788            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
15789                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
15790                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15791                            "New package not signed by keys specified by upgrade-keysets: "
15792                                    + pkgName);
15793                    return;
15794                }
15795            } else {
15796                // default to original signature matching
15797                if (compareSignatures(oldPackage.mSigningDetails.signatures,
15798                        pkg.mSigningDetails.signatures)
15799                        != PackageManager.SIGNATURE_MATCH) {
15800                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15801                            "New package has a different signature: " + pkgName);
15802                    return;
15803                }
15804            }
15805
15806            // don't allow a system upgrade unless the upgrade hash matches
15807            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
15808                byte[] digestBytes = null;
15809                try {
15810                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15811                    updateDigest(digest, new File(pkg.baseCodePath));
15812                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15813                        for (String path : pkg.splitCodePaths) {
15814                            updateDigest(digest, new File(path));
15815                        }
15816                    }
15817                    digestBytes = digest.digest();
15818                } catch (NoSuchAlgorithmException | IOException e) {
15819                    res.setError(INSTALL_FAILED_INVALID_APK,
15820                            "Could not compute hash: " + pkgName);
15821                    return;
15822                }
15823                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15824                    res.setError(INSTALL_FAILED_INVALID_APK,
15825                            "New package fails restrict-update check: " + pkgName);
15826                    return;
15827                }
15828                // retain upgrade restriction
15829                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15830            }
15831
15832            // Check for shared user id changes
15833            String invalidPackageName =
15834                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15835            if (invalidPackageName != null) {
15836                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15837                        "Package " + invalidPackageName + " tried to change user "
15838                                + oldPackage.mSharedUserId);
15839                return;
15840            }
15841
15842            // check if the new package supports all of the abis which the old package supports
15843            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
15844            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
15845            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
15846                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15847                        "Update to package " + pkgName + " doesn't support multi arch");
15848                return;
15849            }
15850
15851            // In case of rollback, remember per-user/profile install state
15852            allUsers = sUserManager.getUserIds();
15853            installedUsers = ps.queryInstalledUsers(allUsers, true);
15854
15855            // don't allow an upgrade from full to ephemeral
15856            if (isInstantApp) {
15857                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
15858                    for (int currentUser : allUsers) {
15859                        if (!ps.getInstantApp(currentUser)) {
15860                            // can't downgrade from full to instant
15861                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15862                                    + " for user: " + currentUser);
15863                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15864                            return;
15865                        }
15866                    }
15867                } else if (!ps.getInstantApp(user.getIdentifier())) {
15868                    // can't downgrade from full to instant
15869                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15870                            + " for user: " + user.getIdentifier());
15871                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15872                    return;
15873                }
15874            }
15875        }
15876
15877        // Update what is removed
15878        res.removedInfo = new PackageRemovedInfo(this);
15879        res.removedInfo.uid = oldPackage.applicationInfo.uid;
15880        res.removedInfo.removedPackage = oldPackage.packageName;
15881        res.removedInfo.installerPackageName = ps.installerPackageName;
15882        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15883        res.removedInfo.isUpdate = true;
15884        res.removedInfo.origUsers = installedUsers;
15885        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15886        for (int i = 0; i < installedUsers.length; i++) {
15887            final int userId = installedUsers[i];
15888            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15889        }
15890
15891        final int childCount = (oldPackage.childPackages != null)
15892                ? oldPackage.childPackages.size() : 0;
15893        for (int i = 0; i < childCount; i++) {
15894            boolean childPackageUpdated = false;
15895            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15896            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15897            if (res.addedChildPackages != null) {
15898                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15899                if (childRes != null) {
15900                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15901                    childRes.removedInfo.removedPackage = childPkg.packageName;
15902                    if (childPs != null) {
15903                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
15904                    }
15905                    childRes.removedInfo.isUpdate = true;
15906                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15907                    childPackageUpdated = true;
15908                }
15909            }
15910            if (!childPackageUpdated) {
15911                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
15912                childRemovedRes.removedPackage = childPkg.packageName;
15913                if (childPs != null) {
15914                    childRemovedRes.installerPackageName = childPs.installerPackageName;
15915                }
15916                childRemovedRes.isUpdate = false;
15917                childRemovedRes.dataRemoved = true;
15918                synchronized (mPackages) {
15919                    if (childPs != null) {
15920                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15921                    }
15922                }
15923                if (res.removedInfo.removedChildPackages == null) {
15924                    res.removedInfo.removedChildPackages = new ArrayMap<>();
15925                }
15926                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15927            }
15928        }
15929
15930        boolean sysPkg = (isSystemApp(oldPackage));
15931        if (sysPkg) {
15932            // Set the system/privileged/oem/vendor flags as needed
15933            final boolean privileged =
15934                    (oldPackage.applicationInfo.privateFlags
15935                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15936            final boolean oem =
15937                    (oldPackage.applicationInfo.privateFlags
15938                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
15939            final boolean vendor =
15940                    (oldPackage.applicationInfo.privateFlags
15941                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
15942            final @ParseFlags int systemParseFlags = parseFlags;
15943            final @ScanFlags int systemScanFlags = scanFlags
15944                    | SCAN_AS_SYSTEM
15945                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
15946                    | (oem ? SCAN_AS_OEM : 0)
15947                    | (vendor ? SCAN_AS_VENDOR : 0);
15948
15949            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
15950                    user, allUsers, installerPackageName, res, installReason);
15951        } else {
15952            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
15953                    user, allUsers, installerPackageName, res, installReason);
15954        }
15955    }
15956
15957    @Override
15958    public List<String> getPreviousCodePaths(String packageName) {
15959        final int callingUid = Binder.getCallingUid();
15960        final List<String> result = new ArrayList<>();
15961        if (getInstantAppPackageName(callingUid) != null) {
15962            return result;
15963        }
15964        final PackageSetting ps = mSettings.mPackages.get(packageName);
15965        if (ps != null
15966                && ps.oldCodePaths != null
15967                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15968            result.addAll(ps.oldCodePaths);
15969        }
15970        return result;
15971    }
15972
15973    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15974            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15975            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
15976            String installerPackageName, PackageInstalledInfo res, int installReason) {
15977        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15978                + deletedPackage);
15979
15980        String pkgName = deletedPackage.packageName;
15981        boolean deletedPkg = true;
15982        boolean addedPkg = false;
15983        boolean updatedSettings = false;
15984        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15985        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15986                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15987
15988        final long origUpdateTime = (pkg.mExtras != null)
15989                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15990
15991        // First delete the existing package while retaining the data directory
15992        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15993                res.removedInfo, true, pkg)) {
15994            // If the existing package wasn't successfully deleted
15995            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15996            deletedPkg = false;
15997        } else {
15998            // Successfully deleted the old package; proceed with replace.
15999
16000            // If deleted package lived in a container, give users a chance to
16001            // relinquish resources before killing.
16002            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16003                if (DEBUG_INSTALL) {
16004                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16005                }
16006                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16007                final ArrayList<String> pkgList = new ArrayList<String>(1);
16008                pkgList.add(deletedPackage.applicationInfo.packageName);
16009                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16010            }
16011
16012            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16013                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16014            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16015
16016            try {
16017                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16018                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16019                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16020                        installReason);
16021
16022                // Update the in-memory copy of the previous code paths.
16023                PackageSetting ps = mSettings.mPackages.get(pkgName);
16024                if (!killApp) {
16025                    if (ps.oldCodePaths == null) {
16026                        ps.oldCodePaths = new ArraySet<>();
16027                    }
16028                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16029                    if (deletedPackage.splitCodePaths != null) {
16030                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16031                    }
16032                } else {
16033                    ps.oldCodePaths = null;
16034                }
16035                if (ps.childPackageNames != null) {
16036                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16037                        final String childPkgName = ps.childPackageNames.get(i);
16038                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16039                        childPs.oldCodePaths = ps.oldCodePaths;
16040                    }
16041                }
16042                // set instant app status, but, only if it's explicitly specified
16043                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16044                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16045                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16046                prepareAppDataAfterInstallLIF(newPackage);
16047                addedPkg = true;
16048                mDexManager.notifyPackageUpdated(newPackage.packageName,
16049                        newPackage.baseCodePath, newPackage.splitCodePaths);
16050            } catch (PackageManagerException e) {
16051                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16052            }
16053        }
16054
16055        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16056            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16057
16058            // Revert all internal state mutations and added folders for the failed install
16059            if (addedPkg) {
16060                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16061                        res.removedInfo, true, null);
16062            }
16063
16064            // Restore the old package
16065            if (deletedPkg) {
16066                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16067                File restoreFile = new File(deletedPackage.codePath);
16068                // Parse old package
16069                boolean oldExternal = isExternal(deletedPackage);
16070                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16071                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16072                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16073                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16074                try {
16075                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16076                            null);
16077                } catch (PackageManagerException e) {
16078                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16079                            + e.getMessage());
16080                    return;
16081                }
16082
16083                synchronized (mPackages) {
16084                    // Ensure the installer package name up to date
16085                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16086
16087                    // Update permissions for restored package
16088                    mPermissionManager.updatePermissions(
16089                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16090                            mPermissionCallback);
16091
16092                    mSettings.writeLPr();
16093                }
16094
16095                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16096            }
16097        } else {
16098            synchronized (mPackages) {
16099                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16100                if (ps != null) {
16101                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16102                    if (res.removedInfo.removedChildPackages != null) {
16103                        final int childCount = res.removedInfo.removedChildPackages.size();
16104                        // Iterate in reverse as we may modify the collection
16105                        for (int i = childCount - 1; i >= 0; i--) {
16106                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16107                            if (res.addedChildPackages.containsKey(childPackageName)) {
16108                                res.removedInfo.removedChildPackages.removeAt(i);
16109                            } else {
16110                                PackageRemovedInfo childInfo = res.removedInfo
16111                                        .removedChildPackages.valueAt(i);
16112                                childInfo.removedForAllUsers = mPackages.get(
16113                                        childInfo.removedPackage) == null;
16114                            }
16115                        }
16116                    }
16117                }
16118            }
16119        }
16120    }
16121
16122    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16123            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16124            final @ScanFlags int scanFlags, UserHandle user,
16125            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16126            int installReason) {
16127        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16128                + ", old=" + deletedPackage);
16129
16130        final boolean disabledSystem;
16131
16132        // Remove existing system package
16133        removePackageLI(deletedPackage, true);
16134
16135        synchronized (mPackages) {
16136            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16137        }
16138        if (!disabledSystem) {
16139            // We didn't need to disable the .apk as a current system package,
16140            // which means we are replacing another update that is already
16141            // installed.  We need to make sure to delete the older one's .apk.
16142            res.removedInfo.args = createInstallArgsForExisting(0,
16143                    deletedPackage.applicationInfo.getCodePath(),
16144                    deletedPackage.applicationInfo.getResourcePath(),
16145                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16146        } else {
16147            res.removedInfo.args = null;
16148        }
16149
16150        // Successfully disabled the old package. Now proceed with re-installation
16151        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16152                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16153        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16154
16155        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16156        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16157                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16158
16159        PackageParser.Package newPackage = null;
16160        try {
16161            // Add the package to the internal data structures
16162            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16163
16164            // Set the update and install times
16165            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16166            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16167                    System.currentTimeMillis());
16168
16169            // Update the package dynamic state if succeeded
16170            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16171                // Now that the install succeeded make sure we remove data
16172                // directories for any child package the update removed.
16173                final int deletedChildCount = (deletedPackage.childPackages != null)
16174                        ? deletedPackage.childPackages.size() : 0;
16175                final int newChildCount = (newPackage.childPackages != null)
16176                        ? newPackage.childPackages.size() : 0;
16177                for (int i = 0; i < deletedChildCount; i++) {
16178                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16179                    boolean childPackageDeleted = true;
16180                    for (int j = 0; j < newChildCount; j++) {
16181                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16182                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16183                            childPackageDeleted = false;
16184                            break;
16185                        }
16186                    }
16187                    if (childPackageDeleted) {
16188                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16189                                deletedChildPkg.packageName);
16190                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16191                            PackageRemovedInfo removedChildRes = res.removedInfo
16192                                    .removedChildPackages.get(deletedChildPkg.packageName);
16193                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16194                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16195                        }
16196                    }
16197                }
16198
16199                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16200                        installReason);
16201                prepareAppDataAfterInstallLIF(newPackage);
16202
16203                mDexManager.notifyPackageUpdated(newPackage.packageName,
16204                            newPackage.baseCodePath, newPackage.splitCodePaths);
16205            }
16206        } catch (PackageManagerException e) {
16207            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16208            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16209        }
16210
16211        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16212            // Re installation failed. Restore old information
16213            // Remove new pkg information
16214            if (newPackage != null) {
16215                removeInstalledPackageLI(newPackage, true);
16216            }
16217            // Add back the old system package
16218            try {
16219                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16220            } catch (PackageManagerException e) {
16221                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16222            }
16223
16224            synchronized (mPackages) {
16225                if (disabledSystem) {
16226                    enableSystemPackageLPw(deletedPackage);
16227                }
16228
16229                // Ensure the installer package name up to date
16230                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16231
16232                // Update permissions for restored package
16233                mPermissionManager.updatePermissions(
16234                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16235                        mPermissionCallback);
16236
16237                mSettings.writeLPr();
16238            }
16239
16240            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16241                    + " after failed upgrade");
16242        }
16243    }
16244
16245    /**
16246     * Checks whether the parent or any of the child packages have a change shared
16247     * user. For a package to be a valid update the shred users of the parent and
16248     * the children should match. We may later support changing child shared users.
16249     * @param oldPkg The updated package.
16250     * @param newPkg The update package.
16251     * @return The shared user that change between the versions.
16252     */
16253    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16254            PackageParser.Package newPkg) {
16255        // Check parent shared user
16256        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16257            return newPkg.packageName;
16258        }
16259        // Check child shared users
16260        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16261        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16262        for (int i = 0; i < newChildCount; i++) {
16263            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16264            // If this child was present, did it have the same shared user?
16265            for (int j = 0; j < oldChildCount; j++) {
16266                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16267                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16268                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16269                    return newChildPkg.packageName;
16270                }
16271            }
16272        }
16273        return null;
16274    }
16275
16276    private void removeNativeBinariesLI(PackageSetting ps) {
16277        // Remove the lib path for the parent package
16278        if (ps != null) {
16279            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16280            // Remove the lib path for the child packages
16281            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16282            for (int i = 0; i < childCount; i++) {
16283                PackageSetting childPs = null;
16284                synchronized (mPackages) {
16285                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16286                }
16287                if (childPs != null) {
16288                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16289                            .legacyNativeLibraryPathString);
16290                }
16291            }
16292        }
16293    }
16294
16295    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16296        // Enable the parent package
16297        mSettings.enableSystemPackageLPw(pkg.packageName);
16298        // Enable the child packages
16299        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16300        for (int i = 0; i < childCount; i++) {
16301            PackageParser.Package childPkg = pkg.childPackages.get(i);
16302            mSettings.enableSystemPackageLPw(childPkg.packageName);
16303        }
16304    }
16305
16306    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16307            PackageParser.Package newPkg) {
16308        // Disable the parent package (parent always replaced)
16309        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16310        // Disable the child packages
16311        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16312        for (int i = 0; i < childCount; i++) {
16313            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16314            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16315            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16316        }
16317        return disabled;
16318    }
16319
16320    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16321            String installerPackageName) {
16322        // Enable the parent package
16323        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16324        // Enable the child packages
16325        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16326        for (int i = 0; i < childCount; i++) {
16327            PackageParser.Package childPkg = pkg.childPackages.get(i);
16328            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16329        }
16330    }
16331
16332    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16333            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16334        // Update the parent package setting
16335        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16336                res, user, installReason);
16337        // Update the child packages setting
16338        final int childCount = (newPackage.childPackages != null)
16339                ? newPackage.childPackages.size() : 0;
16340        for (int i = 0; i < childCount; i++) {
16341            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16342            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16343            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16344                    childRes.origUsers, childRes, user, installReason);
16345        }
16346    }
16347
16348    private void updateSettingsInternalLI(PackageParser.Package pkg,
16349            String installerPackageName, int[] allUsers, int[] installedForUsers,
16350            PackageInstalledInfo res, UserHandle user, int installReason) {
16351        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16352
16353        String pkgName = pkg.packageName;
16354        synchronized (mPackages) {
16355            //write settings. the installStatus will be incomplete at this stage.
16356            //note that the new package setting would have already been
16357            //added to mPackages. It hasn't been persisted yet.
16358            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16359            // TODO: Remove this write? It's also written at the end of this method
16360            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16361            mSettings.writeLPr();
16362            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16363        }
16364
16365        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16366        synchronized (mPackages) {
16367// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16368            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16369                    mPermissionCallback);
16370            // For system-bundled packages, we assume that installing an upgraded version
16371            // of the package implies that the user actually wants to run that new code,
16372            // so we enable the package.
16373            PackageSetting ps = mSettings.mPackages.get(pkgName);
16374            final int userId = user.getIdentifier();
16375            if (ps != null) {
16376                if (isSystemApp(pkg)) {
16377                    if (DEBUG_INSTALL) {
16378                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16379                    }
16380                    // Enable system package for requested users
16381                    if (res.origUsers != null) {
16382                        for (int origUserId : res.origUsers) {
16383                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16384                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16385                                        origUserId, installerPackageName);
16386                            }
16387                        }
16388                    }
16389                    // Also convey the prior install/uninstall state
16390                    if (allUsers != null && installedForUsers != null) {
16391                        for (int currentUserId : allUsers) {
16392                            final boolean installed = ArrayUtils.contains(
16393                                    installedForUsers, currentUserId);
16394                            if (DEBUG_INSTALL) {
16395                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16396                            }
16397                            ps.setInstalled(installed, currentUserId);
16398                        }
16399                        // these install state changes will be persisted in the
16400                        // upcoming call to mSettings.writeLPr().
16401                    }
16402                }
16403                // It's implied that when a user requests installation, they want the app to be
16404                // installed and enabled.
16405                if (userId != UserHandle.USER_ALL) {
16406                    ps.setInstalled(true, userId);
16407                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16408                }
16409
16410                // When replacing an existing package, preserve the original install reason for all
16411                // users that had the package installed before.
16412                final Set<Integer> previousUserIds = new ArraySet<>();
16413                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16414                    final int installReasonCount = res.removedInfo.installReasons.size();
16415                    for (int i = 0; i < installReasonCount; i++) {
16416                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16417                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16418                        ps.setInstallReason(previousInstallReason, previousUserId);
16419                        previousUserIds.add(previousUserId);
16420                    }
16421                }
16422
16423                // Set install reason for users that are having the package newly installed.
16424                if (userId == UserHandle.USER_ALL) {
16425                    for (int currentUserId : sUserManager.getUserIds()) {
16426                        if (!previousUserIds.contains(currentUserId)) {
16427                            ps.setInstallReason(installReason, currentUserId);
16428                        }
16429                    }
16430                } else if (!previousUserIds.contains(userId)) {
16431                    ps.setInstallReason(installReason, userId);
16432                }
16433                mSettings.writeKernelMappingLPr(ps);
16434            }
16435            res.name = pkgName;
16436            res.uid = pkg.applicationInfo.uid;
16437            res.pkg = pkg;
16438            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16439            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16440            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16441            //to update install status
16442            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16443            mSettings.writeLPr();
16444            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16445        }
16446
16447        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16448    }
16449
16450    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16451        try {
16452            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16453            installPackageLI(args, res);
16454        } finally {
16455            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16456        }
16457    }
16458
16459    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16460        final int installFlags = args.installFlags;
16461        final String installerPackageName = args.installerPackageName;
16462        final String volumeUuid = args.volumeUuid;
16463        final File tmpPackageFile = new File(args.getCodePath());
16464        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16465        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16466                || (args.volumeUuid != null));
16467        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16468        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16469        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16470        final boolean virtualPreload =
16471                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16472        boolean replace = false;
16473        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16474        if (args.move != null) {
16475            // moving a complete application; perform an initial scan on the new install location
16476            scanFlags |= SCAN_INITIAL;
16477        }
16478        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16479            scanFlags |= SCAN_DONT_KILL_APP;
16480        }
16481        if (instantApp) {
16482            scanFlags |= SCAN_AS_INSTANT_APP;
16483        }
16484        if (fullApp) {
16485            scanFlags |= SCAN_AS_FULL_APP;
16486        }
16487        if (virtualPreload) {
16488            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16489        }
16490
16491        // Result object to be returned
16492        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16493        res.installerPackageName = installerPackageName;
16494
16495        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16496
16497        // Sanity check
16498        if (instantApp && (forwardLocked || onExternal)) {
16499            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16500                    + " external=" + onExternal);
16501            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16502            return;
16503        }
16504
16505        // Retrieve PackageSettings and parse package
16506        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16507                | PackageParser.PARSE_ENFORCE_CODE
16508                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16509                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16510                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16511        PackageParser pp = new PackageParser();
16512        pp.setSeparateProcesses(mSeparateProcesses);
16513        pp.setDisplayMetrics(mMetrics);
16514        pp.setCallback(mPackageParserCallback);
16515
16516        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16517        final PackageParser.Package pkg;
16518        try {
16519            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16520            DexMetadataHelper.validatePackageDexMetadata(pkg);
16521        } catch (PackageParserException e) {
16522            res.setError("Failed parse during installPackageLI", e);
16523            return;
16524        } finally {
16525            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16526        }
16527
16528        // App targetSdkVersion is below min supported version
16529        if (!forceSdk && pkg.applicationInfo.isTargetingDeprecatedSdkVersion()) {
16530            Slog.w(TAG, "App " + pkg.packageName + " targets deprecated sdk");
16531
16532            res.setError(INSTALL_FAILED_NEWER_SDK,
16533                    "App is targeting deprecated sdk (targetSdkVersion should be at least "
16534                    + Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT + ").");
16535            return;
16536        }
16537
16538        // Instant apps have several additional install-time checks.
16539        if (instantApp) {
16540            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
16541                Slog.w(TAG,
16542                        "Instant app package " + pkg.packageName + " does not target at least O");
16543                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16544                        "Instant app package must target at least O");
16545                return;
16546            }
16547            if (pkg.applicationInfo.targetSandboxVersion != 2) {
16548                Slog.w(TAG, "Instant app package " + pkg.packageName
16549                        + " does not target targetSandboxVersion 2");
16550                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16551                        "Instant app package must use targetSandboxVersion 2");
16552                return;
16553            }
16554            if (pkg.mSharedUserId != null) {
16555                Slog.w(TAG, "Instant app package " + pkg.packageName
16556                        + " may not declare sharedUserId.");
16557                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16558                        "Instant app package may not declare a sharedUserId");
16559                return;
16560            }
16561        }
16562
16563        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16564            // Static shared libraries have synthetic package names
16565            renameStaticSharedLibraryPackage(pkg);
16566
16567            // No static shared libs on external storage
16568            if (onExternal) {
16569                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16570                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16571                        "Packages declaring static-shared libs cannot be updated");
16572                return;
16573            }
16574        }
16575
16576        // If we are installing a clustered package add results for the children
16577        if (pkg.childPackages != null) {
16578            synchronized (mPackages) {
16579                final int childCount = pkg.childPackages.size();
16580                for (int i = 0; i < childCount; i++) {
16581                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16582                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16583                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16584                    childRes.pkg = childPkg;
16585                    childRes.name = childPkg.packageName;
16586                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16587                    if (childPs != null) {
16588                        childRes.origUsers = childPs.queryInstalledUsers(
16589                                sUserManager.getUserIds(), true);
16590                    }
16591                    if ((mPackages.containsKey(childPkg.packageName))) {
16592                        childRes.removedInfo = new PackageRemovedInfo(this);
16593                        childRes.removedInfo.removedPackage = childPkg.packageName;
16594                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16595                    }
16596                    if (res.addedChildPackages == null) {
16597                        res.addedChildPackages = new ArrayMap<>();
16598                    }
16599                    res.addedChildPackages.put(childPkg.packageName, childRes);
16600                }
16601            }
16602        }
16603
16604        // If package doesn't declare API override, mark that we have an install
16605        // time CPU ABI override.
16606        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16607            pkg.cpuAbiOverride = args.abiOverride;
16608        }
16609
16610        String pkgName = res.name = pkg.packageName;
16611        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16612            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16613                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16614                return;
16615            }
16616        }
16617
16618        try {
16619            // either use what we've been given or parse directly from the APK
16620            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16621                pkg.setSigningDetails(args.signingDetails);
16622            } else {
16623                PackageParser.collectCertificates(pkg, parseFlags);
16624            }
16625        } catch (PackageParserException e) {
16626            res.setError("Failed collect during installPackageLI", e);
16627            return;
16628        }
16629
16630        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
16631                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16632            Slog.w(TAG, "Instant app package " + pkg.packageName
16633                    + " is not signed with at least APK Signature Scheme v2");
16634            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16635                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
16636            return;
16637        }
16638
16639        // Get rid of all references to package scan path via parser.
16640        pp = null;
16641        String oldCodePath = null;
16642        boolean systemApp = false;
16643        synchronized (mPackages) {
16644            // Check if installing already existing package
16645            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16646                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16647                if (pkg.mOriginalPackages != null
16648                        && pkg.mOriginalPackages.contains(oldName)
16649                        && mPackages.containsKey(oldName)) {
16650                    // This package is derived from an original package,
16651                    // and this device has been updating from that original
16652                    // name.  We must continue using the original name, so
16653                    // rename the new package here.
16654                    pkg.setPackageName(oldName);
16655                    pkgName = pkg.packageName;
16656                    replace = true;
16657                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16658                            + oldName + " pkgName=" + pkgName);
16659                } else if (mPackages.containsKey(pkgName)) {
16660                    // This package, under its official name, already exists
16661                    // on the device; we should replace it.
16662                    replace = true;
16663                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16664                }
16665
16666                // Child packages are installed through the parent package
16667                if (pkg.parentPackage != null) {
16668                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16669                            "Package " + pkg.packageName + " is child of package "
16670                                    + pkg.parentPackage.parentPackage + ". Child packages "
16671                                    + "can be updated only through the parent package.");
16672                    return;
16673                }
16674
16675                if (replace) {
16676                    // Prevent apps opting out from runtime permissions
16677                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16678                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16679                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16680                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16681                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16682                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16683                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16684                                        + " doesn't support runtime permissions but the old"
16685                                        + " target SDK " + oldTargetSdk + " does.");
16686                        return;
16687                    }
16688                    // Prevent persistent apps from being updated
16689                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16690                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16691                                "Package " + oldPackage.packageName + " is a persistent app. "
16692                                        + "Persistent apps are not updateable.");
16693                        return;
16694                    }
16695                    // Prevent apps from downgrading their targetSandbox.
16696                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16697                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16698                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16699                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16700                                "Package " + pkg.packageName + " new target sandbox "
16701                                + newTargetSandbox + " is incompatible with the previous value of"
16702                                + oldTargetSandbox + ".");
16703                        return;
16704                    }
16705
16706                    // Prevent installing of child packages
16707                    if (oldPackage.parentPackage != null) {
16708                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16709                                "Package " + pkg.packageName + " is child of package "
16710                                        + oldPackage.parentPackage + ". Child packages "
16711                                        + "can be updated only through the parent package.");
16712                        return;
16713                    }
16714                }
16715            }
16716
16717            PackageSetting ps = mSettings.mPackages.get(pkgName);
16718            if (ps != null) {
16719                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16720
16721                // Static shared libs have same package with different versions where
16722                // we internally use a synthetic package name to allow multiple versions
16723                // of the same package, therefore we need to compare signatures against
16724                // the package setting for the latest library version.
16725                PackageSetting signatureCheckPs = ps;
16726                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16727                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16728                    if (libraryEntry != null) {
16729                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16730                    }
16731                }
16732
16733                // Quick sanity check that we're signed correctly if updating;
16734                // we'll check this again later when scanning, but we want to
16735                // bail early here before tripping over redefined permissions.
16736                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16737                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16738                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16739                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16740                                + pkg.packageName + " upgrade keys do not match the "
16741                                + "previously installed version");
16742                        return;
16743                    }
16744                } else {
16745                    try {
16746                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16747                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16748                        // We don't care about disabledPkgSetting on install for now.
16749                        final boolean compatMatch = verifySignatures(
16750                                signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
16751                                compareRecover);
16752                        // The new KeySets will be re-added later in the scanning process.
16753                        if (compatMatch) {
16754                            synchronized (mPackages) {
16755                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16756                            }
16757                        }
16758                    } catch (PackageManagerException e) {
16759                        res.setError(e.error, e.getMessage());
16760                        return;
16761                    }
16762                }
16763
16764                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16765                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16766                    systemApp = (ps.pkg.applicationInfo.flags &
16767                            ApplicationInfo.FLAG_SYSTEM) != 0;
16768                }
16769                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16770            }
16771
16772            int N = pkg.permissions.size();
16773            for (int i = N-1; i >= 0; i--) {
16774                final PackageParser.Permission perm = pkg.permissions.get(i);
16775                final BasePermission bp =
16776                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
16777
16778                // Don't allow anyone but the system to define ephemeral permissions.
16779                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16780                        && !systemApp) {
16781                    Slog.w(TAG, "Non-System package " + pkg.packageName
16782                            + " attempting to delcare ephemeral permission "
16783                            + perm.info.name + "; Removing ephemeral.");
16784                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
16785                }
16786
16787                // Check whether the newly-scanned package wants to define an already-defined perm
16788                if (bp != null) {
16789                    // If the defining package is signed with our cert, it's okay.  This
16790                    // also includes the "updating the same package" case, of course.
16791                    // "updating same package" could also involve key-rotation.
16792                    final boolean sigsOk;
16793                    final String sourcePackageName = bp.getSourcePackageName();
16794                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16795                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16796                    if (sourcePackageName.equals(pkg.packageName)
16797                            && (ksms.shouldCheckUpgradeKeySetLocked(
16798                                    sourcePackageSetting, scanFlags))) {
16799                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
16800                    } else {
16801                        sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
16802                                pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH;
16803                    }
16804                    if (!sigsOk) {
16805                        // If the owning package is the system itself, we log but allow
16806                        // install to proceed; we fail the install on all other permission
16807                        // redefinitions.
16808                        if (!sourcePackageName.equals("android")) {
16809                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16810                                    + pkg.packageName + " attempting to redeclare permission "
16811                                    + perm.info.name + " already owned by " + sourcePackageName);
16812                            res.origPermission = perm.info.name;
16813                            res.origPackage = sourcePackageName;
16814                            return;
16815                        } else {
16816                            Slog.w(TAG, "Package " + pkg.packageName
16817                                    + " attempting to redeclare system permission "
16818                                    + perm.info.name + "; ignoring new declaration");
16819                            pkg.permissions.remove(i);
16820                        }
16821                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16822                        // Prevent apps to change protection level to dangerous from any other
16823                        // type as this would allow a privilege escalation where an app adds a
16824                        // normal/signature permission in other app's group and later redefines
16825                        // it as dangerous leading to the group auto-grant.
16826                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16827                                == PermissionInfo.PROTECTION_DANGEROUS) {
16828                            if (bp != null && !bp.isRuntime()) {
16829                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16830                                        + "non-runtime permission " + perm.info.name
16831                                        + " to runtime; keeping old protection level");
16832                                perm.info.protectionLevel = bp.getProtectionLevel();
16833                            }
16834                        }
16835                    }
16836                }
16837            }
16838        }
16839
16840        if (systemApp) {
16841            if (onExternal) {
16842                // Abort update; system app can't be replaced with app on sdcard
16843                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16844                        "Cannot install updates to system apps on sdcard");
16845                return;
16846            } else if (instantApp) {
16847                // Abort update; system app can't be replaced with an instant app
16848                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16849                        "Cannot update a system app with an instant app");
16850                return;
16851            }
16852        }
16853
16854        if (args.move != null) {
16855            // We did an in-place move, so dex is ready to roll
16856            scanFlags |= SCAN_NO_DEX;
16857            scanFlags |= SCAN_MOVE;
16858
16859            synchronized (mPackages) {
16860                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16861                if (ps == null) {
16862                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16863                            "Missing settings for moved package " + pkgName);
16864                }
16865
16866                // We moved the entire application as-is, so bring over the
16867                // previously derived ABI information.
16868                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16869                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16870            }
16871
16872        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16873            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16874            scanFlags |= SCAN_NO_DEX;
16875
16876            try {
16877                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16878                    args.abiOverride : pkg.cpuAbiOverride);
16879                final boolean extractNativeLibs = !pkg.isLibrary();
16880                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
16881            } catch (PackageManagerException pme) {
16882                Slog.e(TAG, "Error deriving application ABI", pme);
16883                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16884                return;
16885            }
16886
16887            // Shared libraries for the package need to be updated.
16888            synchronized (mPackages) {
16889                try {
16890                    updateSharedLibrariesLPr(pkg, null);
16891                } catch (PackageManagerException e) {
16892                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16893                }
16894            }
16895        }
16896
16897        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16898            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16899            return;
16900        }
16901
16902        if (!instantApp) {
16903            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16904        } else {
16905            if (DEBUG_DOMAIN_VERIFICATION) {
16906                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16907            }
16908        }
16909
16910        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16911                "installPackageLI")) {
16912            if (replace) {
16913                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16914                    // Static libs have a synthetic package name containing the version
16915                    // and cannot be updated as an update would get a new package name,
16916                    // unless this is the exact same version code which is useful for
16917                    // development.
16918                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16919                    if (existingPkg != null &&
16920                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
16921                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16922                                + "static-shared libs cannot be updated");
16923                        return;
16924                    }
16925                }
16926                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
16927                        installerPackageName, res, args.installReason);
16928            } else {
16929                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16930                        args.user, installerPackageName, volumeUuid, res, args.installReason);
16931            }
16932        }
16933
16934        // Check whether we need to dexopt the app.
16935        //
16936        // NOTE: it is IMPORTANT to call dexopt:
16937        //   - after doRename which will sync the package data from PackageParser.Package and its
16938        //     corresponding ApplicationInfo.
16939        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
16940        //     uid of the application (pkg.applicationInfo.uid).
16941        //     This update happens in place!
16942        //
16943        // We only need to dexopt if the package meets ALL of the following conditions:
16944        //   1) it is not forward locked.
16945        //   2) it is not on on an external ASEC container.
16946        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
16947        //
16948        // Note that we do not dexopt instant apps by default. dexopt can take some time to
16949        // complete, so we skip this step during installation. Instead, we'll take extra time
16950        // the first time the instant app starts. It's preferred to do it this way to provide
16951        // continuous progress to the useur instead of mysteriously blocking somewhere in the
16952        // middle of running an instant app. The default behaviour can be overridden
16953        // via gservices.
16954        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
16955                && !forwardLocked
16956                && !pkg.applicationInfo.isExternalAsec()
16957                && (!instantApp || Global.getInt(mContext.getContentResolver(),
16958                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
16959
16960        if (performDexopt) {
16961            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16962            // Do not run PackageDexOptimizer through the local performDexOpt
16963            // method because `pkg` may not be in `mPackages` yet.
16964            //
16965            // Also, don't fail application installs if the dexopt step fails.
16966            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
16967                    REASON_INSTALL,
16968                    DexoptOptions.DEXOPT_BOOT_COMPLETE);
16969            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16970                    null /* instructionSets */,
16971                    getOrCreateCompilerPackageStats(pkg),
16972                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
16973                    dexoptOptions);
16974            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16975        }
16976
16977        // Notify BackgroundDexOptService that the package has been changed.
16978        // If this is an update of a package which used to fail to compile,
16979        // BackgroundDexOptService will remove it from its blacklist.
16980        // TODO: Layering violation
16981        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
16982
16983        synchronized (mPackages) {
16984            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16985            if (ps != null) {
16986                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16987                ps.setUpdateAvailable(false /*updateAvailable*/);
16988            }
16989
16990            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16991            for (int i = 0; i < childCount; i++) {
16992                PackageParser.Package childPkg = pkg.childPackages.get(i);
16993                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16994                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16995                if (childPs != null) {
16996                    childRes.newUsers = childPs.queryInstalledUsers(
16997                            sUserManager.getUserIds(), true);
16998                }
16999            }
17000
17001            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17002                updateSequenceNumberLP(ps, res.newUsers);
17003                updateInstantAppInstallerLocked(pkgName);
17004            }
17005        }
17006    }
17007
17008    private void startIntentFilterVerifications(int userId, boolean replacing,
17009            PackageParser.Package pkg) {
17010        if (mIntentFilterVerifierComponent == null) {
17011            Slog.w(TAG, "No IntentFilter verification will not be done as "
17012                    + "there is no IntentFilterVerifier available!");
17013            return;
17014        }
17015
17016        final int verifierUid = getPackageUid(
17017                mIntentFilterVerifierComponent.getPackageName(),
17018                MATCH_DEBUG_TRIAGED_MISSING,
17019                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17020
17021        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17022        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17023        mHandler.sendMessage(msg);
17024
17025        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17026        for (int i = 0; i < childCount; i++) {
17027            PackageParser.Package childPkg = pkg.childPackages.get(i);
17028            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17029            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17030            mHandler.sendMessage(msg);
17031        }
17032    }
17033
17034    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17035            PackageParser.Package pkg) {
17036        int size = pkg.activities.size();
17037        if (size == 0) {
17038            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17039                    "No activity, so no need to verify any IntentFilter!");
17040            return;
17041        }
17042
17043        final boolean hasDomainURLs = hasDomainURLs(pkg);
17044        if (!hasDomainURLs) {
17045            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17046                    "No domain URLs, so no need to verify any IntentFilter!");
17047            return;
17048        }
17049
17050        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17051                + " if any IntentFilter from the " + size
17052                + " Activities needs verification ...");
17053
17054        int count = 0;
17055        final String packageName = pkg.packageName;
17056
17057        synchronized (mPackages) {
17058            // If this is a new install and we see that we've already run verification for this
17059            // package, we have nothing to do: it means the state was restored from backup.
17060            if (!replacing) {
17061                IntentFilterVerificationInfo ivi =
17062                        mSettings.getIntentFilterVerificationLPr(packageName);
17063                if (ivi != null) {
17064                    if (DEBUG_DOMAIN_VERIFICATION) {
17065                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17066                                + ivi.getStatusString());
17067                    }
17068                    return;
17069                }
17070            }
17071
17072            // If any filters need to be verified, then all need to be.
17073            boolean needToVerify = false;
17074            for (PackageParser.Activity a : pkg.activities) {
17075                for (ActivityIntentInfo filter : a.intents) {
17076                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17077                        if (DEBUG_DOMAIN_VERIFICATION) {
17078                            Slog.d(TAG,
17079                                    "Intent filter needs verification, so processing all filters");
17080                        }
17081                        needToVerify = true;
17082                        break;
17083                    }
17084                }
17085            }
17086
17087            if (needToVerify) {
17088                final int verificationId = mIntentFilterVerificationToken++;
17089                for (PackageParser.Activity a : pkg.activities) {
17090                    for (ActivityIntentInfo filter : a.intents) {
17091                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17092                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17093                                    "Verification needed for IntentFilter:" + filter.toString());
17094                            mIntentFilterVerifier.addOneIntentFilterVerification(
17095                                    verifierUid, userId, verificationId, filter, packageName);
17096                            count++;
17097                        }
17098                    }
17099                }
17100            }
17101        }
17102
17103        if (count > 0) {
17104            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17105                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17106                    +  " for userId:" + userId);
17107            mIntentFilterVerifier.startVerifications(userId);
17108        } else {
17109            if (DEBUG_DOMAIN_VERIFICATION) {
17110                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17111            }
17112        }
17113    }
17114
17115    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17116        final ComponentName cn  = filter.activity.getComponentName();
17117        final String packageName = cn.getPackageName();
17118
17119        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17120                packageName);
17121        if (ivi == null) {
17122            return true;
17123        }
17124        int status = ivi.getStatus();
17125        switch (status) {
17126            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17127            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17128                return true;
17129
17130            default:
17131                // Nothing to do
17132                return false;
17133        }
17134    }
17135
17136    private static boolean isMultiArch(ApplicationInfo info) {
17137        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17138    }
17139
17140    private static boolean isExternal(PackageParser.Package pkg) {
17141        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17142    }
17143
17144    private static boolean isExternal(PackageSetting ps) {
17145        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17146    }
17147
17148    private static boolean isSystemApp(PackageParser.Package pkg) {
17149        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17150    }
17151
17152    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17153        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17154    }
17155
17156    private static boolean isOemApp(PackageParser.Package pkg) {
17157        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17158    }
17159
17160    private static boolean isVendorApp(PackageParser.Package pkg) {
17161        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17162    }
17163
17164    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17165        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17166    }
17167
17168    private static boolean isSystemApp(PackageSetting ps) {
17169        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17170    }
17171
17172    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17173        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17174    }
17175
17176    private int packageFlagsToInstallFlags(PackageSetting ps) {
17177        int installFlags = 0;
17178        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17179            // This existing package was an external ASEC install when we have
17180            // the external flag without a UUID
17181            installFlags |= PackageManager.INSTALL_EXTERNAL;
17182        }
17183        if (ps.isForwardLocked()) {
17184            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17185        }
17186        return installFlags;
17187    }
17188
17189    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17190        if (isExternal(pkg)) {
17191            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17192                return mSettings.getExternalVersion();
17193            } else {
17194                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17195            }
17196        } else {
17197            return mSettings.getInternalVersion();
17198        }
17199    }
17200
17201    private void deleteTempPackageFiles() {
17202        final FilenameFilter filter = new FilenameFilter() {
17203            public boolean accept(File dir, String name) {
17204                return name.startsWith("vmdl") && name.endsWith(".tmp");
17205            }
17206        };
17207        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17208            file.delete();
17209        }
17210    }
17211
17212    @Override
17213    public void deletePackageAsUser(String packageName, int versionCode,
17214            IPackageDeleteObserver observer, int userId, int flags) {
17215        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17216                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17217    }
17218
17219    @Override
17220    public void deletePackageVersioned(VersionedPackage versionedPackage,
17221            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17222        final int callingUid = Binder.getCallingUid();
17223        mContext.enforceCallingOrSelfPermission(
17224                android.Manifest.permission.DELETE_PACKAGES, null);
17225        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17226        Preconditions.checkNotNull(versionedPackage);
17227        Preconditions.checkNotNull(observer);
17228        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17229                PackageManager.VERSION_CODE_HIGHEST,
17230                Long.MAX_VALUE, "versionCode must be >= -1");
17231
17232        final String packageName = versionedPackage.getPackageName();
17233        final long versionCode = versionedPackage.getLongVersionCode();
17234        final String internalPackageName;
17235        synchronized (mPackages) {
17236            // Normalize package name to handle renamed packages and static libs
17237            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17238        }
17239
17240        final int uid = Binder.getCallingUid();
17241        if (!isOrphaned(internalPackageName)
17242                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17243            try {
17244                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17245                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17246                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17247                observer.onUserActionRequired(intent);
17248            } catch (RemoteException re) {
17249            }
17250            return;
17251        }
17252        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17253        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17254        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17255            mContext.enforceCallingOrSelfPermission(
17256                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17257                    "deletePackage for user " + userId);
17258        }
17259
17260        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17261            try {
17262                observer.onPackageDeleted(packageName,
17263                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17264            } catch (RemoteException re) {
17265            }
17266            return;
17267        }
17268
17269        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17270            try {
17271                observer.onPackageDeleted(packageName,
17272                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17273            } catch (RemoteException re) {
17274            }
17275            return;
17276        }
17277
17278        if (DEBUG_REMOVE) {
17279            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17280                    + " deleteAllUsers: " + deleteAllUsers + " version="
17281                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17282                    ? "VERSION_CODE_HIGHEST" : versionCode));
17283        }
17284        // Queue up an async operation since the package deletion may take a little while.
17285        mHandler.post(new Runnable() {
17286            public void run() {
17287                mHandler.removeCallbacks(this);
17288                int returnCode;
17289                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17290                boolean doDeletePackage = true;
17291                if (ps != null) {
17292                    final boolean targetIsInstantApp =
17293                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17294                    doDeletePackage = !targetIsInstantApp
17295                            || canViewInstantApps;
17296                }
17297                if (doDeletePackage) {
17298                    if (!deleteAllUsers) {
17299                        returnCode = deletePackageX(internalPackageName, versionCode,
17300                                userId, deleteFlags);
17301                    } else {
17302                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17303                                internalPackageName, users);
17304                        // If nobody is blocking uninstall, proceed with delete for all users
17305                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17306                            returnCode = deletePackageX(internalPackageName, versionCode,
17307                                    userId, deleteFlags);
17308                        } else {
17309                            // Otherwise uninstall individually for users with blockUninstalls=false
17310                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17311                            for (int userId : users) {
17312                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17313                                    returnCode = deletePackageX(internalPackageName, versionCode,
17314                                            userId, userFlags);
17315                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17316                                        Slog.w(TAG, "Package delete failed for user " + userId
17317                                                + ", returnCode " + returnCode);
17318                                    }
17319                                }
17320                            }
17321                            // The app has only been marked uninstalled for certain users.
17322                            // We still need to report that delete was blocked
17323                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17324                        }
17325                    }
17326                } else {
17327                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17328                }
17329                try {
17330                    observer.onPackageDeleted(packageName, returnCode, null);
17331                } catch (RemoteException e) {
17332                    Log.i(TAG, "Observer no longer exists.");
17333                } //end catch
17334            } //end run
17335        });
17336    }
17337
17338    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17339        if (pkg.staticSharedLibName != null) {
17340            return pkg.manifestPackageName;
17341        }
17342        return pkg.packageName;
17343    }
17344
17345    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17346        // Handle renamed packages
17347        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17348        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17349
17350        // Is this a static library?
17351        LongSparseArray<SharedLibraryEntry> versionedLib =
17352                mStaticLibsByDeclaringPackage.get(packageName);
17353        if (versionedLib == null || versionedLib.size() <= 0) {
17354            return packageName;
17355        }
17356
17357        // Figure out which lib versions the caller can see
17358        LongSparseLongArray versionsCallerCanSee = null;
17359        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17360        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17361                && callingAppId != Process.ROOT_UID) {
17362            versionsCallerCanSee = new LongSparseLongArray();
17363            String libName = versionedLib.valueAt(0).info.getName();
17364            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17365            if (uidPackages != null) {
17366                for (String uidPackage : uidPackages) {
17367                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17368                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17369                    if (libIdx >= 0) {
17370                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17371                        versionsCallerCanSee.append(libVersion, libVersion);
17372                    }
17373                }
17374            }
17375        }
17376
17377        // Caller can see nothing - done
17378        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17379            return packageName;
17380        }
17381
17382        // Find the version the caller can see and the app version code
17383        SharedLibraryEntry highestVersion = null;
17384        final int versionCount = versionedLib.size();
17385        for (int i = 0; i < versionCount; i++) {
17386            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17387            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17388                    libEntry.info.getLongVersion()) < 0) {
17389                continue;
17390            }
17391            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17392            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17393                if (libVersionCode == versionCode) {
17394                    return libEntry.apk;
17395                }
17396            } else if (highestVersion == null) {
17397                highestVersion = libEntry;
17398            } else if (libVersionCode  > highestVersion.info
17399                    .getDeclaringPackage().getLongVersionCode()) {
17400                highestVersion = libEntry;
17401            }
17402        }
17403
17404        if (highestVersion != null) {
17405            return highestVersion.apk;
17406        }
17407
17408        return packageName;
17409    }
17410
17411    boolean isCallerVerifier(int callingUid) {
17412        final int callingUserId = UserHandle.getUserId(callingUid);
17413        return mRequiredVerifierPackage != null &&
17414                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17415    }
17416
17417    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17418        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17419              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17420            return true;
17421        }
17422        final int callingUserId = UserHandle.getUserId(callingUid);
17423        // If the caller installed the pkgName, then allow it to silently uninstall.
17424        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17425            return true;
17426        }
17427
17428        // Allow package verifier to silently uninstall.
17429        if (mRequiredVerifierPackage != null &&
17430                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17431            return true;
17432        }
17433
17434        // Allow package uninstaller to silently uninstall.
17435        if (mRequiredUninstallerPackage != null &&
17436                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17437            return true;
17438        }
17439
17440        // Allow storage manager to silently uninstall.
17441        if (mStorageManagerPackage != null &&
17442                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17443            return true;
17444        }
17445
17446        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17447        // uninstall for device owner provisioning.
17448        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17449                == PERMISSION_GRANTED) {
17450            return true;
17451        }
17452
17453        return false;
17454    }
17455
17456    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17457        int[] result = EMPTY_INT_ARRAY;
17458        for (int userId : userIds) {
17459            if (getBlockUninstallForUser(packageName, userId)) {
17460                result = ArrayUtils.appendInt(result, userId);
17461            }
17462        }
17463        return result;
17464    }
17465
17466    @Override
17467    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17468        final int callingUid = Binder.getCallingUid();
17469        if (getInstantAppPackageName(callingUid) != null
17470                && !isCallerSameApp(packageName, callingUid)) {
17471            return false;
17472        }
17473        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17474    }
17475
17476    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17477        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17478                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17479        try {
17480            if (dpm != null) {
17481                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17482                        /* callingUserOnly =*/ false);
17483                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17484                        : deviceOwnerComponentName.getPackageName();
17485                // Does the package contains the device owner?
17486                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17487                // this check is probably not needed, since DO should be registered as a device
17488                // admin on some user too. (Original bug for this: b/17657954)
17489                if (packageName.equals(deviceOwnerPackageName)) {
17490                    return true;
17491                }
17492                // Does it contain a device admin for any user?
17493                int[] users;
17494                if (userId == UserHandle.USER_ALL) {
17495                    users = sUserManager.getUserIds();
17496                } else {
17497                    users = new int[]{userId};
17498                }
17499                for (int i = 0; i < users.length; ++i) {
17500                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17501                        return true;
17502                    }
17503                }
17504            }
17505        } catch (RemoteException e) {
17506        }
17507        return false;
17508    }
17509
17510    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17511        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17512    }
17513
17514    /**
17515     *  This method is an internal method that could be get invoked either
17516     *  to delete an installed package or to clean up a failed installation.
17517     *  After deleting an installed package, a broadcast is sent to notify any
17518     *  listeners that the package has been removed. For cleaning up a failed
17519     *  installation, the broadcast is not necessary since the package's
17520     *  installation wouldn't have sent the initial broadcast either
17521     *  The key steps in deleting a package are
17522     *  deleting the package information in internal structures like mPackages,
17523     *  deleting the packages base directories through installd
17524     *  updating mSettings to reflect current status
17525     *  persisting settings for later use
17526     *  sending a broadcast if necessary
17527     */
17528    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17529        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17530        final boolean res;
17531
17532        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17533                ? UserHandle.USER_ALL : userId;
17534
17535        if (isPackageDeviceAdmin(packageName, removeUser)) {
17536            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17537            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17538        }
17539
17540        PackageSetting uninstalledPs = null;
17541        PackageParser.Package pkg = null;
17542
17543        // for the uninstall-updates case and restricted profiles, remember the per-
17544        // user handle installed state
17545        int[] allUsers;
17546        synchronized (mPackages) {
17547            uninstalledPs = mSettings.mPackages.get(packageName);
17548            if (uninstalledPs == null) {
17549                Slog.w(TAG, "Not removing non-existent package " + packageName);
17550                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17551            }
17552
17553            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17554                    && uninstalledPs.versionCode != versionCode) {
17555                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17556                        + uninstalledPs.versionCode + " != " + versionCode);
17557                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17558            }
17559
17560            // Static shared libs can be declared by any package, so let us not
17561            // allow removing a package if it provides a lib others depend on.
17562            pkg = mPackages.get(packageName);
17563
17564            allUsers = sUserManager.getUserIds();
17565
17566            if (pkg != null && pkg.staticSharedLibName != null) {
17567                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17568                        pkg.staticSharedLibVersion);
17569                if (libEntry != null) {
17570                    for (int currUserId : allUsers) {
17571                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17572                            continue;
17573                        }
17574                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17575                                libEntry.info, 0, currUserId);
17576                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17577                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17578                                    + " hosting lib " + libEntry.info.getName() + " version "
17579                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17580                                    + " for user " + currUserId);
17581                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17582                        }
17583                    }
17584                }
17585            }
17586
17587            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17588        }
17589
17590        final int freezeUser;
17591        if (isUpdatedSystemApp(uninstalledPs)
17592                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17593            // We're downgrading a system app, which will apply to all users, so
17594            // freeze them all during the downgrade
17595            freezeUser = UserHandle.USER_ALL;
17596        } else {
17597            freezeUser = removeUser;
17598        }
17599
17600        synchronized (mInstallLock) {
17601            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17602            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17603                    deleteFlags, "deletePackageX")) {
17604                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17605                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17606            }
17607            synchronized (mPackages) {
17608                if (res) {
17609                    if (pkg != null) {
17610                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17611                    }
17612                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17613                    updateInstantAppInstallerLocked(packageName);
17614                }
17615            }
17616        }
17617
17618        if (res) {
17619            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17620            info.sendPackageRemovedBroadcasts(killApp);
17621            info.sendSystemPackageUpdatedBroadcasts();
17622            info.sendSystemPackageAppearedBroadcasts();
17623        }
17624        // Force a gc here.
17625        Runtime.getRuntime().gc();
17626        // Delete the resources here after sending the broadcast to let
17627        // other processes clean up before deleting resources.
17628        if (info.args != null) {
17629            synchronized (mInstallLock) {
17630                info.args.doPostDeleteLI(true);
17631            }
17632        }
17633
17634        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17635    }
17636
17637    static class PackageRemovedInfo {
17638        final PackageSender packageSender;
17639        String removedPackage;
17640        String installerPackageName;
17641        int uid = -1;
17642        int removedAppId = -1;
17643        int[] origUsers;
17644        int[] removedUsers = null;
17645        int[] broadcastUsers = null;
17646        int[] instantUserIds = null;
17647        SparseArray<Integer> installReasons;
17648        boolean isRemovedPackageSystemUpdate = false;
17649        boolean isUpdate;
17650        boolean dataRemoved;
17651        boolean removedForAllUsers;
17652        boolean isStaticSharedLib;
17653        // Clean up resources deleted packages.
17654        InstallArgs args = null;
17655        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17656        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17657
17658        PackageRemovedInfo(PackageSender packageSender) {
17659            this.packageSender = packageSender;
17660        }
17661
17662        void sendPackageRemovedBroadcasts(boolean killApp) {
17663            sendPackageRemovedBroadcastInternal(killApp);
17664            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17665            for (int i = 0; i < childCount; i++) {
17666                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17667                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17668            }
17669        }
17670
17671        void sendSystemPackageUpdatedBroadcasts() {
17672            if (isRemovedPackageSystemUpdate) {
17673                sendSystemPackageUpdatedBroadcastsInternal();
17674                final int childCount = (removedChildPackages != null)
17675                        ? removedChildPackages.size() : 0;
17676                for (int i = 0; i < childCount; i++) {
17677                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17678                    if (childInfo.isRemovedPackageSystemUpdate) {
17679                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17680                    }
17681                }
17682            }
17683        }
17684
17685        void sendSystemPackageAppearedBroadcasts() {
17686            final int packageCount = (appearedChildPackages != null)
17687                    ? appearedChildPackages.size() : 0;
17688            for (int i = 0; i < packageCount; i++) {
17689                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17690                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17691                    true /*sendBootCompleted*/, false /*startReceiver*/,
17692                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17693            }
17694        }
17695
17696        private void sendSystemPackageUpdatedBroadcastsInternal() {
17697            Bundle extras = new Bundle(2);
17698            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17699            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17700            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17701                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17702            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17703                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17704            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17705                null, null, 0, removedPackage, null, null, null);
17706            if (installerPackageName != null) {
17707                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17708                        removedPackage, extras, 0 /*flags*/,
17709                        installerPackageName, null, null, null);
17710                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17711                        removedPackage, extras, 0 /*flags*/,
17712                        installerPackageName, null, null, null);
17713            }
17714        }
17715
17716        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17717            // Don't send static shared library removal broadcasts as these
17718            // libs are visible only the the apps that depend on them an one
17719            // cannot remove the library if it has a dependency.
17720            if (isStaticSharedLib) {
17721                return;
17722            }
17723            Bundle extras = new Bundle(2);
17724            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17725            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17726            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17727            if (isUpdate || isRemovedPackageSystemUpdate) {
17728                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17729            }
17730            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17731            if (removedPackage != null) {
17732                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17733                    removedPackage, extras, 0, null /*targetPackage*/, null,
17734                    broadcastUsers, instantUserIds);
17735                if (installerPackageName != null) {
17736                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17737                            removedPackage, extras, 0 /*flags*/,
17738                            installerPackageName, null, broadcastUsers, instantUserIds);
17739                }
17740                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17741                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17742                        removedPackage, extras,
17743                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17744                        null, null, broadcastUsers, instantUserIds);
17745                    packageSender.notifyPackageRemoved(removedPackage);
17746                }
17747            }
17748            if (removedAppId >= 0) {
17749                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17750                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17751                    null, null, broadcastUsers, instantUserIds);
17752            }
17753        }
17754
17755        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17756            removedUsers = userIds;
17757            if (removedUsers == null) {
17758                broadcastUsers = null;
17759                return;
17760            }
17761
17762            broadcastUsers = EMPTY_INT_ARRAY;
17763            instantUserIds = EMPTY_INT_ARRAY;
17764            for (int i = userIds.length - 1; i >= 0; --i) {
17765                final int userId = userIds[i];
17766                if (deletedPackageSetting.getInstantApp(userId)) {
17767                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17768                } else {
17769                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17770                }
17771            }
17772        }
17773    }
17774
17775    /*
17776     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17777     * flag is not set, the data directory is removed as well.
17778     * make sure this flag is set for partially installed apps. If not its meaningless to
17779     * delete a partially installed application.
17780     */
17781    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17782            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17783        String packageName = ps.name;
17784        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17785        // Retrieve object to delete permissions for shared user later on
17786        final PackageParser.Package deletedPkg;
17787        final PackageSetting deletedPs;
17788        // reader
17789        synchronized (mPackages) {
17790            deletedPkg = mPackages.get(packageName);
17791            deletedPs = mSettings.mPackages.get(packageName);
17792            if (outInfo != null) {
17793                outInfo.removedPackage = packageName;
17794                outInfo.installerPackageName = ps.installerPackageName;
17795                outInfo.isStaticSharedLib = deletedPkg != null
17796                        && deletedPkg.staticSharedLibName != null;
17797                outInfo.populateUsers(deletedPs == null ? null
17798                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17799            }
17800        }
17801
17802        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
17803
17804        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17805            final PackageParser.Package resolvedPkg;
17806            if (deletedPkg != null) {
17807                resolvedPkg = deletedPkg;
17808            } else {
17809                // We don't have a parsed package when it lives on an ejected
17810                // adopted storage device, so fake something together
17811                resolvedPkg = new PackageParser.Package(ps.name);
17812                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17813            }
17814            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17815                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17816            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17817            if (outInfo != null) {
17818                outInfo.dataRemoved = true;
17819            }
17820            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17821        }
17822
17823        int removedAppId = -1;
17824
17825        // writer
17826        synchronized (mPackages) {
17827            boolean installedStateChanged = false;
17828            if (deletedPs != null) {
17829                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17830                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17831                    clearDefaultBrowserIfNeeded(packageName);
17832                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17833                    removedAppId = mSettings.removePackageLPw(packageName);
17834                    if (outInfo != null) {
17835                        outInfo.removedAppId = removedAppId;
17836                    }
17837                    mPermissionManager.updatePermissions(
17838                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
17839                    if (deletedPs.sharedUser != null) {
17840                        // Remove permissions associated with package. Since runtime
17841                        // permissions are per user we have to kill the removed package
17842                        // or packages running under the shared user of the removed
17843                        // package if revoking the permissions requested only by the removed
17844                        // package is successful and this causes a change in gids.
17845                        for (int userId : UserManagerService.getInstance().getUserIds()) {
17846                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17847                                    userId);
17848                            if (userIdToKill == UserHandle.USER_ALL
17849                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
17850                                // If gids changed for this user, kill all affected packages.
17851                                mHandler.post(new Runnable() {
17852                                    @Override
17853                                    public void run() {
17854                                        // This has to happen with no lock held.
17855                                        killApplication(deletedPs.name, deletedPs.appId,
17856                                                KILL_APP_REASON_GIDS_CHANGED);
17857                                    }
17858                                });
17859                                break;
17860                            }
17861                        }
17862                    }
17863                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17864                }
17865                // make sure to preserve per-user disabled state if this removal was just
17866                // a downgrade of a system app to the factory package
17867                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17868                    if (DEBUG_REMOVE) {
17869                        Slog.d(TAG, "Propagating install state across downgrade");
17870                    }
17871                    for (int userId : allUserHandles) {
17872                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17873                        if (DEBUG_REMOVE) {
17874                            Slog.d(TAG, "    user " + userId + " => " + installed);
17875                        }
17876                        if (installed != ps.getInstalled(userId)) {
17877                            installedStateChanged = true;
17878                        }
17879                        ps.setInstalled(installed, userId);
17880                    }
17881                }
17882            }
17883            // can downgrade to reader
17884            if (writeSettings) {
17885                // Save settings now
17886                mSettings.writeLPr();
17887            }
17888            if (installedStateChanged) {
17889                mSettings.writeKernelMappingLPr(ps);
17890            }
17891        }
17892        if (removedAppId != -1) {
17893            // A user ID was deleted here. Go through all users and remove it
17894            // from KeyStore.
17895            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17896        }
17897    }
17898
17899    static boolean locationIsPrivileged(String path) {
17900        try {
17901            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
17902            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
17903            return path.startsWith(privilegedAppDir.getCanonicalPath())
17904                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath());
17905        } catch (IOException e) {
17906            Slog.e(TAG, "Unable to access code path " + path);
17907        }
17908        return false;
17909    }
17910
17911    static boolean locationIsOem(String path) {
17912        try {
17913            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
17914        } catch (IOException e) {
17915            Slog.e(TAG, "Unable to access code path " + path);
17916        }
17917        return false;
17918    }
17919
17920    static boolean locationIsVendor(String path) {
17921        try {
17922            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
17923        } catch (IOException e) {
17924            Slog.e(TAG, "Unable to access code path " + path);
17925        }
17926        return false;
17927    }
17928
17929    /*
17930     * Tries to delete system package.
17931     */
17932    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17933            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17934            boolean writeSettings) {
17935        if (deletedPs.parentPackageName != null) {
17936            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17937            return false;
17938        }
17939
17940        final boolean applyUserRestrictions
17941                = (allUserHandles != null) && (outInfo.origUsers != null);
17942        final PackageSetting disabledPs;
17943        // Confirm if the system package has been updated
17944        // An updated system app can be deleted. This will also have to restore
17945        // the system pkg from system partition
17946        // reader
17947        synchronized (mPackages) {
17948            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17949        }
17950
17951        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17952                + " disabledPs=" + disabledPs);
17953
17954        if (disabledPs == null) {
17955            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17956            return false;
17957        } else if (DEBUG_REMOVE) {
17958            Slog.d(TAG, "Deleting system pkg from data partition");
17959        }
17960
17961        if (DEBUG_REMOVE) {
17962            if (applyUserRestrictions) {
17963                Slog.d(TAG, "Remembering install states:");
17964                for (int userId : allUserHandles) {
17965                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17966                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
17967                }
17968            }
17969        }
17970
17971        // Delete the updated package
17972        outInfo.isRemovedPackageSystemUpdate = true;
17973        if (outInfo.removedChildPackages != null) {
17974            final int childCount = (deletedPs.childPackageNames != null)
17975                    ? deletedPs.childPackageNames.size() : 0;
17976            for (int i = 0; i < childCount; i++) {
17977                String childPackageName = deletedPs.childPackageNames.get(i);
17978                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17979                        .contains(childPackageName)) {
17980                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17981                            childPackageName);
17982                    if (childInfo != null) {
17983                        childInfo.isRemovedPackageSystemUpdate = true;
17984                    }
17985                }
17986            }
17987        }
17988
17989        if (disabledPs.versionCode < deletedPs.versionCode) {
17990            // Delete data for downgrades
17991            flags &= ~PackageManager.DELETE_KEEP_DATA;
17992        } else {
17993            // Preserve data by setting flag
17994            flags |= PackageManager.DELETE_KEEP_DATA;
17995        }
17996
17997        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17998                outInfo, writeSettings, disabledPs.pkg);
17999        if (!ret) {
18000            return false;
18001        }
18002
18003        // writer
18004        synchronized (mPackages) {
18005            // NOTE: The system package always needs to be enabled; even if it's for
18006            // a compressed stub. If we don't, installing the system package fails
18007            // during scan [scanning checks the disabled packages]. We will reverse
18008            // this later, after we've "installed" the stub.
18009            // Reinstate the old system package
18010            enableSystemPackageLPw(disabledPs.pkg);
18011            // Remove any native libraries from the upgraded package.
18012            removeNativeBinariesLI(deletedPs);
18013        }
18014
18015        // Install the system package
18016        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18017        try {
18018            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18019                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18020        } catch (PackageManagerException e) {
18021            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18022                    + e.getMessage());
18023            return false;
18024        } finally {
18025            if (disabledPs.pkg.isStub) {
18026                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18027            }
18028        }
18029        return true;
18030    }
18031
18032    /**
18033     * Installs a package that's already on the system partition.
18034     */
18035    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18036            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18037            @Nullable PermissionsState origPermissionState, boolean writeSettings)
18038                    throws PackageManagerException {
18039        @ParseFlags int parseFlags =
18040                mDefParseFlags
18041                | PackageParser.PARSE_MUST_BE_APK
18042                | PackageParser.PARSE_IS_SYSTEM_DIR;
18043        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18044        if (isPrivileged || locationIsPrivileged(codePathString)) {
18045            scanFlags |= SCAN_AS_PRIVILEGED;
18046        }
18047        if (locationIsOem(codePathString)) {
18048            scanFlags |= SCAN_AS_OEM;
18049        }
18050        if (locationIsVendor(codePathString)) {
18051            scanFlags |= SCAN_AS_VENDOR;
18052        }
18053
18054        final File codePath = new File(codePathString);
18055        final PackageParser.Package pkg =
18056                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18057
18058        try {
18059            // update shared libraries for the newly re-installed system package
18060            updateSharedLibrariesLPr(pkg, null);
18061        } catch (PackageManagerException e) {
18062            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18063        }
18064
18065        prepareAppDataAfterInstallLIF(pkg);
18066
18067        // writer
18068        synchronized (mPackages) {
18069            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18070
18071            // Propagate the permissions state as we do not want to drop on the floor
18072            // runtime permissions. The update permissions method below will take
18073            // care of removing obsolete permissions and grant install permissions.
18074            if (origPermissionState != null) {
18075                ps.getPermissionsState().copyFrom(origPermissionState);
18076            }
18077            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18078                    mPermissionCallback);
18079
18080            final boolean applyUserRestrictions
18081                    = (allUserHandles != null) && (origUserHandles != null);
18082            if (applyUserRestrictions) {
18083                boolean installedStateChanged = false;
18084                if (DEBUG_REMOVE) {
18085                    Slog.d(TAG, "Propagating install state across reinstall");
18086                }
18087                for (int userId : allUserHandles) {
18088                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18089                    if (DEBUG_REMOVE) {
18090                        Slog.d(TAG, "    user " + userId + " => " + installed);
18091                    }
18092                    if (installed != ps.getInstalled(userId)) {
18093                        installedStateChanged = true;
18094                    }
18095                    ps.setInstalled(installed, userId);
18096
18097                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18098                }
18099                // Regardless of writeSettings we need to ensure that this restriction
18100                // state propagation is persisted
18101                mSettings.writeAllUsersPackageRestrictionsLPr();
18102                if (installedStateChanged) {
18103                    mSettings.writeKernelMappingLPr(ps);
18104                }
18105            }
18106            // can downgrade to reader here
18107            if (writeSettings) {
18108                mSettings.writeLPr();
18109            }
18110        }
18111        return pkg;
18112    }
18113
18114    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18115            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18116            PackageRemovedInfo outInfo, boolean writeSettings,
18117            PackageParser.Package replacingPackage) {
18118        synchronized (mPackages) {
18119            if (outInfo != null) {
18120                outInfo.uid = ps.appId;
18121            }
18122
18123            if (outInfo != null && outInfo.removedChildPackages != null) {
18124                final int childCount = (ps.childPackageNames != null)
18125                        ? ps.childPackageNames.size() : 0;
18126                for (int i = 0; i < childCount; i++) {
18127                    String childPackageName = ps.childPackageNames.get(i);
18128                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18129                    if (childPs == null) {
18130                        return false;
18131                    }
18132                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18133                            childPackageName);
18134                    if (childInfo != null) {
18135                        childInfo.uid = childPs.appId;
18136                    }
18137                }
18138            }
18139        }
18140
18141        // Delete package data from internal structures and also remove data if flag is set
18142        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18143
18144        // Delete the child packages data
18145        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18146        for (int i = 0; i < childCount; i++) {
18147            PackageSetting childPs;
18148            synchronized (mPackages) {
18149                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18150            }
18151            if (childPs != null) {
18152                PackageRemovedInfo childOutInfo = (outInfo != null
18153                        && outInfo.removedChildPackages != null)
18154                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18155                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18156                        && (replacingPackage != null
18157                        && !replacingPackage.hasChildPackage(childPs.name))
18158                        ? flags & ~DELETE_KEEP_DATA : flags;
18159                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18160                        deleteFlags, writeSettings);
18161            }
18162        }
18163
18164        // Delete application code and resources only for parent packages
18165        if (ps.parentPackageName == null) {
18166            if (deleteCodeAndResources && (outInfo != null)) {
18167                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18168                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18169                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18170            }
18171        }
18172
18173        return true;
18174    }
18175
18176    @Override
18177    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18178            int userId) {
18179        mContext.enforceCallingOrSelfPermission(
18180                android.Manifest.permission.DELETE_PACKAGES, null);
18181        synchronized (mPackages) {
18182            // Cannot block uninstall of static shared libs as they are
18183            // considered a part of the using app (emulating static linking).
18184            // Also static libs are installed always on internal storage.
18185            PackageParser.Package pkg = mPackages.get(packageName);
18186            if (pkg != null && pkg.staticSharedLibName != null) {
18187                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18188                        + " providing static shared library: " + pkg.staticSharedLibName);
18189                return false;
18190            }
18191            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18192            mSettings.writePackageRestrictionsLPr(userId);
18193        }
18194        return true;
18195    }
18196
18197    @Override
18198    public boolean getBlockUninstallForUser(String packageName, int userId) {
18199        synchronized (mPackages) {
18200            final PackageSetting ps = mSettings.mPackages.get(packageName);
18201            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18202                return false;
18203            }
18204            return mSettings.getBlockUninstallLPr(userId, packageName);
18205        }
18206    }
18207
18208    @Override
18209    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18210        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18211        synchronized (mPackages) {
18212            PackageSetting ps = mSettings.mPackages.get(packageName);
18213            if (ps == null) {
18214                Log.w(TAG, "Package doesn't exist: " + packageName);
18215                return false;
18216            }
18217            if (systemUserApp) {
18218                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18219            } else {
18220                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18221            }
18222            mSettings.writeLPr();
18223        }
18224        return true;
18225    }
18226
18227    /*
18228     * This method handles package deletion in general
18229     */
18230    private boolean deletePackageLIF(String packageName, UserHandle user,
18231            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18232            PackageRemovedInfo outInfo, boolean writeSettings,
18233            PackageParser.Package replacingPackage) {
18234        if (packageName == null) {
18235            Slog.w(TAG, "Attempt to delete null packageName.");
18236            return false;
18237        }
18238
18239        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18240
18241        PackageSetting ps;
18242        synchronized (mPackages) {
18243            ps = mSettings.mPackages.get(packageName);
18244            if (ps == null) {
18245                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18246                return false;
18247            }
18248
18249            if (ps.parentPackageName != null && (!isSystemApp(ps)
18250                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18251                if (DEBUG_REMOVE) {
18252                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18253                            + ((user == null) ? UserHandle.USER_ALL : user));
18254                }
18255                final int removedUserId = (user != null) ? user.getIdentifier()
18256                        : UserHandle.USER_ALL;
18257                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18258                    return false;
18259                }
18260                markPackageUninstalledForUserLPw(ps, user);
18261                scheduleWritePackageRestrictionsLocked(user);
18262                return true;
18263            }
18264        }
18265
18266        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18267                && user.getIdentifier() != UserHandle.USER_ALL)) {
18268            // The caller is asking that the package only be deleted for a single
18269            // user.  To do this, we just mark its uninstalled state and delete
18270            // its data. If this is a system app, we only allow this to happen if
18271            // they have set the special DELETE_SYSTEM_APP which requests different
18272            // semantics than normal for uninstalling system apps.
18273            markPackageUninstalledForUserLPw(ps, user);
18274
18275            if (!isSystemApp(ps)) {
18276                // Do not uninstall the APK if an app should be cached
18277                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18278                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18279                    // Other user still have this package installed, so all
18280                    // we need to do is clear this user's data and save that
18281                    // it is uninstalled.
18282                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18283                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18284                        return false;
18285                    }
18286                    scheduleWritePackageRestrictionsLocked(user);
18287                    return true;
18288                } else {
18289                    // We need to set it back to 'installed' so the uninstall
18290                    // broadcasts will be sent correctly.
18291                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18292                    ps.setInstalled(true, user.getIdentifier());
18293                    mSettings.writeKernelMappingLPr(ps);
18294                }
18295            } else {
18296                // This is a system app, so we assume that the
18297                // other users still have this package installed, so all
18298                // we need to do is clear this user's data and save that
18299                // it is uninstalled.
18300                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18301                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18302                    return false;
18303                }
18304                scheduleWritePackageRestrictionsLocked(user);
18305                return true;
18306            }
18307        }
18308
18309        // If we are deleting a composite package for all users, keep track
18310        // of result for each child.
18311        if (ps.childPackageNames != null && outInfo != null) {
18312            synchronized (mPackages) {
18313                final int childCount = ps.childPackageNames.size();
18314                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18315                for (int i = 0; i < childCount; i++) {
18316                    String childPackageName = ps.childPackageNames.get(i);
18317                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18318                    childInfo.removedPackage = childPackageName;
18319                    childInfo.installerPackageName = ps.installerPackageName;
18320                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18321                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18322                    if (childPs != null) {
18323                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18324                    }
18325                }
18326            }
18327        }
18328
18329        boolean ret = false;
18330        if (isSystemApp(ps)) {
18331            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18332            // When an updated system application is deleted we delete the existing resources
18333            // as well and fall back to existing code in system partition
18334            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18335        } else {
18336            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18337            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18338                    outInfo, writeSettings, replacingPackage);
18339        }
18340
18341        // Take a note whether we deleted the package for all users
18342        if (outInfo != null) {
18343            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18344            if (outInfo.removedChildPackages != null) {
18345                synchronized (mPackages) {
18346                    final int childCount = outInfo.removedChildPackages.size();
18347                    for (int i = 0; i < childCount; i++) {
18348                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18349                        if (childInfo != null) {
18350                            childInfo.removedForAllUsers = mPackages.get(
18351                                    childInfo.removedPackage) == null;
18352                        }
18353                    }
18354                }
18355            }
18356            // If we uninstalled an update to a system app there may be some
18357            // child packages that appeared as they are declared in the system
18358            // app but were not declared in the update.
18359            if (isSystemApp(ps)) {
18360                synchronized (mPackages) {
18361                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18362                    final int childCount = (updatedPs.childPackageNames != null)
18363                            ? updatedPs.childPackageNames.size() : 0;
18364                    for (int i = 0; i < childCount; i++) {
18365                        String childPackageName = updatedPs.childPackageNames.get(i);
18366                        if (outInfo.removedChildPackages == null
18367                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18368                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18369                            if (childPs == null) {
18370                                continue;
18371                            }
18372                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18373                            installRes.name = childPackageName;
18374                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18375                            installRes.pkg = mPackages.get(childPackageName);
18376                            installRes.uid = childPs.pkg.applicationInfo.uid;
18377                            if (outInfo.appearedChildPackages == null) {
18378                                outInfo.appearedChildPackages = new ArrayMap<>();
18379                            }
18380                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18381                        }
18382                    }
18383                }
18384            }
18385        }
18386
18387        return ret;
18388    }
18389
18390    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18391        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18392                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18393        for (int nextUserId : userIds) {
18394            if (DEBUG_REMOVE) {
18395                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18396            }
18397            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18398                    false /*installed*/,
18399                    true /*stopped*/,
18400                    true /*notLaunched*/,
18401                    false /*hidden*/,
18402                    false /*suspended*/,
18403                    false /*instantApp*/,
18404                    false /*virtualPreload*/,
18405                    null /*lastDisableAppCaller*/,
18406                    null /*enabledComponents*/,
18407                    null /*disabledComponents*/,
18408                    ps.readUserState(nextUserId).domainVerificationStatus,
18409                    0, PackageManager.INSTALL_REASON_UNKNOWN,
18410                    null /*harmfulAppWarning*/);
18411        }
18412        mSettings.writeKernelMappingLPr(ps);
18413    }
18414
18415    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18416            PackageRemovedInfo outInfo) {
18417        final PackageParser.Package pkg;
18418        synchronized (mPackages) {
18419            pkg = mPackages.get(ps.name);
18420        }
18421
18422        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18423                : new int[] {userId};
18424        for (int nextUserId : userIds) {
18425            if (DEBUG_REMOVE) {
18426                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18427                        + nextUserId);
18428            }
18429
18430            destroyAppDataLIF(pkg, userId,
18431                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18432            destroyAppProfilesLIF(pkg, userId);
18433            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18434            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18435            schedulePackageCleaning(ps.name, nextUserId, false);
18436            synchronized (mPackages) {
18437                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18438                    scheduleWritePackageRestrictionsLocked(nextUserId);
18439                }
18440                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18441            }
18442        }
18443
18444        if (outInfo != null) {
18445            outInfo.removedPackage = ps.name;
18446            outInfo.installerPackageName = ps.installerPackageName;
18447            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18448            outInfo.removedAppId = ps.appId;
18449            outInfo.removedUsers = userIds;
18450            outInfo.broadcastUsers = userIds;
18451        }
18452
18453        return true;
18454    }
18455
18456    private final class ClearStorageConnection implements ServiceConnection {
18457        IMediaContainerService mContainerService;
18458
18459        @Override
18460        public void onServiceConnected(ComponentName name, IBinder service) {
18461            synchronized (this) {
18462                mContainerService = IMediaContainerService.Stub
18463                        .asInterface(Binder.allowBlocking(service));
18464                notifyAll();
18465            }
18466        }
18467
18468        @Override
18469        public void onServiceDisconnected(ComponentName name) {
18470        }
18471    }
18472
18473    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18474        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18475
18476        final boolean mounted;
18477        if (Environment.isExternalStorageEmulated()) {
18478            mounted = true;
18479        } else {
18480            final String status = Environment.getExternalStorageState();
18481
18482            mounted = status.equals(Environment.MEDIA_MOUNTED)
18483                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18484        }
18485
18486        if (!mounted) {
18487            return;
18488        }
18489
18490        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18491        int[] users;
18492        if (userId == UserHandle.USER_ALL) {
18493            users = sUserManager.getUserIds();
18494        } else {
18495            users = new int[] { userId };
18496        }
18497        final ClearStorageConnection conn = new ClearStorageConnection();
18498        if (mContext.bindServiceAsUser(
18499                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18500            try {
18501                for (int curUser : users) {
18502                    long timeout = SystemClock.uptimeMillis() + 5000;
18503                    synchronized (conn) {
18504                        long now;
18505                        while (conn.mContainerService == null &&
18506                                (now = SystemClock.uptimeMillis()) < timeout) {
18507                            try {
18508                                conn.wait(timeout - now);
18509                            } catch (InterruptedException e) {
18510                            }
18511                        }
18512                    }
18513                    if (conn.mContainerService == null) {
18514                        return;
18515                    }
18516
18517                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18518                    clearDirectory(conn.mContainerService,
18519                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18520                    if (allData) {
18521                        clearDirectory(conn.mContainerService,
18522                                userEnv.buildExternalStorageAppDataDirs(packageName));
18523                        clearDirectory(conn.mContainerService,
18524                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18525                    }
18526                }
18527            } finally {
18528                mContext.unbindService(conn);
18529            }
18530        }
18531    }
18532
18533    @Override
18534    public void clearApplicationProfileData(String packageName) {
18535        enforceSystemOrRoot("Only the system can clear all profile data");
18536
18537        final PackageParser.Package pkg;
18538        synchronized (mPackages) {
18539            pkg = mPackages.get(packageName);
18540        }
18541
18542        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18543            synchronized (mInstallLock) {
18544                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18545            }
18546        }
18547    }
18548
18549    @Override
18550    public void clearApplicationUserData(final String packageName,
18551            final IPackageDataObserver observer, final int userId) {
18552        mContext.enforceCallingOrSelfPermission(
18553                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18554
18555        final int callingUid = Binder.getCallingUid();
18556        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18557                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18558
18559        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18560        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18561        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18562            throw new SecurityException("Cannot clear data for a protected package: "
18563                    + packageName);
18564        }
18565        // Queue up an async operation since the package deletion may take a little while.
18566        mHandler.post(new Runnable() {
18567            public void run() {
18568                mHandler.removeCallbacks(this);
18569                final boolean succeeded;
18570                if (!filterApp) {
18571                    try (PackageFreezer freezer = freezePackage(packageName,
18572                            "clearApplicationUserData")) {
18573                        synchronized (mInstallLock) {
18574                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18575                        }
18576                        clearExternalStorageDataSync(packageName, userId, true);
18577                        synchronized (mPackages) {
18578                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18579                                    packageName, userId);
18580                        }
18581                    }
18582                    if (succeeded) {
18583                        // invoke DeviceStorageMonitor's update method to clear any notifications
18584                        DeviceStorageMonitorInternal dsm = LocalServices
18585                                .getService(DeviceStorageMonitorInternal.class);
18586                        if (dsm != null) {
18587                            dsm.checkMemory();
18588                        }
18589                    }
18590                } else {
18591                    succeeded = false;
18592                }
18593                if (observer != null) {
18594                    try {
18595                        observer.onRemoveCompleted(packageName, succeeded);
18596                    } catch (RemoteException e) {
18597                        Log.i(TAG, "Observer no longer exists.");
18598                    }
18599                } //end if observer
18600            } //end run
18601        });
18602    }
18603
18604    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18605        if (packageName == null) {
18606            Slog.w(TAG, "Attempt to delete null packageName.");
18607            return false;
18608        }
18609
18610        // Try finding details about the requested package
18611        PackageParser.Package pkg;
18612        synchronized (mPackages) {
18613            pkg = mPackages.get(packageName);
18614            if (pkg == null) {
18615                final PackageSetting ps = mSettings.mPackages.get(packageName);
18616                if (ps != null) {
18617                    pkg = ps.pkg;
18618                }
18619            }
18620
18621            if (pkg == null) {
18622                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18623                return false;
18624            }
18625
18626            PackageSetting ps = (PackageSetting) pkg.mExtras;
18627            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18628        }
18629
18630        clearAppDataLIF(pkg, userId,
18631                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18632
18633        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18634        removeKeystoreDataIfNeeded(userId, appId);
18635
18636        UserManagerInternal umInternal = getUserManagerInternal();
18637        final int flags;
18638        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18639            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18640        } else if (umInternal.isUserRunning(userId)) {
18641            flags = StorageManager.FLAG_STORAGE_DE;
18642        } else {
18643            flags = 0;
18644        }
18645        prepareAppDataContentsLIF(pkg, userId, flags);
18646
18647        return true;
18648    }
18649
18650    /**
18651     * Reverts user permission state changes (permissions and flags) in
18652     * all packages for a given user.
18653     *
18654     * @param userId The device user for which to do a reset.
18655     */
18656    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18657        final int packageCount = mPackages.size();
18658        for (int i = 0; i < packageCount; i++) {
18659            PackageParser.Package pkg = mPackages.valueAt(i);
18660            PackageSetting ps = (PackageSetting) pkg.mExtras;
18661            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18662        }
18663    }
18664
18665    private void resetNetworkPolicies(int userId) {
18666        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18667    }
18668
18669    /**
18670     * Reverts user permission state changes (permissions and flags).
18671     *
18672     * @param ps The package for which to reset.
18673     * @param userId The device user for which to do a reset.
18674     */
18675    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18676            final PackageSetting ps, final int userId) {
18677        if (ps.pkg == null) {
18678            return;
18679        }
18680
18681        // These are flags that can change base on user actions.
18682        final int userSettableMask = FLAG_PERMISSION_USER_SET
18683                | FLAG_PERMISSION_USER_FIXED
18684                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18685                | FLAG_PERMISSION_REVIEW_REQUIRED;
18686
18687        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18688                | FLAG_PERMISSION_POLICY_FIXED;
18689
18690        boolean writeInstallPermissions = false;
18691        boolean writeRuntimePermissions = false;
18692
18693        final int permissionCount = ps.pkg.requestedPermissions.size();
18694        for (int i = 0; i < permissionCount; i++) {
18695            final String permName = ps.pkg.requestedPermissions.get(i);
18696            final BasePermission bp =
18697                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
18698            if (bp == null) {
18699                continue;
18700            }
18701
18702            // If shared user we just reset the state to which only this app contributed.
18703            if (ps.sharedUser != null) {
18704                boolean used = false;
18705                final int packageCount = ps.sharedUser.packages.size();
18706                for (int j = 0; j < packageCount; j++) {
18707                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18708                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18709                            && pkg.pkg.requestedPermissions.contains(permName)) {
18710                        used = true;
18711                        break;
18712                    }
18713                }
18714                if (used) {
18715                    continue;
18716                }
18717            }
18718
18719            final PermissionsState permissionsState = ps.getPermissionsState();
18720
18721            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
18722
18723            // Always clear the user settable flags.
18724            final boolean hasInstallState =
18725                    permissionsState.getInstallPermissionState(permName) != null;
18726            // If permission review is enabled and this is a legacy app, mark the
18727            // permission as requiring a review as this is the initial state.
18728            int flags = 0;
18729            if (mSettings.mPermissions.mPermissionReviewRequired
18730                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18731                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18732            }
18733            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18734                if (hasInstallState) {
18735                    writeInstallPermissions = true;
18736                } else {
18737                    writeRuntimePermissions = true;
18738                }
18739            }
18740
18741            // Below is only runtime permission handling.
18742            if (!bp.isRuntime()) {
18743                continue;
18744            }
18745
18746            // Never clobber system or policy.
18747            if ((oldFlags & policyOrSystemFlags) != 0) {
18748                continue;
18749            }
18750
18751            // If this permission was granted by default, make sure it is.
18752            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18753                if (permissionsState.grantRuntimePermission(bp, userId)
18754                        != PERMISSION_OPERATION_FAILURE) {
18755                    writeRuntimePermissions = true;
18756                }
18757            // If permission review is enabled the permissions for a legacy apps
18758            // are represented as constantly granted runtime ones, so don't revoke.
18759            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18760                // Otherwise, reset the permission.
18761                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18762                switch (revokeResult) {
18763                    case PERMISSION_OPERATION_SUCCESS:
18764                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18765                        writeRuntimePermissions = true;
18766                        final int appId = ps.appId;
18767                        mHandler.post(new Runnable() {
18768                            @Override
18769                            public void run() {
18770                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18771                            }
18772                        });
18773                    } break;
18774                }
18775            }
18776        }
18777
18778        // Synchronously write as we are taking permissions away.
18779        if (writeRuntimePermissions) {
18780            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18781        }
18782
18783        // Synchronously write as we are taking permissions away.
18784        if (writeInstallPermissions) {
18785            mSettings.writeLPr();
18786        }
18787    }
18788
18789    /**
18790     * Remove entries from the keystore daemon. Will only remove it if the
18791     * {@code appId} is valid.
18792     */
18793    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18794        if (appId < 0) {
18795            return;
18796        }
18797
18798        final KeyStore keyStore = KeyStore.getInstance();
18799        if (keyStore != null) {
18800            if (userId == UserHandle.USER_ALL) {
18801                for (final int individual : sUserManager.getUserIds()) {
18802                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18803                }
18804            } else {
18805                keyStore.clearUid(UserHandle.getUid(userId, appId));
18806            }
18807        } else {
18808            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18809        }
18810    }
18811
18812    @Override
18813    public void deleteApplicationCacheFiles(final String packageName,
18814            final IPackageDataObserver observer) {
18815        final int userId = UserHandle.getCallingUserId();
18816        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18817    }
18818
18819    @Override
18820    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18821            final IPackageDataObserver observer) {
18822        final int callingUid = Binder.getCallingUid();
18823        mContext.enforceCallingOrSelfPermission(
18824                android.Manifest.permission.DELETE_CACHE_FILES, null);
18825        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18826                /* requireFullPermission= */ true, /* checkShell= */ false,
18827                "delete application cache files");
18828        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18829                android.Manifest.permission.ACCESS_INSTANT_APPS);
18830
18831        final PackageParser.Package pkg;
18832        synchronized (mPackages) {
18833            pkg = mPackages.get(packageName);
18834        }
18835
18836        // Queue up an async operation since the package deletion may take a little while.
18837        mHandler.post(new Runnable() {
18838            public void run() {
18839                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
18840                boolean doClearData = true;
18841                if (ps != null) {
18842                    final boolean targetIsInstantApp =
18843                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18844                    doClearData = !targetIsInstantApp
18845                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18846                }
18847                if (doClearData) {
18848                    synchronized (mInstallLock) {
18849                        final int flags = StorageManager.FLAG_STORAGE_DE
18850                                | StorageManager.FLAG_STORAGE_CE;
18851                        // We're only clearing cache files, so we don't care if the
18852                        // app is unfrozen and still able to run
18853                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18854                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18855                    }
18856                    clearExternalStorageDataSync(packageName, userId, false);
18857                }
18858                if (observer != null) {
18859                    try {
18860                        observer.onRemoveCompleted(packageName, true);
18861                    } catch (RemoteException e) {
18862                        Log.i(TAG, "Observer no longer exists.");
18863                    }
18864                }
18865            }
18866        });
18867    }
18868
18869    @Override
18870    public void getPackageSizeInfo(final String packageName, int userHandle,
18871            final IPackageStatsObserver observer) {
18872        throw new UnsupportedOperationException(
18873                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18874    }
18875
18876    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18877        final PackageSetting ps;
18878        synchronized (mPackages) {
18879            ps = mSettings.mPackages.get(packageName);
18880            if (ps == null) {
18881                Slog.w(TAG, "Failed to find settings for " + packageName);
18882                return false;
18883            }
18884        }
18885
18886        final String[] packageNames = { packageName };
18887        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18888        final String[] codePaths = { ps.codePathString };
18889
18890        try {
18891            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18892                    ps.appId, ceDataInodes, codePaths, stats);
18893
18894            // For now, ignore code size of packages on system partition
18895            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18896                stats.codeSize = 0;
18897            }
18898
18899            // External clients expect these to be tracked separately
18900            stats.dataSize -= stats.cacheSize;
18901
18902        } catch (InstallerException e) {
18903            Slog.w(TAG, String.valueOf(e));
18904            return false;
18905        }
18906
18907        return true;
18908    }
18909
18910    private int getUidTargetSdkVersionLockedLPr(int uid) {
18911        Object obj = mSettings.getUserIdLPr(uid);
18912        if (obj instanceof SharedUserSetting) {
18913            final SharedUserSetting sus = (SharedUserSetting) obj;
18914            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18915            final Iterator<PackageSetting> it = sus.packages.iterator();
18916            while (it.hasNext()) {
18917                final PackageSetting ps = it.next();
18918                if (ps.pkg != null) {
18919                    int v = ps.pkg.applicationInfo.targetSdkVersion;
18920                    if (v < vers) vers = v;
18921                }
18922            }
18923            return vers;
18924        } else if (obj instanceof PackageSetting) {
18925            final PackageSetting ps = (PackageSetting) obj;
18926            if (ps.pkg != null) {
18927                return ps.pkg.applicationInfo.targetSdkVersion;
18928            }
18929        }
18930        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18931    }
18932
18933    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
18934        final PackageParser.Package p = mPackages.get(packageName);
18935        if (p != null) {
18936            return p.applicationInfo.targetSdkVersion;
18937        }
18938        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18939    }
18940
18941    @Override
18942    public void addPreferredActivity(IntentFilter filter, int match,
18943            ComponentName[] set, ComponentName activity, int userId) {
18944        addPreferredActivityInternal(filter, match, set, activity, true, userId,
18945                "Adding preferred");
18946    }
18947
18948    private void addPreferredActivityInternal(IntentFilter filter, int match,
18949            ComponentName[] set, ComponentName activity, boolean always, int userId,
18950            String opname) {
18951        // writer
18952        int callingUid = Binder.getCallingUid();
18953        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18954                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18955        if (filter.countActions() == 0) {
18956            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18957            return;
18958        }
18959        synchronized (mPackages) {
18960            if (mContext.checkCallingOrSelfPermission(
18961                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18962                    != PackageManager.PERMISSION_GRANTED) {
18963                if (getUidTargetSdkVersionLockedLPr(callingUid)
18964                        < Build.VERSION_CODES.FROYO) {
18965                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18966                            + callingUid);
18967                    return;
18968                }
18969                mContext.enforceCallingOrSelfPermission(
18970                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18971            }
18972
18973            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18974            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18975                    + userId + ":");
18976            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18977            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18978            scheduleWritePackageRestrictionsLocked(userId);
18979            postPreferredActivityChangedBroadcast(userId);
18980        }
18981    }
18982
18983    private void postPreferredActivityChangedBroadcast(int userId) {
18984        mHandler.post(() -> {
18985            final IActivityManager am = ActivityManager.getService();
18986            if (am == null) {
18987                return;
18988            }
18989
18990            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18991            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18992            try {
18993                am.broadcastIntent(null, intent, null, null,
18994                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
18995                        null, false, false, userId);
18996            } catch (RemoteException e) {
18997            }
18998        });
18999    }
19000
19001    @Override
19002    public void replacePreferredActivity(IntentFilter filter, int match,
19003            ComponentName[] set, ComponentName activity, int userId) {
19004        if (filter.countActions() != 1) {
19005            throw new IllegalArgumentException(
19006                    "replacePreferredActivity expects filter to have only 1 action.");
19007        }
19008        if (filter.countDataAuthorities() != 0
19009                || filter.countDataPaths() != 0
19010                || filter.countDataSchemes() > 1
19011                || filter.countDataTypes() != 0) {
19012            throw new IllegalArgumentException(
19013                    "replacePreferredActivity expects filter to have no data authorities, " +
19014                    "paths, or types; and at most one scheme.");
19015        }
19016
19017        final int callingUid = Binder.getCallingUid();
19018        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19019                true /* requireFullPermission */, false /* checkShell */,
19020                "replace preferred activity");
19021        synchronized (mPackages) {
19022            if (mContext.checkCallingOrSelfPermission(
19023                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19024                    != PackageManager.PERMISSION_GRANTED) {
19025                if (getUidTargetSdkVersionLockedLPr(callingUid)
19026                        < Build.VERSION_CODES.FROYO) {
19027                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19028                            + Binder.getCallingUid());
19029                    return;
19030                }
19031                mContext.enforceCallingOrSelfPermission(
19032                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19033            }
19034
19035            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19036            if (pir != null) {
19037                // Get all of the existing entries that exactly match this filter.
19038                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19039                if (existing != null && existing.size() == 1) {
19040                    PreferredActivity cur = existing.get(0);
19041                    if (DEBUG_PREFERRED) {
19042                        Slog.i(TAG, "Checking replace of preferred:");
19043                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19044                        if (!cur.mPref.mAlways) {
19045                            Slog.i(TAG, "  -- CUR; not mAlways!");
19046                        } else {
19047                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19048                            Slog.i(TAG, "  -- CUR: mSet="
19049                                    + Arrays.toString(cur.mPref.mSetComponents));
19050                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19051                            Slog.i(TAG, "  -- NEW: mMatch="
19052                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19053                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19054                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19055                        }
19056                    }
19057                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19058                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19059                            && cur.mPref.sameSet(set)) {
19060                        // Setting the preferred activity to what it happens to be already
19061                        if (DEBUG_PREFERRED) {
19062                            Slog.i(TAG, "Replacing with same preferred activity "
19063                                    + cur.mPref.mShortComponent + " for user "
19064                                    + userId + ":");
19065                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19066                        }
19067                        return;
19068                    }
19069                }
19070
19071                if (existing != null) {
19072                    if (DEBUG_PREFERRED) {
19073                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19074                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19075                    }
19076                    for (int i = 0; i < existing.size(); i++) {
19077                        PreferredActivity pa = existing.get(i);
19078                        if (DEBUG_PREFERRED) {
19079                            Slog.i(TAG, "Removing existing preferred activity "
19080                                    + pa.mPref.mComponent + ":");
19081                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19082                        }
19083                        pir.removeFilter(pa);
19084                    }
19085                }
19086            }
19087            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19088                    "Replacing preferred");
19089        }
19090    }
19091
19092    @Override
19093    public void clearPackagePreferredActivities(String packageName) {
19094        final int callingUid = Binder.getCallingUid();
19095        if (getInstantAppPackageName(callingUid) != null) {
19096            return;
19097        }
19098        // writer
19099        synchronized (mPackages) {
19100            PackageParser.Package pkg = mPackages.get(packageName);
19101            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19102                if (mContext.checkCallingOrSelfPermission(
19103                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19104                        != PackageManager.PERMISSION_GRANTED) {
19105                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19106                            < Build.VERSION_CODES.FROYO) {
19107                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19108                                + callingUid);
19109                        return;
19110                    }
19111                    mContext.enforceCallingOrSelfPermission(
19112                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19113                }
19114            }
19115            final PackageSetting ps = mSettings.getPackageLPr(packageName);
19116            if (ps != null
19117                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19118                return;
19119            }
19120            int user = UserHandle.getCallingUserId();
19121            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19122                scheduleWritePackageRestrictionsLocked(user);
19123            }
19124        }
19125    }
19126
19127    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19128    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19129        ArrayList<PreferredActivity> removed = null;
19130        boolean changed = false;
19131        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19132            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19133            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19134            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19135                continue;
19136            }
19137            Iterator<PreferredActivity> it = pir.filterIterator();
19138            while (it.hasNext()) {
19139                PreferredActivity pa = it.next();
19140                // Mark entry for removal only if it matches the package name
19141                // and the entry is of type "always".
19142                if (packageName == null ||
19143                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19144                                && pa.mPref.mAlways)) {
19145                    if (removed == null) {
19146                        removed = new ArrayList<PreferredActivity>();
19147                    }
19148                    removed.add(pa);
19149                }
19150            }
19151            if (removed != null) {
19152                for (int j=0; j<removed.size(); j++) {
19153                    PreferredActivity pa = removed.get(j);
19154                    pir.removeFilter(pa);
19155                }
19156                changed = true;
19157            }
19158        }
19159        if (changed) {
19160            postPreferredActivityChangedBroadcast(userId);
19161        }
19162        return changed;
19163    }
19164
19165    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19166    private void clearIntentFilterVerificationsLPw(int userId) {
19167        final int packageCount = mPackages.size();
19168        for (int i = 0; i < packageCount; i++) {
19169            PackageParser.Package pkg = mPackages.valueAt(i);
19170            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19171        }
19172    }
19173
19174    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19175    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19176        if (userId == UserHandle.USER_ALL) {
19177            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19178                    sUserManager.getUserIds())) {
19179                for (int oneUserId : sUserManager.getUserIds()) {
19180                    scheduleWritePackageRestrictionsLocked(oneUserId);
19181                }
19182            }
19183        } else {
19184            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19185                scheduleWritePackageRestrictionsLocked(userId);
19186            }
19187        }
19188    }
19189
19190    /** Clears state for all users, and touches intent filter verification policy */
19191    void clearDefaultBrowserIfNeeded(String packageName) {
19192        for (int oneUserId : sUserManager.getUserIds()) {
19193            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19194        }
19195    }
19196
19197    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19198        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19199        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19200            if (packageName.equals(defaultBrowserPackageName)) {
19201                setDefaultBrowserPackageName(null, userId);
19202            }
19203        }
19204    }
19205
19206    @Override
19207    public void resetApplicationPreferences(int userId) {
19208        mContext.enforceCallingOrSelfPermission(
19209                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19210        final long identity = Binder.clearCallingIdentity();
19211        // writer
19212        try {
19213            synchronized (mPackages) {
19214                clearPackagePreferredActivitiesLPw(null, userId);
19215                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19216                // TODO: We have to reset the default SMS and Phone. This requires
19217                // significant refactoring to keep all default apps in the package
19218                // manager (cleaner but more work) or have the services provide
19219                // callbacks to the package manager to request a default app reset.
19220                applyFactoryDefaultBrowserLPw(userId);
19221                clearIntentFilterVerificationsLPw(userId);
19222                primeDomainVerificationsLPw(userId);
19223                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19224                scheduleWritePackageRestrictionsLocked(userId);
19225            }
19226            resetNetworkPolicies(userId);
19227        } finally {
19228            Binder.restoreCallingIdentity(identity);
19229        }
19230    }
19231
19232    @Override
19233    public int getPreferredActivities(List<IntentFilter> outFilters,
19234            List<ComponentName> outActivities, String packageName) {
19235        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19236            return 0;
19237        }
19238        int num = 0;
19239        final int userId = UserHandle.getCallingUserId();
19240        // reader
19241        synchronized (mPackages) {
19242            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19243            if (pir != null) {
19244                final Iterator<PreferredActivity> it = pir.filterIterator();
19245                while (it.hasNext()) {
19246                    final PreferredActivity pa = it.next();
19247                    if (packageName == null
19248                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19249                                    && pa.mPref.mAlways)) {
19250                        if (outFilters != null) {
19251                            outFilters.add(new IntentFilter(pa));
19252                        }
19253                        if (outActivities != null) {
19254                            outActivities.add(pa.mPref.mComponent);
19255                        }
19256                    }
19257                }
19258            }
19259        }
19260
19261        return num;
19262    }
19263
19264    @Override
19265    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19266            int userId) {
19267        int callingUid = Binder.getCallingUid();
19268        if (callingUid != Process.SYSTEM_UID) {
19269            throw new SecurityException(
19270                    "addPersistentPreferredActivity can only be run by the system");
19271        }
19272        if (filter.countActions() == 0) {
19273            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19274            return;
19275        }
19276        synchronized (mPackages) {
19277            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19278                    ":");
19279            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19280            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19281                    new PersistentPreferredActivity(filter, activity));
19282            scheduleWritePackageRestrictionsLocked(userId);
19283            postPreferredActivityChangedBroadcast(userId);
19284        }
19285    }
19286
19287    @Override
19288    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19289        int callingUid = Binder.getCallingUid();
19290        if (callingUid != Process.SYSTEM_UID) {
19291            throw new SecurityException(
19292                    "clearPackagePersistentPreferredActivities can only be run by the system");
19293        }
19294        ArrayList<PersistentPreferredActivity> removed = null;
19295        boolean changed = false;
19296        synchronized (mPackages) {
19297            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19298                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19299                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19300                        .valueAt(i);
19301                if (userId != thisUserId) {
19302                    continue;
19303                }
19304                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19305                while (it.hasNext()) {
19306                    PersistentPreferredActivity ppa = it.next();
19307                    // Mark entry for removal only if it matches the package name.
19308                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19309                        if (removed == null) {
19310                            removed = new ArrayList<PersistentPreferredActivity>();
19311                        }
19312                        removed.add(ppa);
19313                    }
19314                }
19315                if (removed != null) {
19316                    for (int j=0; j<removed.size(); j++) {
19317                        PersistentPreferredActivity ppa = removed.get(j);
19318                        ppir.removeFilter(ppa);
19319                    }
19320                    changed = true;
19321                }
19322            }
19323
19324            if (changed) {
19325                scheduleWritePackageRestrictionsLocked(userId);
19326                postPreferredActivityChangedBroadcast(userId);
19327            }
19328        }
19329    }
19330
19331    /**
19332     * Common machinery for picking apart a restored XML blob and passing
19333     * it to a caller-supplied functor to be applied to the running system.
19334     */
19335    private void restoreFromXml(XmlPullParser parser, int userId,
19336            String expectedStartTag, BlobXmlRestorer functor)
19337            throws IOException, XmlPullParserException {
19338        int type;
19339        while ((type = parser.next()) != XmlPullParser.START_TAG
19340                && type != XmlPullParser.END_DOCUMENT) {
19341        }
19342        if (type != XmlPullParser.START_TAG) {
19343            // oops didn't find a start tag?!
19344            if (DEBUG_BACKUP) {
19345                Slog.e(TAG, "Didn't find start tag during restore");
19346            }
19347            return;
19348        }
19349Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19350        // this is supposed to be TAG_PREFERRED_BACKUP
19351        if (!expectedStartTag.equals(parser.getName())) {
19352            if (DEBUG_BACKUP) {
19353                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19354            }
19355            return;
19356        }
19357
19358        // skip interfering stuff, then we're aligned with the backing implementation
19359        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19360Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19361        functor.apply(parser, userId);
19362    }
19363
19364    private interface BlobXmlRestorer {
19365        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19366    }
19367
19368    /**
19369     * Non-Binder method, support for the backup/restore mechanism: write the
19370     * full set of preferred activities in its canonical XML format.  Returns the
19371     * XML output as a byte array, or null if there is none.
19372     */
19373    @Override
19374    public byte[] getPreferredActivityBackup(int userId) {
19375        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19376            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19377        }
19378
19379        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19380        try {
19381            final XmlSerializer serializer = new FastXmlSerializer();
19382            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19383            serializer.startDocument(null, true);
19384            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19385
19386            synchronized (mPackages) {
19387                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19388            }
19389
19390            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19391            serializer.endDocument();
19392            serializer.flush();
19393        } catch (Exception e) {
19394            if (DEBUG_BACKUP) {
19395                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19396            }
19397            return null;
19398        }
19399
19400        return dataStream.toByteArray();
19401    }
19402
19403    @Override
19404    public void restorePreferredActivities(byte[] backup, int userId) {
19405        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19406            throw new SecurityException("Only the system may call restorePreferredActivities()");
19407        }
19408
19409        try {
19410            final XmlPullParser parser = Xml.newPullParser();
19411            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19412            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19413                    new BlobXmlRestorer() {
19414                        @Override
19415                        public void apply(XmlPullParser parser, int userId)
19416                                throws XmlPullParserException, IOException {
19417                            synchronized (mPackages) {
19418                                mSettings.readPreferredActivitiesLPw(parser, userId);
19419                            }
19420                        }
19421                    } );
19422        } catch (Exception e) {
19423            if (DEBUG_BACKUP) {
19424                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19425            }
19426        }
19427    }
19428
19429    /**
19430     * Non-Binder method, support for the backup/restore mechanism: write the
19431     * default browser (etc) settings in its canonical XML format.  Returns the default
19432     * browser XML representation as a byte array, or null if there is none.
19433     */
19434    @Override
19435    public byte[] getDefaultAppsBackup(int userId) {
19436        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19437            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19438        }
19439
19440        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19441        try {
19442            final XmlSerializer serializer = new FastXmlSerializer();
19443            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19444            serializer.startDocument(null, true);
19445            serializer.startTag(null, TAG_DEFAULT_APPS);
19446
19447            synchronized (mPackages) {
19448                mSettings.writeDefaultAppsLPr(serializer, userId);
19449            }
19450
19451            serializer.endTag(null, TAG_DEFAULT_APPS);
19452            serializer.endDocument();
19453            serializer.flush();
19454        } catch (Exception e) {
19455            if (DEBUG_BACKUP) {
19456                Slog.e(TAG, "Unable to write default apps for backup", e);
19457            }
19458            return null;
19459        }
19460
19461        return dataStream.toByteArray();
19462    }
19463
19464    @Override
19465    public void restoreDefaultApps(byte[] backup, int userId) {
19466        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19467            throw new SecurityException("Only the system may call restoreDefaultApps()");
19468        }
19469
19470        try {
19471            final XmlPullParser parser = Xml.newPullParser();
19472            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19473            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19474                    new BlobXmlRestorer() {
19475                        @Override
19476                        public void apply(XmlPullParser parser, int userId)
19477                                throws XmlPullParserException, IOException {
19478                            synchronized (mPackages) {
19479                                mSettings.readDefaultAppsLPw(parser, userId);
19480                            }
19481                        }
19482                    } );
19483        } catch (Exception e) {
19484            if (DEBUG_BACKUP) {
19485                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19486            }
19487        }
19488    }
19489
19490    @Override
19491    public byte[] getIntentFilterVerificationBackup(int userId) {
19492        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19493            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19494        }
19495
19496        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19497        try {
19498            final XmlSerializer serializer = new FastXmlSerializer();
19499            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19500            serializer.startDocument(null, true);
19501            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19502
19503            synchronized (mPackages) {
19504                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19505            }
19506
19507            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19508            serializer.endDocument();
19509            serializer.flush();
19510        } catch (Exception e) {
19511            if (DEBUG_BACKUP) {
19512                Slog.e(TAG, "Unable to write default apps for backup", e);
19513            }
19514            return null;
19515        }
19516
19517        return dataStream.toByteArray();
19518    }
19519
19520    @Override
19521    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19522        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19523            throw new SecurityException("Only the system may call restorePreferredActivities()");
19524        }
19525
19526        try {
19527            final XmlPullParser parser = Xml.newPullParser();
19528            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19529            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19530                    new BlobXmlRestorer() {
19531                        @Override
19532                        public void apply(XmlPullParser parser, int userId)
19533                                throws XmlPullParserException, IOException {
19534                            synchronized (mPackages) {
19535                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19536                                mSettings.writeLPr();
19537                            }
19538                        }
19539                    } );
19540        } catch (Exception e) {
19541            if (DEBUG_BACKUP) {
19542                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19543            }
19544        }
19545    }
19546
19547    @Override
19548    public byte[] getPermissionGrantBackup(int userId) {
19549        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19550            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19551        }
19552
19553        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19554        try {
19555            final XmlSerializer serializer = new FastXmlSerializer();
19556            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19557            serializer.startDocument(null, true);
19558            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19559
19560            synchronized (mPackages) {
19561                serializeRuntimePermissionGrantsLPr(serializer, userId);
19562            }
19563
19564            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19565            serializer.endDocument();
19566            serializer.flush();
19567        } catch (Exception e) {
19568            if (DEBUG_BACKUP) {
19569                Slog.e(TAG, "Unable to write default apps for backup", e);
19570            }
19571            return null;
19572        }
19573
19574        return dataStream.toByteArray();
19575    }
19576
19577    @Override
19578    public void restorePermissionGrants(byte[] backup, int userId) {
19579        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19580            throw new SecurityException("Only the system may call restorePermissionGrants()");
19581        }
19582
19583        try {
19584            final XmlPullParser parser = Xml.newPullParser();
19585            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19586            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19587                    new BlobXmlRestorer() {
19588                        @Override
19589                        public void apply(XmlPullParser parser, int userId)
19590                                throws XmlPullParserException, IOException {
19591                            synchronized (mPackages) {
19592                                processRestoredPermissionGrantsLPr(parser, userId);
19593                            }
19594                        }
19595                    } );
19596        } catch (Exception e) {
19597            if (DEBUG_BACKUP) {
19598                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19599            }
19600        }
19601    }
19602
19603    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19604            throws IOException {
19605        serializer.startTag(null, TAG_ALL_GRANTS);
19606
19607        final int N = mSettings.mPackages.size();
19608        for (int i = 0; i < N; i++) {
19609            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19610            boolean pkgGrantsKnown = false;
19611
19612            PermissionsState packagePerms = ps.getPermissionsState();
19613
19614            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19615                final int grantFlags = state.getFlags();
19616                // only look at grants that are not system/policy fixed
19617                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19618                    final boolean isGranted = state.isGranted();
19619                    // And only back up the user-twiddled state bits
19620                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19621                        final String packageName = mSettings.mPackages.keyAt(i);
19622                        if (!pkgGrantsKnown) {
19623                            serializer.startTag(null, TAG_GRANT);
19624                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19625                            pkgGrantsKnown = true;
19626                        }
19627
19628                        final boolean userSet =
19629                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19630                        final boolean userFixed =
19631                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19632                        final boolean revoke =
19633                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19634
19635                        serializer.startTag(null, TAG_PERMISSION);
19636                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19637                        if (isGranted) {
19638                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19639                        }
19640                        if (userSet) {
19641                            serializer.attribute(null, ATTR_USER_SET, "true");
19642                        }
19643                        if (userFixed) {
19644                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19645                        }
19646                        if (revoke) {
19647                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19648                        }
19649                        serializer.endTag(null, TAG_PERMISSION);
19650                    }
19651                }
19652            }
19653
19654            if (pkgGrantsKnown) {
19655                serializer.endTag(null, TAG_GRANT);
19656            }
19657        }
19658
19659        serializer.endTag(null, TAG_ALL_GRANTS);
19660    }
19661
19662    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19663            throws XmlPullParserException, IOException {
19664        String pkgName = null;
19665        int outerDepth = parser.getDepth();
19666        int type;
19667        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19668                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19669            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19670                continue;
19671            }
19672
19673            final String tagName = parser.getName();
19674            if (tagName.equals(TAG_GRANT)) {
19675                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19676                if (DEBUG_BACKUP) {
19677                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19678                }
19679            } else if (tagName.equals(TAG_PERMISSION)) {
19680
19681                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19682                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19683
19684                int newFlagSet = 0;
19685                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19686                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19687                }
19688                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19689                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19690                }
19691                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19692                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19693                }
19694                if (DEBUG_BACKUP) {
19695                    Slog.v(TAG, "  + Restoring grant:"
19696                            + " pkg=" + pkgName
19697                            + " perm=" + permName
19698                            + " granted=" + isGranted
19699                            + " bits=0x" + Integer.toHexString(newFlagSet));
19700                }
19701                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19702                if (ps != null) {
19703                    // Already installed so we apply the grant immediately
19704                    if (DEBUG_BACKUP) {
19705                        Slog.v(TAG, "        + already installed; applying");
19706                    }
19707                    PermissionsState perms = ps.getPermissionsState();
19708                    BasePermission bp =
19709                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19710                    if (bp != null) {
19711                        if (isGranted) {
19712                            perms.grantRuntimePermission(bp, userId);
19713                        }
19714                        if (newFlagSet != 0) {
19715                            perms.updatePermissionFlags(
19716                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19717                        }
19718                    }
19719                } else {
19720                    // Need to wait for post-restore install to apply the grant
19721                    if (DEBUG_BACKUP) {
19722                        Slog.v(TAG, "        - not yet installed; saving for later");
19723                    }
19724                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19725                            isGranted, newFlagSet, userId);
19726                }
19727            } else {
19728                PackageManagerService.reportSettingsProblem(Log.WARN,
19729                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19730                XmlUtils.skipCurrentTag(parser);
19731            }
19732        }
19733
19734        scheduleWriteSettingsLocked();
19735        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19736    }
19737
19738    @Override
19739    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19740            int sourceUserId, int targetUserId, int flags) {
19741        mContext.enforceCallingOrSelfPermission(
19742                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19743        int callingUid = Binder.getCallingUid();
19744        enforceOwnerRights(ownerPackage, callingUid);
19745        PackageManagerServiceUtils.enforceShellRestriction(
19746                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19747        if (intentFilter.countActions() == 0) {
19748            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19749            return;
19750        }
19751        synchronized (mPackages) {
19752            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19753                    ownerPackage, targetUserId, flags);
19754            CrossProfileIntentResolver resolver =
19755                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19756            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19757            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19758            if (existing != null) {
19759                int size = existing.size();
19760                for (int i = 0; i < size; i++) {
19761                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19762                        return;
19763                    }
19764                }
19765            }
19766            resolver.addFilter(newFilter);
19767            scheduleWritePackageRestrictionsLocked(sourceUserId);
19768        }
19769    }
19770
19771    @Override
19772    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19773        mContext.enforceCallingOrSelfPermission(
19774                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19775        final int callingUid = Binder.getCallingUid();
19776        enforceOwnerRights(ownerPackage, callingUid);
19777        PackageManagerServiceUtils.enforceShellRestriction(
19778                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19779        synchronized (mPackages) {
19780            CrossProfileIntentResolver resolver =
19781                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19782            ArraySet<CrossProfileIntentFilter> set =
19783                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19784            for (CrossProfileIntentFilter filter : set) {
19785                if (filter.getOwnerPackage().equals(ownerPackage)) {
19786                    resolver.removeFilter(filter);
19787                }
19788            }
19789            scheduleWritePackageRestrictionsLocked(sourceUserId);
19790        }
19791    }
19792
19793    // Enforcing that callingUid is owning pkg on userId
19794    private void enforceOwnerRights(String pkg, int callingUid) {
19795        // The system owns everything.
19796        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19797            return;
19798        }
19799        final int callingUserId = UserHandle.getUserId(callingUid);
19800        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19801        if (pi == null) {
19802            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19803                    + callingUserId);
19804        }
19805        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19806            throw new SecurityException("Calling uid " + callingUid
19807                    + " does not own package " + pkg);
19808        }
19809    }
19810
19811    @Override
19812    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19813        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19814            return null;
19815        }
19816        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19817    }
19818
19819    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19820        UserManagerService ums = UserManagerService.getInstance();
19821        if (ums != null) {
19822            final UserInfo parent = ums.getProfileParent(userId);
19823            final int launcherUid = (parent != null) ? parent.id : userId;
19824            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19825            if (launcherComponent != null) {
19826                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19827                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19828                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19829                        .setPackage(launcherComponent.getPackageName());
19830                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19831            }
19832        }
19833    }
19834
19835    /**
19836     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19837     * then reports the most likely home activity or null if there are more than one.
19838     */
19839    private ComponentName getDefaultHomeActivity(int userId) {
19840        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19841        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19842        if (cn != null) {
19843            return cn;
19844        }
19845
19846        // Find the launcher with the highest priority and return that component if there are no
19847        // other home activity with the same priority.
19848        int lastPriority = Integer.MIN_VALUE;
19849        ComponentName lastComponent = null;
19850        final int size = allHomeCandidates.size();
19851        for (int i = 0; i < size; i++) {
19852            final ResolveInfo ri = allHomeCandidates.get(i);
19853            if (ri.priority > lastPriority) {
19854                lastComponent = ri.activityInfo.getComponentName();
19855                lastPriority = ri.priority;
19856            } else if (ri.priority == lastPriority) {
19857                // Two components found with same priority.
19858                lastComponent = null;
19859            }
19860        }
19861        return lastComponent;
19862    }
19863
19864    private Intent getHomeIntent() {
19865        Intent intent = new Intent(Intent.ACTION_MAIN);
19866        intent.addCategory(Intent.CATEGORY_HOME);
19867        intent.addCategory(Intent.CATEGORY_DEFAULT);
19868        return intent;
19869    }
19870
19871    private IntentFilter getHomeFilter() {
19872        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19873        filter.addCategory(Intent.CATEGORY_HOME);
19874        filter.addCategory(Intent.CATEGORY_DEFAULT);
19875        return filter;
19876    }
19877
19878    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19879            int userId) {
19880        Intent intent  = getHomeIntent();
19881        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19882                PackageManager.GET_META_DATA, userId);
19883        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19884                true, false, false, userId);
19885
19886        allHomeCandidates.clear();
19887        if (list != null) {
19888            for (ResolveInfo ri : list) {
19889                allHomeCandidates.add(ri);
19890            }
19891        }
19892        return (preferred == null || preferred.activityInfo == null)
19893                ? null
19894                : new ComponentName(preferred.activityInfo.packageName,
19895                        preferred.activityInfo.name);
19896    }
19897
19898    @Override
19899    public void setHomeActivity(ComponentName comp, int userId) {
19900        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19901            return;
19902        }
19903        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19904        getHomeActivitiesAsUser(homeActivities, userId);
19905
19906        boolean found = false;
19907
19908        final int size = homeActivities.size();
19909        final ComponentName[] set = new ComponentName[size];
19910        for (int i = 0; i < size; i++) {
19911            final ResolveInfo candidate = homeActivities.get(i);
19912            final ActivityInfo info = candidate.activityInfo;
19913            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19914            set[i] = activityName;
19915            if (!found && activityName.equals(comp)) {
19916                found = true;
19917            }
19918        }
19919        if (!found) {
19920            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19921                    + userId);
19922        }
19923        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19924                set, comp, userId);
19925    }
19926
19927    private @Nullable String getSetupWizardPackageName() {
19928        final Intent intent = new Intent(Intent.ACTION_MAIN);
19929        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19930
19931        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19932                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19933                        | MATCH_DISABLED_COMPONENTS,
19934                UserHandle.myUserId());
19935        if (matches.size() == 1) {
19936            return matches.get(0).getComponentInfo().packageName;
19937        } else {
19938            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19939                    + ": matches=" + matches);
19940            return null;
19941        }
19942    }
19943
19944    private @Nullable String getStorageManagerPackageName() {
19945        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19946
19947        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19948                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19949                        | MATCH_DISABLED_COMPONENTS,
19950                UserHandle.myUserId());
19951        if (matches.size() == 1) {
19952            return matches.get(0).getComponentInfo().packageName;
19953        } else {
19954            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19955                    + matches.size() + ": matches=" + matches);
19956            return null;
19957        }
19958    }
19959
19960    @Override
19961    public void setApplicationEnabledSetting(String appPackageName,
19962            int newState, int flags, int userId, String callingPackage) {
19963        if (!sUserManager.exists(userId)) return;
19964        if (callingPackage == null) {
19965            callingPackage = Integer.toString(Binder.getCallingUid());
19966        }
19967        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19968    }
19969
19970    @Override
19971    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19972        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19973        synchronized (mPackages) {
19974            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19975            if (pkgSetting != null) {
19976                pkgSetting.setUpdateAvailable(updateAvailable);
19977            }
19978        }
19979    }
19980
19981    @Override
19982    public void setComponentEnabledSetting(ComponentName componentName,
19983            int newState, int flags, int userId) {
19984        if (!sUserManager.exists(userId)) return;
19985        setEnabledSetting(componentName.getPackageName(),
19986                componentName.getClassName(), newState, flags, userId, null);
19987    }
19988
19989    private void setEnabledSetting(final String packageName, String className, int newState,
19990            final int flags, int userId, String callingPackage) {
19991        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19992              || newState == COMPONENT_ENABLED_STATE_ENABLED
19993              || newState == COMPONENT_ENABLED_STATE_DISABLED
19994              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19995              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19996            throw new IllegalArgumentException("Invalid new component state: "
19997                    + newState);
19998        }
19999        PackageSetting pkgSetting;
20000        final int callingUid = Binder.getCallingUid();
20001        final int permission;
20002        if (callingUid == Process.SYSTEM_UID) {
20003            permission = PackageManager.PERMISSION_GRANTED;
20004        } else {
20005            permission = mContext.checkCallingOrSelfPermission(
20006                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20007        }
20008        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20009                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20010        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20011        boolean sendNow = false;
20012        boolean isApp = (className == null);
20013        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20014        String componentName = isApp ? packageName : className;
20015        int packageUid = -1;
20016        ArrayList<String> components;
20017
20018        // reader
20019        synchronized (mPackages) {
20020            pkgSetting = mSettings.mPackages.get(packageName);
20021            if (pkgSetting == null) {
20022                if (!isCallerInstantApp) {
20023                    if (className == null) {
20024                        throw new IllegalArgumentException("Unknown package: " + packageName);
20025                    }
20026                    throw new IllegalArgumentException(
20027                            "Unknown component: " + packageName + "/" + className);
20028                } else {
20029                    // throw SecurityException to prevent leaking package information
20030                    throw new SecurityException(
20031                            "Attempt to change component state; "
20032                            + "pid=" + Binder.getCallingPid()
20033                            + ", uid=" + callingUid
20034                            + (className == null
20035                                    ? ", package=" + packageName
20036                                    : ", component=" + packageName + "/" + className));
20037                }
20038            }
20039        }
20040
20041        // Limit who can change which apps
20042        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20043            // Don't allow apps that don't have permission to modify other apps
20044            if (!allowedByPermission
20045                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20046                throw new SecurityException(
20047                        "Attempt to change component state; "
20048                        + "pid=" + Binder.getCallingPid()
20049                        + ", uid=" + callingUid
20050                        + (className == null
20051                                ? ", package=" + packageName
20052                                : ", component=" + packageName + "/" + className));
20053            }
20054            // Don't allow changing protected packages.
20055            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20056                throw new SecurityException("Cannot disable a protected package: " + packageName);
20057            }
20058        }
20059
20060        synchronized (mPackages) {
20061            if (callingUid == Process.SHELL_UID
20062                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20063                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20064                // unless it is a test package.
20065                int oldState = pkgSetting.getEnabled(userId);
20066                if (className == null
20067                        &&
20068                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20069                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20070                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20071                        &&
20072                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20073                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
20074                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20075                    // ok
20076                } else {
20077                    throw new SecurityException(
20078                            "Shell cannot change component state for " + packageName + "/"
20079                                    + className + " to " + newState);
20080                }
20081            }
20082        }
20083        if (className == null) {
20084            // We're dealing with an application/package level state change
20085            synchronized (mPackages) {
20086                if (pkgSetting.getEnabled(userId) == newState) {
20087                    // Nothing to do
20088                    return;
20089                }
20090            }
20091            // If we're enabling a system stub, there's a little more work to do.
20092            // Prior to enabling the package, we need to decompress the APK(s) to the
20093            // data partition and then replace the version on the system partition.
20094            final PackageParser.Package deletedPkg = pkgSetting.pkg;
20095            final boolean isSystemStub = deletedPkg.isStub
20096                    && deletedPkg.isSystem();
20097            if (isSystemStub
20098                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20099                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20100                final File codePath = decompressPackage(deletedPkg);
20101                if (codePath == null) {
20102                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20103                    return;
20104                }
20105                // TODO remove direct parsing of the package object during internal cleanup
20106                // of scan package
20107                // We need to call parse directly here for no other reason than we need
20108                // the new package in order to disable the old one [we use the information
20109                // for some internal optimization to optionally create a new package setting
20110                // object on replace]. However, we can't get the package from the scan
20111                // because the scan modifies live structures and we need to remove the
20112                // old [system] package from the system before a scan can be attempted.
20113                // Once scan is indempotent we can remove this parse and use the package
20114                // object we scanned, prior to adding it to package settings.
20115                final PackageParser pp = new PackageParser();
20116                pp.setSeparateProcesses(mSeparateProcesses);
20117                pp.setDisplayMetrics(mMetrics);
20118                pp.setCallback(mPackageParserCallback);
20119                final PackageParser.Package tmpPkg;
20120                try {
20121                    final @ParseFlags int parseFlags = mDefParseFlags
20122                            | PackageParser.PARSE_MUST_BE_APK
20123                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20124                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20125                } catch (PackageParserException e) {
20126                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20127                    return;
20128                }
20129                synchronized (mInstallLock) {
20130                    // Disable the stub and remove any package entries
20131                    removePackageLI(deletedPkg, true);
20132                    synchronized (mPackages) {
20133                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20134                    }
20135                    final PackageParser.Package pkg;
20136                    try (PackageFreezer freezer =
20137                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20138                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20139                                | PackageParser.PARSE_ENFORCE_CODE;
20140                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20141                                0 /*currentTime*/, null /*user*/);
20142                        prepareAppDataAfterInstallLIF(pkg);
20143                        synchronized (mPackages) {
20144                            try {
20145                                updateSharedLibrariesLPr(pkg, null);
20146                            } catch (PackageManagerException e) {
20147                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20148                            }
20149                            mPermissionManager.updatePermissions(
20150                                    pkg.packageName, pkg, true, mPackages.values(),
20151                                    mPermissionCallback);
20152                            mSettings.writeLPr();
20153                        }
20154                    } catch (PackageManagerException e) {
20155                        // Whoops! Something went wrong; try to roll back to the stub
20156                        Slog.w(TAG, "Failed to install compressed system package:"
20157                                + pkgSetting.name, e);
20158                        // Remove the failed install
20159                        removeCodePathLI(codePath);
20160
20161                        // Install the system package
20162                        try (PackageFreezer freezer =
20163                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20164                            synchronized (mPackages) {
20165                                // NOTE: The system package always needs to be enabled; even
20166                                // if it's for a compressed stub. If we don't, installing the
20167                                // system package fails during scan [scanning checks the disabled
20168                                // packages]. We will reverse this later, after we've "installed"
20169                                // the stub.
20170                                // This leaves us in a fragile state; the stub should never be
20171                                // enabled, so, cross your fingers and hope nothing goes wrong
20172                                // until we can disable the package later.
20173                                enableSystemPackageLPw(deletedPkg);
20174                            }
20175                            installPackageFromSystemLIF(deletedPkg.codePath,
20176                                    false /*isPrivileged*/, null /*allUserHandles*/,
20177                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20178                                    true /*writeSettings*/);
20179                        } catch (PackageManagerException pme) {
20180                            Slog.w(TAG, "Failed to restore system package:"
20181                                    + deletedPkg.packageName, pme);
20182                        } finally {
20183                            synchronized (mPackages) {
20184                                mSettings.disableSystemPackageLPw(
20185                                        deletedPkg.packageName, true /*replaced*/);
20186                                mSettings.writeLPr();
20187                            }
20188                        }
20189                        return;
20190                    }
20191                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20192                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20193                    clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20194                    mDexManager.notifyPackageUpdated(pkg.packageName,
20195                            pkg.baseCodePath, pkg.splitCodePaths);
20196                }
20197            }
20198            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20199                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20200                // Don't care about who enables an app.
20201                callingPackage = null;
20202            }
20203            synchronized (mPackages) {
20204                pkgSetting.setEnabled(newState, userId, callingPackage);
20205            }
20206        } else {
20207            synchronized (mPackages) {
20208                // We're dealing with a component level state change
20209                // First, verify that this is a valid class name.
20210                PackageParser.Package pkg = pkgSetting.pkg;
20211                if (pkg == null || !pkg.hasComponentClassName(className)) {
20212                    if (pkg != null &&
20213                            pkg.applicationInfo.targetSdkVersion >=
20214                                    Build.VERSION_CODES.JELLY_BEAN) {
20215                        throw new IllegalArgumentException("Component class " + className
20216                                + " does not exist in " + packageName);
20217                    } else {
20218                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20219                                + className + " does not exist in " + packageName);
20220                    }
20221                }
20222                switch (newState) {
20223                    case COMPONENT_ENABLED_STATE_ENABLED:
20224                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20225                            return;
20226                        }
20227                        break;
20228                    case COMPONENT_ENABLED_STATE_DISABLED:
20229                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20230                            return;
20231                        }
20232                        break;
20233                    case COMPONENT_ENABLED_STATE_DEFAULT:
20234                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20235                            return;
20236                        }
20237                        break;
20238                    default:
20239                        Slog.e(TAG, "Invalid new component state: " + newState);
20240                        return;
20241                }
20242            }
20243        }
20244        synchronized (mPackages) {
20245            scheduleWritePackageRestrictionsLocked(userId);
20246            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20247            final long callingId = Binder.clearCallingIdentity();
20248            try {
20249                updateInstantAppInstallerLocked(packageName);
20250            } finally {
20251                Binder.restoreCallingIdentity(callingId);
20252            }
20253            components = mPendingBroadcasts.get(userId, packageName);
20254            final boolean newPackage = components == null;
20255            if (newPackage) {
20256                components = new ArrayList<String>();
20257            }
20258            if (!components.contains(componentName)) {
20259                components.add(componentName);
20260            }
20261            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20262                sendNow = true;
20263                // Purge entry from pending broadcast list if another one exists already
20264                // since we are sending one right away.
20265                mPendingBroadcasts.remove(userId, packageName);
20266            } else {
20267                if (newPackage) {
20268                    mPendingBroadcasts.put(userId, packageName, components);
20269                }
20270                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20271                    // Schedule a message
20272                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20273                }
20274            }
20275        }
20276
20277        long callingId = Binder.clearCallingIdentity();
20278        try {
20279            if (sendNow) {
20280                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20281                sendPackageChangedBroadcast(packageName,
20282                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20283            }
20284        } finally {
20285            Binder.restoreCallingIdentity(callingId);
20286        }
20287    }
20288
20289    @Override
20290    public void flushPackageRestrictionsAsUser(int userId) {
20291        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20292            return;
20293        }
20294        if (!sUserManager.exists(userId)) {
20295            return;
20296        }
20297        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20298                false /* checkShell */, "flushPackageRestrictions");
20299        synchronized (mPackages) {
20300            mSettings.writePackageRestrictionsLPr(userId);
20301            mDirtyUsers.remove(userId);
20302            if (mDirtyUsers.isEmpty()) {
20303                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20304            }
20305        }
20306    }
20307
20308    private void sendPackageChangedBroadcast(String packageName,
20309            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20310        if (DEBUG_INSTALL)
20311            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20312                    + componentNames);
20313        Bundle extras = new Bundle(4);
20314        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20315        String nameList[] = new String[componentNames.size()];
20316        componentNames.toArray(nameList);
20317        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20318        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20319        extras.putInt(Intent.EXTRA_UID, packageUid);
20320        // If this is not reporting a change of the overall package, then only send it
20321        // to registered receivers.  We don't want to launch a swath of apps for every
20322        // little component state change.
20323        final int flags = !componentNames.contains(packageName)
20324                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20325        final int userId = UserHandle.getUserId(packageUid);
20326        final boolean isInstantApp = isInstantApp(packageName, userId);
20327        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20328        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20329        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20330                userIds, instantUserIds);
20331    }
20332
20333    @Override
20334    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20335        if (!sUserManager.exists(userId)) return;
20336        final int callingUid = Binder.getCallingUid();
20337        if (getInstantAppPackageName(callingUid) != null) {
20338            return;
20339        }
20340        final int permission = mContext.checkCallingOrSelfPermission(
20341                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20342        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20343        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20344                true /* requireFullPermission */, true /* checkShell */, "stop package");
20345        // writer
20346        synchronized (mPackages) {
20347            final PackageSetting ps = mSettings.mPackages.get(packageName);
20348            if (!filterAppAccessLPr(ps, callingUid, userId)
20349                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20350                            allowedByPermission, callingUid, userId)) {
20351                scheduleWritePackageRestrictionsLocked(userId);
20352            }
20353        }
20354    }
20355
20356    @Override
20357    public String getInstallerPackageName(String packageName) {
20358        final int callingUid = Binder.getCallingUid();
20359        if (getInstantAppPackageName(callingUid) != null) {
20360            return null;
20361        }
20362        // reader
20363        synchronized (mPackages) {
20364            final PackageSetting ps = mSettings.mPackages.get(packageName);
20365            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20366                return null;
20367            }
20368            return mSettings.getInstallerPackageNameLPr(packageName);
20369        }
20370    }
20371
20372    public boolean isOrphaned(String packageName) {
20373        // reader
20374        synchronized (mPackages) {
20375            return mSettings.isOrphaned(packageName);
20376        }
20377    }
20378
20379    @Override
20380    public int getApplicationEnabledSetting(String packageName, int userId) {
20381        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20382        int callingUid = Binder.getCallingUid();
20383        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20384                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20385        // reader
20386        synchronized (mPackages) {
20387            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20388                return COMPONENT_ENABLED_STATE_DISABLED;
20389            }
20390            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20391        }
20392    }
20393
20394    @Override
20395    public int getComponentEnabledSetting(ComponentName component, int userId) {
20396        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20397        int callingUid = Binder.getCallingUid();
20398        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20399                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20400        synchronized (mPackages) {
20401            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20402                    component, TYPE_UNKNOWN, userId)) {
20403                return COMPONENT_ENABLED_STATE_DISABLED;
20404            }
20405            return mSettings.getComponentEnabledSettingLPr(component, userId);
20406        }
20407    }
20408
20409    @Override
20410    public void enterSafeMode() {
20411        enforceSystemOrRoot("Only the system can request entering safe mode");
20412
20413        if (!mSystemReady) {
20414            mSafeMode = true;
20415        }
20416    }
20417
20418    @Override
20419    public void systemReady() {
20420        enforceSystemOrRoot("Only the system can claim the system is ready");
20421
20422        mSystemReady = true;
20423        final ContentResolver resolver = mContext.getContentResolver();
20424        ContentObserver co = new ContentObserver(mHandler) {
20425            @Override
20426            public void onChange(boolean selfChange) {
20427                mEphemeralAppsDisabled =
20428                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20429                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20430            }
20431        };
20432        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20433                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20434                false, co, UserHandle.USER_SYSTEM);
20435        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20436                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20437        co.onChange(true);
20438
20439        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20440        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20441        // it is done.
20442        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20443            @Override
20444            public void onChange(boolean selfChange) {
20445                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20446                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20447                        oobEnabled == 1 ? "true" : "false");
20448            }
20449        };
20450        mContext.getContentResolver().registerContentObserver(
20451                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20452                UserHandle.USER_SYSTEM);
20453        // At boot, restore the value from the setting, which persists across reboot.
20454        privAppOobObserver.onChange(true);
20455
20456        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20457        // disabled after already being started.
20458        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20459                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20460
20461        // Read the compatibilty setting when the system is ready.
20462        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20463                mContext.getContentResolver(),
20464                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20465        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20466        if (DEBUG_SETTINGS) {
20467            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20468        }
20469
20470        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20471
20472        synchronized (mPackages) {
20473            // Verify that all of the preferred activity components actually
20474            // exist.  It is possible for applications to be updated and at
20475            // that point remove a previously declared activity component that
20476            // had been set as a preferred activity.  We try to clean this up
20477            // the next time we encounter that preferred activity, but it is
20478            // possible for the user flow to never be able to return to that
20479            // situation so here we do a sanity check to make sure we haven't
20480            // left any junk around.
20481            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20482            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20483                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20484                removed.clear();
20485                for (PreferredActivity pa : pir.filterSet()) {
20486                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20487                        removed.add(pa);
20488                    }
20489                }
20490                if (removed.size() > 0) {
20491                    for (int r=0; r<removed.size(); r++) {
20492                        PreferredActivity pa = removed.get(r);
20493                        Slog.w(TAG, "Removing dangling preferred activity: "
20494                                + pa.mPref.mComponent);
20495                        pir.removeFilter(pa);
20496                    }
20497                    mSettings.writePackageRestrictionsLPr(
20498                            mSettings.mPreferredActivities.keyAt(i));
20499                }
20500            }
20501
20502            for (int userId : UserManagerService.getInstance().getUserIds()) {
20503                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20504                    grantPermissionsUserIds = ArrayUtils.appendInt(
20505                            grantPermissionsUserIds, userId);
20506                }
20507            }
20508        }
20509        sUserManager.systemReady();
20510        // If we upgraded grant all default permissions before kicking off.
20511        for (int userId : grantPermissionsUserIds) {
20512            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20513        }
20514
20515        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20516            // If we did not grant default permissions, we preload from this the
20517            // default permission exceptions lazily to ensure we don't hit the
20518            // disk on a new user creation.
20519            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20520        }
20521
20522        // Now that we've scanned all packages, and granted any default
20523        // permissions, ensure permissions are updated. Beware of dragons if you
20524        // try optimizing this.
20525        synchronized (mPackages) {
20526            mPermissionManager.updateAllPermissions(
20527                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20528                    mPermissionCallback);
20529        }
20530
20531        // Kick off any messages waiting for system ready
20532        if (mPostSystemReadyMessages != null) {
20533            for (Message msg : mPostSystemReadyMessages) {
20534                msg.sendToTarget();
20535            }
20536            mPostSystemReadyMessages = null;
20537        }
20538
20539        // Watch for external volumes that come and go over time
20540        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20541        storage.registerListener(mStorageListener);
20542
20543        mInstallerService.systemReady();
20544        mPackageDexOptimizer.systemReady();
20545
20546        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20547                StorageManagerInternal.class);
20548        StorageManagerInternal.addExternalStoragePolicy(
20549                new StorageManagerInternal.ExternalStorageMountPolicy() {
20550            @Override
20551            public int getMountMode(int uid, String packageName) {
20552                if (Process.isIsolated(uid)) {
20553                    return Zygote.MOUNT_EXTERNAL_NONE;
20554                }
20555                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20556                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20557                }
20558                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20559                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20560                }
20561                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20562                    return Zygote.MOUNT_EXTERNAL_READ;
20563                }
20564                return Zygote.MOUNT_EXTERNAL_WRITE;
20565            }
20566
20567            @Override
20568            public boolean hasExternalStorage(int uid, String packageName) {
20569                return true;
20570            }
20571        });
20572
20573        // Now that we're mostly running, clean up stale users and apps
20574        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20575        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20576
20577        mPermissionManager.systemReady();
20578    }
20579
20580    public void waitForAppDataPrepared() {
20581        if (mPrepareAppDataFuture == null) {
20582            return;
20583        }
20584        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20585        mPrepareAppDataFuture = null;
20586    }
20587
20588    @Override
20589    public boolean isSafeMode() {
20590        // allow instant applications
20591        return mSafeMode;
20592    }
20593
20594    @Override
20595    public boolean hasSystemUidErrors() {
20596        // allow instant applications
20597        return mHasSystemUidErrors;
20598    }
20599
20600    static String arrayToString(int[] array) {
20601        StringBuffer buf = new StringBuffer(128);
20602        buf.append('[');
20603        if (array != null) {
20604            for (int i=0; i<array.length; i++) {
20605                if (i > 0) buf.append(", ");
20606                buf.append(array[i]);
20607            }
20608        }
20609        buf.append(']');
20610        return buf.toString();
20611    }
20612
20613    @Override
20614    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20615            FileDescriptor err, String[] args, ShellCallback callback,
20616            ResultReceiver resultReceiver) {
20617        (new PackageManagerShellCommand(this)).exec(
20618                this, in, out, err, args, callback, resultReceiver);
20619    }
20620
20621    @Override
20622    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20623        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20624
20625        DumpState dumpState = new DumpState();
20626        boolean fullPreferred = false;
20627        boolean checkin = false;
20628
20629        String packageName = null;
20630        ArraySet<String> permissionNames = null;
20631
20632        int opti = 0;
20633        while (opti < args.length) {
20634            String opt = args[opti];
20635            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20636                break;
20637            }
20638            opti++;
20639
20640            if ("-a".equals(opt)) {
20641                // Right now we only know how to print all.
20642            } else if ("-h".equals(opt)) {
20643                pw.println("Package manager dump options:");
20644                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20645                pw.println("    --checkin: dump for a checkin");
20646                pw.println("    -f: print details of intent filters");
20647                pw.println("    -h: print this help");
20648                pw.println("  cmd may be one of:");
20649                pw.println("    l[ibraries]: list known shared libraries");
20650                pw.println("    f[eatures]: list device features");
20651                pw.println("    k[eysets]: print known keysets");
20652                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20653                pw.println("    perm[issions]: dump permissions");
20654                pw.println("    permission [name ...]: dump declaration and use of given permission");
20655                pw.println("    pref[erred]: print preferred package settings");
20656                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20657                pw.println("    prov[iders]: dump content providers");
20658                pw.println("    p[ackages]: dump installed packages");
20659                pw.println("    s[hared-users]: dump shared user IDs");
20660                pw.println("    m[essages]: print collected runtime messages");
20661                pw.println("    v[erifiers]: print package verifier info");
20662                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20663                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20664                pw.println("    version: print database version info");
20665                pw.println("    write: write current settings now");
20666                pw.println("    installs: details about install sessions");
20667                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20668                pw.println("    dexopt: dump dexopt state");
20669                pw.println("    compiler-stats: dump compiler statistics");
20670                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20671                pw.println("    service-permissions: dump permissions required by services");
20672                pw.println("    <package.name>: info about given package");
20673                return;
20674            } else if ("--checkin".equals(opt)) {
20675                checkin = true;
20676            } else if ("-f".equals(opt)) {
20677                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20678            } else if ("--proto".equals(opt)) {
20679                dumpProto(fd);
20680                return;
20681            } else {
20682                pw.println("Unknown argument: " + opt + "; use -h for help");
20683            }
20684        }
20685
20686        // Is the caller requesting to dump a particular piece of data?
20687        if (opti < args.length) {
20688            String cmd = args[opti];
20689            opti++;
20690            // Is this a package name?
20691            if ("android".equals(cmd) || cmd.contains(".")) {
20692                packageName = cmd;
20693                // When dumping a single package, we always dump all of its
20694                // filter information since the amount of data will be reasonable.
20695                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20696            } else if ("check-permission".equals(cmd)) {
20697                if (opti >= args.length) {
20698                    pw.println("Error: check-permission missing permission argument");
20699                    return;
20700                }
20701                String perm = args[opti];
20702                opti++;
20703                if (opti >= args.length) {
20704                    pw.println("Error: check-permission missing package argument");
20705                    return;
20706                }
20707
20708                String pkg = args[opti];
20709                opti++;
20710                int user = UserHandle.getUserId(Binder.getCallingUid());
20711                if (opti < args.length) {
20712                    try {
20713                        user = Integer.parseInt(args[opti]);
20714                    } catch (NumberFormatException e) {
20715                        pw.println("Error: check-permission user argument is not a number: "
20716                                + args[opti]);
20717                        return;
20718                    }
20719                }
20720
20721                // Normalize package name to handle renamed packages and static libs
20722                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20723
20724                pw.println(checkPermission(perm, pkg, user));
20725                return;
20726            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20727                dumpState.setDump(DumpState.DUMP_LIBS);
20728            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20729                dumpState.setDump(DumpState.DUMP_FEATURES);
20730            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20731                if (opti >= args.length) {
20732                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20733                            | DumpState.DUMP_SERVICE_RESOLVERS
20734                            | DumpState.DUMP_RECEIVER_RESOLVERS
20735                            | DumpState.DUMP_CONTENT_RESOLVERS);
20736                } else {
20737                    while (opti < args.length) {
20738                        String name = args[opti];
20739                        if ("a".equals(name) || "activity".equals(name)) {
20740                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20741                        } else if ("s".equals(name) || "service".equals(name)) {
20742                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20743                        } else if ("r".equals(name) || "receiver".equals(name)) {
20744                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20745                        } else if ("c".equals(name) || "content".equals(name)) {
20746                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20747                        } else {
20748                            pw.println("Error: unknown resolver table type: " + name);
20749                            return;
20750                        }
20751                        opti++;
20752                    }
20753                }
20754            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20755                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20756            } else if ("permission".equals(cmd)) {
20757                if (opti >= args.length) {
20758                    pw.println("Error: permission requires permission name");
20759                    return;
20760                }
20761                permissionNames = new ArraySet<>();
20762                while (opti < args.length) {
20763                    permissionNames.add(args[opti]);
20764                    opti++;
20765                }
20766                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20767                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20768            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20769                dumpState.setDump(DumpState.DUMP_PREFERRED);
20770            } else if ("preferred-xml".equals(cmd)) {
20771                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20772                if (opti < args.length && "--full".equals(args[opti])) {
20773                    fullPreferred = true;
20774                    opti++;
20775                }
20776            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20777                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20778            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20779                dumpState.setDump(DumpState.DUMP_PACKAGES);
20780            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20781                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20782            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20783                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20784            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20785                dumpState.setDump(DumpState.DUMP_MESSAGES);
20786            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20787                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20788            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20789                    || "intent-filter-verifiers".equals(cmd)) {
20790                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20791            } else if ("version".equals(cmd)) {
20792                dumpState.setDump(DumpState.DUMP_VERSION);
20793            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20794                dumpState.setDump(DumpState.DUMP_KEYSETS);
20795            } else if ("installs".equals(cmd)) {
20796                dumpState.setDump(DumpState.DUMP_INSTALLS);
20797            } else if ("frozen".equals(cmd)) {
20798                dumpState.setDump(DumpState.DUMP_FROZEN);
20799            } else if ("volumes".equals(cmd)) {
20800                dumpState.setDump(DumpState.DUMP_VOLUMES);
20801            } else if ("dexopt".equals(cmd)) {
20802                dumpState.setDump(DumpState.DUMP_DEXOPT);
20803            } else if ("compiler-stats".equals(cmd)) {
20804                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20805            } else if ("changes".equals(cmd)) {
20806                dumpState.setDump(DumpState.DUMP_CHANGES);
20807            } else if ("service-permissions".equals(cmd)) {
20808                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
20809            } else if ("write".equals(cmd)) {
20810                synchronized (mPackages) {
20811                    mSettings.writeLPr();
20812                    pw.println("Settings written.");
20813                    return;
20814                }
20815            }
20816        }
20817
20818        if (checkin) {
20819            pw.println("vers,1");
20820        }
20821
20822        // reader
20823        synchronized (mPackages) {
20824            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20825                if (!checkin) {
20826                    if (dumpState.onTitlePrinted())
20827                        pw.println();
20828                    pw.println("Database versions:");
20829                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20830                }
20831            }
20832
20833            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20834                if (!checkin) {
20835                    if (dumpState.onTitlePrinted())
20836                        pw.println();
20837                    pw.println("Verifiers:");
20838                    pw.print("  Required: ");
20839                    pw.print(mRequiredVerifierPackage);
20840                    pw.print(" (uid=");
20841                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20842                            UserHandle.USER_SYSTEM));
20843                    pw.println(")");
20844                } else if (mRequiredVerifierPackage != null) {
20845                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20846                    pw.print(",");
20847                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20848                            UserHandle.USER_SYSTEM));
20849                }
20850            }
20851
20852            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20853                    packageName == null) {
20854                if (mIntentFilterVerifierComponent != null) {
20855                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20856                    if (!checkin) {
20857                        if (dumpState.onTitlePrinted())
20858                            pw.println();
20859                        pw.println("Intent Filter Verifier:");
20860                        pw.print("  Using: ");
20861                        pw.print(verifierPackageName);
20862                        pw.print(" (uid=");
20863                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20864                                UserHandle.USER_SYSTEM));
20865                        pw.println(")");
20866                    } else if (verifierPackageName != null) {
20867                        pw.print("ifv,"); pw.print(verifierPackageName);
20868                        pw.print(",");
20869                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20870                                UserHandle.USER_SYSTEM));
20871                    }
20872                } else {
20873                    pw.println();
20874                    pw.println("No Intent Filter Verifier available!");
20875                }
20876            }
20877
20878            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20879                boolean printedHeader = false;
20880                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20881                while (it.hasNext()) {
20882                    String libName = it.next();
20883                    LongSparseArray<SharedLibraryEntry> versionedLib
20884                            = mSharedLibraries.get(libName);
20885                    if (versionedLib == null) {
20886                        continue;
20887                    }
20888                    final int versionCount = versionedLib.size();
20889                    for (int i = 0; i < versionCount; i++) {
20890                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20891                        if (!checkin) {
20892                            if (!printedHeader) {
20893                                if (dumpState.onTitlePrinted())
20894                                    pw.println();
20895                                pw.println("Libraries:");
20896                                printedHeader = true;
20897                            }
20898                            pw.print("  ");
20899                        } else {
20900                            pw.print("lib,");
20901                        }
20902                        pw.print(libEntry.info.getName());
20903                        if (libEntry.info.isStatic()) {
20904                            pw.print(" version=" + libEntry.info.getLongVersion());
20905                        }
20906                        if (!checkin) {
20907                            pw.print(" -> ");
20908                        }
20909                        if (libEntry.path != null) {
20910                            pw.print(" (jar) ");
20911                            pw.print(libEntry.path);
20912                        } else {
20913                            pw.print(" (apk) ");
20914                            pw.print(libEntry.apk);
20915                        }
20916                        pw.println();
20917                    }
20918                }
20919            }
20920
20921            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20922                if (dumpState.onTitlePrinted())
20923                    pw.println();
20924                if (!checkin) {
20925                    pw.println("Features:");
20926                }
20927
20928                synchronized (mAvailableFeatures) {
20929                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20930                        if (checkin) {
20931                            pw.print("feat,");
20932                            pw.print(feat.name);
20933                            pw.print(",");
20934                            pw.println(feat.version);
20935                        } else {
20936                            pw.print("  ");
20937                            pw.print(feat.name);
20938                            if (feat.version > 0) {
20939                                pw.print(" version=");
20940                                pw.print(feat.version);
20941                            }
20942                            pw.println();
20943                        }
20944                    }
20945                }
20946            }
20947
20948            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20949                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20950                        : "Activity Resolver Table:", "  ", packageName,
20951                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20952                    dumpState.setTitlePrinted(true);
20953                }
20954            }
20955            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20956                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20957                        : "Receiver Resolver Table:", "  ", packageName,
20958                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20959                    dumpState.setTitlePrinted(true);
20960                }
20961            }
20962            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20963                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20964                        : "Service Resolver Table:", "  ", packageName,
20965                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20966                    dumpState.setTitlePrinted(true);
20967                }
20968            }
20969            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20970                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20971                        : "Provider Resolver Table:", "  ", packageName,
20972                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20973                    dumpState.setTitlePrinted(true);
20974                }
20975            }
20976
20977            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20978                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20979                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20980                    int user = mSettings.mPreferredActivities.keyAt(i);
20981                    if (pir.dump(pw,
20982                            dumpState.getTitlePrinted()
20983                                ? "\nPreferred Activities User " + user + ":"
20984                                : "Preferred Activities User " + user + ":", "  ",
20985                            packageName, true, false)) {
20986                        dumpState.setTitlePrinted(true);
20987                    }
20988                }
20989            }
20990
20991            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20992                pw.flush();
20993                FileOutputStream fout = new FileOutputStream(fd);
20994                BufferedOutputStream str = new BufferedOutputStream(fout);
20995                XmlSerializer serializer = new FastXmlSerializer();
20996                try {
20997                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20998                    serializer.startDocument(null, true);
20999                    serializer.setFeature(
21000                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21001                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21002                    serializer.endDocument();
21003                    serializer.flush();
21004                } catch (IllegalArgumentException e) {
21005                    pw.println("Failed writing: " + e);
21006                } catch (IllegalStateException e) {
21007                    pw.println("Failed writing: " + e);
21008                } catch (IOException e) {
21009                    pw.println("Failed writing: " + e);
21010                }
21011            }
21012
21013            if (!checkin
21014                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21015                    && packageName == null) {
21016                pw.println();
21017                int count = mSettings.mPackages.size();
21018                if (count == 0) {
21019                    pw.println("No applications!");
21020                    pw.println();
21021                } else {
21022                    final String prefix = "  ";
21023                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21024                    if (allPackageSettings.size() == 0) {
21025                        pw.println("No domain preferred apps!");
21026                        pw.println();
21027                    } else {
21028                        pw.println("App verification status:");
21029                        pw.println();
21030                        count = 0;
21031                        for (PackageSetting ps : allPackageSettings) {
21032                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21033                            if (ivi == null || ivi.getPackageName() == null) continue;
21034                            pw.println(prefix + "Package: " + ivi.getPackageName());
21035                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21036                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21037                            pw.println();
21038                            count++;
21039                        }
21040                        if (count == 0) {
21041                            pw.println(prefix + "No app verification established.");
21042                            pw.println();
21043                        }
21044                        for (int userId : sUserManager.getUserIds()) {
21045                            pw.println("App linkages for user " + userId + ":");
21046                            pw.println();
21047                            count = 0;
21048                            for (PackageSetting ps : allPackageSettings) {
21049                                final long status = ps.getDomainVerificationStatusForUser(userId);
21050                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21051                                        && !DEBUG_DOMAIN_VERIFICATION) {
21052                                    continue;
21053                                }
21054                                pw.println(prefix + "Package: " + ps.name);
21055                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21056                                String statusStr = IntentFilterVerificationInfo.
21057                                        getStatusStringFromValue(status);
21058                                pw.println(prefix + "Status:  " + statusStr);
21059                                pw.println();
21060                                count++;
21061                            }
21062                            if (count == 0) {
21063                                pw.println(prefix + "No configured app linkages.");
21064                                pw.println();
21065                            }
21066                        }
21067                    }
21068                }
21069            }
21070
21071            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21072                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21073            }
21074
21075            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21076                boolean printedSomething = false;
21077                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21078                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21079                        continue;
21080                    }
21081                    if (!printedSomething) {
21082                        if (dumpState.onTitlePrinted())
21083                            pw.println();
21084                        pw.println("Registered ContentProviders:");
21085                        printedSomething = true;
21086                    }
21087                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21088                    pw.print("    "); pw.println(p.toString());
21089                }
21090                printedSomething = false;
21091                for (Map.Entry<String, PackageParser.Provider> entry :
21092                        mProvidersByAuthority.entrySet()) {
21093                    PackageParser.Provider p = entry.getValue();
21094                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21095                        continue;
21096                    }
21097                    if (!printedSomething) {
21098                        if (dumpState.onTitlePrinted())
21099                            pw.println();
21100                        pw.println("ContentProvider Authorities:");
21101                        printedSomething = true;
21102                    }
21103                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21104                    pw.print("    "); pw.println(p.toString());
21105                    if (p.info != null && p.info.applicationInfo != null) {
21106                        final String appInfo = p.info.applicationInfo.toString();
21107                        pw.print("      applicationInfo="); pw.println(appInfo);
21108                    }
21109                }
21110            }
21111
21112            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21113                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21114            }
21115
21116            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21117                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21118            }
21119
21120            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21121                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21122            }
21123
21124            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21125                if (dumpState.onTitlePrinted()) pw.println();
21126                pw.println("Package Changes:");
21127                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21128                final int K = mChangedPackages.size();
21129                for (int i = 0; i < K; i++) {
21130                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21131                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21132                    final int N = changes.size();
21133                    if (N == 0) {
21134                        pw.print("    "); pw.println("No packages changed");
21135                    } else {
21136                        for (int j = 0; j < N; j++) {
21137                            final String pkgName = changes.valueAt(j);
21138                            final int sequenceNumber = changes.keyAt(j);
21139                            pw.print("    ");
21140                            pw.print("seq=");
21141                            pw.print(sequenceNumber);
21142                            pw.print(", package=");
21143                            pw.println(pkgName);
21144                        }
21145                    }
21146                }
21147            }
21148
21149            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21150                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21151            }
21152
21153            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21154                // XXX should handle packageName != null by dumping only install data that
21155                // the given package is involved with.
21156                if (dumpState.onTitlePrinted()) pw.println();
21157
21158                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21159                ipw.println();
21160                ipw.println("Frozen packages:");
21161                ipw.increaseIndent();
21162                if (mFrozenPackages.size() == 0) {
21163                    ipw.println("(none)");
21164                } else {
21165                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21166                        ipw.println(mFrozenPackages.valueAt(i));
21167                    }
21168                }
21169                ipw.decreaseIndent();
21170            }
21171
21172            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21173                if (dumpState.onTitlePrinted()) pw.println();
21174
21175                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21176                ipw.println();
21177                ipw.println("Loaded volumes:");
21178                ipw.increaseIndent();
21179                if (mLoadedVolumes.size() == 0) {
21180                    ipw.println("(none)");
21181                } else {
21182                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
21183                        ipw.println(mLoadedVolumes.valueAt(i));
21184                    }
21185                }
21186                ipw.decreaseIndent();
21187            }
21188
21189            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21190                    && packageName == null) {
21191                if (dumpState.onTitlePrinted()) pw.println();
21192                pw.println("Service permissions:");
21193
21194                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
21195                while (filterIterator.hasNext()) {
21196                    final ServiceIntentInfo info = filterIterator.next();
21197                    final ServiceInfo serviceInfo = info.service.info;
21198                    final String permission = serviceInfo.permission;
21199                    if (permission != null) {
21200                        pw.print("    ");
21201                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21202                        pw.print(": ");
21203                        pw.println(permission);
21204                    }
21205                }
21206            }
21207
21208            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21209                if (dumpState.onTitlePrinted()) pw.println();
21210                dumpDexoptStateLPr(pw, packageName);
21211            }
21212
21213            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21214                if (dumpState.onTitlePrinted()) pw.println();
21215                dumpCompilerStatsLPr(pw, packageName);
21216            }
21217
21218            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21219                if (dumpState.onTitlePrinted()) pw.println();
21220                mSettings.dumpReadMessagesLPr(pw, dumpState);
21221
21222                pw.println();
21223                pw.println("Package warning messages:");
21224                dumpCriticalInfo(pw, null);
21225            }
21226
21227            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21228                dumpCriticalInfo(pw, "msg,");
21229            }
21230        }
21231
21232        // PackageInstaller should be called outside of mPackages lock
21233        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21234            // XXX should handle packageName != null by dumping only install data that
21235            // the given package is involved with.
21236            if (dumpState.onTitlePrinted()) pw.println();
21237            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21238        }
21239    }
21240
21241    private void dumpProto(FileDescriptor fd) {
21242        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21243
21244        synchronized (mPackages) {
21245            final long requiredVerifierPackageToken =
21246                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21247            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21248            proto.write(
21249                    PackageServiceDumpProto.PackageShortProto.UID,
21250                    getPackageUid(
21251                            mRequiredVerifierPackage,
21252                            MATCH_DEBUG_TRIAGED_MISSING,
21253                            UserHandle.USER_SYSTEM));
21254            proto.end(requiredVerifierPackageToken);
21255
21256            if (mIntentFilterVerifierComponent != null) {
21257                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21258                final long verifierPackageToken =
21259                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21260                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21261                proto.write(
21262                        PackageServiceDumpProto.PackageShortProto.UID,
21263                        getPackageUid(
21264                                verifierPackageName,
21265                                MATCH_DEBUG_TRIAGED_MISSING,
21266                                UserHandle.USER_SYSTEM));
21267                proto.end(verifierPackageToken);
21268            }
21269
21270            dumpSharedLibrariesProto(proto);
21271            dumpFeaturesProto(proto);
21272            mSettings.dumpPackagesProto(proto);
21273            mSettings.dumpSharedUsersProto(proto);
21274            dumpCriticalInfo(proto);
21275        }
21276        proto.flush();
21277    }
21278
21279    private void dumpFeaturesProto(ProtoOutputStream proto) {
21280        synchronized (mAvailableFeatures) {
21281            final int count = mAvailableFeatures.size();
21282            for (int i = 0; i < count; i++) {
21283                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21284            }
21285        }
21286    }
21287
21288    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21289        final int count = mSharedLibraries.size();
21290        for (int i = 0; i < count; i++) {
21291            final String libName = mSharedLibraries.keyAt(i);
21292            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21293            if (versionedLib == null) {
21294                continue;
21295            }
21296            final int versionCount = versionedLib.size();
21297            for (int j = 0; j < versionCount; j++) {
21298                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21299                final long sharedLibraryToken =
21300                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21301                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21302                final boolean isJar = (libEntry.path != null);
21303                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21304                if (isJar) {
21305                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21306                } else {
21307                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21308                }
21309                proto.end(sharedLibraryToken);
21310            }
21311        }
21312    }
21313
21314    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21315        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21316        ipw.println();
21317        ipw.println("Dexopt state:");
21318        ipw.increaseIndent();
21319        Collection<PackageParser.Package> packages = null;
21320        if (packageName != null) {
21321            PackageParser.Package targetPackage = mPackages.get(packageName);
21322            if (targetPackage != null) {
21323                packages = Collections.singletonList(targetPackage);
21324            } else {
21325                ipw.println("Unable to find package: " + packageName);
21326                return;
21327            }
21328        } else {
21329            packages = mPackages.values();
21330        }
21331
21332        for (PackageParser.Package pkg : packages) {
21333            ipw.println("[" + pkg.packageName + "]");
21334            ipw.increaseIndent();
21335            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21336                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21337            ipw.decreaseIndent();
21338        }
21339    }
21340
21341    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21342        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21343        ipw.println();
21344        ipw.println("Compiler stats:");
21345        ipw.increaseIndent();
21346        Collection<PackageParser.Package> packages = null;
21347        if (packageName != null) {
21348            PackageParser.Package targetPackage = mPackages.get(packageName);
21349            if (targetPackage != null) {
21350                packages = Collections.singletonList(targetPackage);
21351            } else {
21352                ipw.println("Unable to find package: " + packageName);
21353                return;
21354            }
21355        } else {
21356            packages = mPackages.values();
21357        }
21358
21359        for (PackageParser.Package pkg : packages) {
21360            ipw.println("[" + pkg.packageName + "]");
21361            ipw.increaseIndent();
21362
21363            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21364            if (stats == null) {
21365                ipw.println("(No recorded stats)");
21366            } else {
21367                stats.dump(ipw);
21368            }
21369            ipw.decreaseIndent();
21370        }
21371    }
21372
21373    private String dumpDomainString(String packageName) {
21374        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21375                .getList();
21376        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21377
21378        ArraySet<String> result = new ArraySet<>();
21379        if (iviList.size() > 0) {
21380            for (IntentFilterVerificationInfo ivi : iviList) {
21381                for (String host : ivi.getDomains()) {
21382                    result.add(host);
21383                }
21384            }
21385        }
21386        if (filters != null && filters.size() > 0) {
21387            for (IntentFilter filter : filters) {
21388                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21389                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21390                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21391                    result.addAll(filter.getHostsList());
21392                }
21393            }
21394        }
21395
21396        StringBuilder sb = new StringBuilder(result.size() * 16);
21397        for (String domain : result) {
21398            if (sb.length() > 0) sb.append(" ");
21399            sb.append(domain);
21400        }
21401        return sb.toString();
21402    }
21403
21404    // ------- apps on sdcard specific code -------
21405    static final boolean DEBUG_SD_INSTALL = false;
21406
21407    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21408
21409    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21410
21411    private boolean mMediaMounted = false;
21412
21413    static String getEncryptKey() {
21414        try {
21415            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21416                    SD_ENCRYPTION_KEYSTORE_NAME);
21417            if (sdEncKey == null) {
21418                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21419                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21420                if (sdEncKey == null) {
21421                    Slog.e(TAG, "Failed to create encryption keys");
21422                    return null;
21423                }
21424            }
21425            return sdEncKey;
21426        } catch (NoSuchAlgorithmException nsae) {
21427            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21428            return null;
21429        } catch (IOException ioe) {
21430            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21431            return null;
21432        }
21433    }
21434
21435    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21436            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21437        final int size = infos.size();
21438        final String[] packageNames = new String[size];
21439        final int[] packageUids = new int[size];
21440        for (int i = 0; i < size; i++) {
21441            final ApplicationInfo info = infos.get(i);
21442            packageNames[i] = info.packageName;
21443            packageUids[i] = info.uid;
21444        }
21445        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21446                finishedReceiver);
21447    }
21448
21449    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21450            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21451        sendResourcesChangedBroadcast(mediaStatus, replacing,
21452                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21453    }
21454
21455    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21456            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21457        int size = pkgList.length;
21458        if (size > 0) {
21459            // Send broadcasts here
21460            Bundle extras = new Bundle();
21461            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21462            if (uidArr != null) {
21463                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21464            }
21465            if (replacing) {
21466                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21467            }
21468            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21469                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21470            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21471        }
21472    }
21473
21474    private void loadPrivatePackages(final VolumeInfo vol) {
21475        mHandler.post(new Runnable() {
21476            @Override
21477            public void run() {
21478                loadPrivatePackagesInner(vol);
21479            }
21480        });
21481    }
21482
21483    private void loadPrivatePackagesInner(VolumeInfo vol) {
21484        final String volumeUuid = vol.fsUuid;
21485        if (TextUtils.isEmpty(volumeUuid)) {
21486            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21487            return;
21488        }
21489
21490        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21491        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21492        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21493
21494        final VersionInfo ver;
21495        final List<PackageSetting> packages;
21496        synchronized (mPackages) {
21497            ver = mSettings.findOrCreateVersion(volumeUuid);
21498            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21499        }
21500
21501        for (PackageSetting ps : packages) {
21502            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21503            synchronized (mInstallLock) {
21504                final PackageParser.Package pkg;
21505                try {
21506                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21507                    loaded.add(pkg.applicationInfo);
21508
21509                } catch (PackageManagerException e) {
21510                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21511                }
21512
21513                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21514                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21515                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21516                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21517                }
21518            }
21519        }
21520
21521        // Reconcile app data for all started/unlocked users
21522        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21523        final UserManager um = mContext.getSystemService(UserManager.class);
21524        UserManagerInternal umInternal = getUserManagerInternal();
21525        for (UserInfo user : um.getUsers()) {
21526            final int flags;
21527            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21528                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21529            } else if (umInternal.isUserRunning(user.id)) {
21530                flags = StorageManager.FLAG_STORAGE_DE;
21531            } else {
21532                continue;
21533            }
21534
21535            try {
21536                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21537                synchronized (mInstallLock) {
21538                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21539                }
21540            } catch (IllegalStateException e) {
21541                // Device was probably ejected, and we'll process that event momentarily
21542                Slog.w(TAG, "Failed to prepare storage: " + e);
21543            }
21544        }
21545
21546        synchronized (mPackages) {
21547            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21548            if (sdkUpdated) {
21549                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21550                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21551            }
21552            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21553                    mPermissionCallback);
21554
21555            // Yay, everything is now upgraded
21556            ver.forceCurrent();
21557
21558            mSettings.writeLPr();
21559        }
21560
21561        for (PackageFreezer freezer : freezers) {
21562            freezer.close();
21563        }
21564
21565        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21566        sendResourcesChangedBroadcast(true, false, loaded, null);
21567        mLoadedVolumes.add(vol.getId());
21568    }
21569
21570    private void unloadPrivatePackages(final VolumeInfo vol) {
21571        mHandler.post(new Runnable() {
21572            @Override
21573            public void run() {
21574                unloadPrivatePackagesInner(vol);
21575            }
21576        });
21577    }
21578
21579    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21580        final String volumeUuid = vol.fsUuid;
21581        if (TextUtils.isEmpty(volumeUuid)) {
21582            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21583            return;
21584        }
21585
21586        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21587        synchronized (mInstallLock) {
21588        synchronized (mPackages) {
21589            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21590            for (PackageSetting ps : packages) {
21591                if (ps.pkg == null) continue;
21592
21593                final ApplicationInfo info = ps.pkg.applicationInfo;
21594                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21595                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21596
21597                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21598                        "unloadPrivatePackagesInner")) {
21599                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21600                            false, null)) {
21601                        unloaded.add(info);
21602                    } else {
21603                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21604                    }
21605                }
21606
21607                // Try very hard to release any references to this package
21608                // so we don't risk the system server being killed due to
21609                // open FDs
21610                AttributeCache.instance().removePackage(ps.name);
21611            }
21612
21613            mSettings.writeLPr();
21614        }
21615        }
21616
21617        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21618        sendResourcesChangedBroadcast(false, false, unloaded, null);
21619        mLoadedVolumes.remove(vol.getId());
21620
21621        // Try very hard to release any references to this path so we don't risk
21622        // the system server being killed due to open FDs
21623        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21624
21625        for (int i = 0; i < 3; i++) {
21626            System.gc();
21627            System.runFinalization();
21628        }
21629    }
21630
21631    private void assertPackageKnown(String volumeUuid, String packageName)
21632            throws PackageManagerException {
21633        synchronized (mPackages) {
21634            // Normalize package name to handle renamed packages
21635            packageName = normalizePackageNameLPr(packageName);
21636
21637            final PackageSetting ps = mSettings.mPackages.get(packageName);
21638            if (ps == null) {
21639                throw new PackageManagerException("Package " + packageName + " is unknown");
21640            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21641                throw new PackageManagerException(
21642                        "Package " + packageName + " found on unknown volume " + volumeUuid
21643                                + "; expected volume " + ps.volumeUuid);
21644            }
21645        }
21646    }
21647
21648    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21649            throws PackageManagerException {
21650        synchronized (mPackages) {
21651            // Normalize package name to handle renamed packages
21652            packageName = normalizePackageNameLPr(packageName);
21653
21654            final PackageSetting ps = mSettings.mPackages.get(packageName);
21655            if (ps == null) {
21656                throw new PackageManagerException("Package " + packageName + " is unknown");
21657            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21658                throw new PackageManagerException(
21659                        "Package " + packageName + " found on unknown volume " + volumeUuid
21660                                + "; expected volume " + ps.volumeUuid);
21661            } else if (!ps.getInstalled(userId)) {
21662                throw new PackageManagerException(
21663                        "Package " + packageName + " not installed for user " + userId);
21664            }
21665        }
21666    }
21667
21668    private List<String> collectAbsoluteCodePaths() {
21669        synchronized (mPackages) {
21670            List<String> codePaths = new ArrayList<>();
21671            final int packageCount = mSettings.mPackages.size();
21672            for (int i = 0; i < packageCount; i++) {
21673                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21674                codePaths.add(ps.codePath.getAbsolutePath());
21675            }
21676            return codePaths;
21677        }
21678    }
21679
21680    /**
21681     * Examine all apps present on given mounted volume, and destroy apps that
21682     * aren't expected, either due to uninstallation or reinstallation on
21683     * another volume.
21684     */
21685    private void reconcileApps(String volumeUuid) {
21686        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21687        List<File> filesToDelete = null;
21688
21689        final File[] files = FileUtils.listFilesOrEmpty(
21690                Environment.getDataAppDirectory(volumeUuid));
21691        for (File file : files) {
21692            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21693                    && !PackageInstallerService.isStageName(file.getName());
21694            if (!isPackage) {
21695                // Ignore entries which are not packages
21696                continue;
21697            }
21698
21699            String absolutePath = file.getAbsolutePath();
21700
21701            boolean pathValid = false;
21702            final int absoluteCodePathCount = absoluteCodePaths.size();
21703            for (int i = 0; i < absoluteCodePathCount; i++) {
21704                String absoluteCodePath = absoluteCodePaths.get(i);
21705                if (absolutePath.startsWith(absoluteCodePath)) {
21706                    pathValid = true;
21707                    break;
21708                }
21709            }
21710
21711            if (!pathValid) {
21712                if (filesToDelete == null) {
21713                    filesToDelete = new ArrayList<>();
21714                }
21715                filesToDelete.add(file);
21716            }
21717        }
21718
21719        if (filesToDelete != null) {
21720            final int fileToDeleteCount = filesToDelete.size();
21721            for (int i = 0; i < fileToDeleteCount; i++) {
21722                File fileToDelete = filesToDelete.get(i);
21723                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21724                synchronized (mInstallLock) {
21725                    removeCodePathLI(fileToDelete);
21726                }
21727            }
21728        }
21729    }
21730
21731    /**
21732     * Reconcile all app data for the given user.
21733     * <p>
21734     * Verifies that directories exist and that ownership and labeling is
21735     * correct for all installed apps on all mounted volumes.
21736     */
21737    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21738        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21739        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21740            final String volumeUuid = vol.getFsUuid();
21741            synchronized (mInstallLock) {
21742                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21743            }
21744        }
21745    }
21746
21747    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21748            boolean migrateAppData) {
21749        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21750    }
21751
21752    /**
21753     * Reconcile all app data on given mounted volume.
21754     * <p>
21755     * Destroys app data that isn't expected, either due to uninstallation or
21756     * reinstallation on another volume.
21757     * <p>
21758     * Verifies that directories exist and that ownership and labeling is
21759     * correct for all installed apps.
21760     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
21761     */
21762    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21763            boolean migrateAppData, boolean onlyCoreApps) {
21764        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21765                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21766        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21767
21768        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21769        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21770
21771        // First look for stale data that doesn't belong, and check if things
21772        // have changed since we did our last restorecon
21773        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21774            if (StorageManager.isFileEncryptedNativeOrEmulated()
21775                    && !StorageManager.isUserKeyUnlocked(userId)) {
21776                throw new RuntimeException(
21777                        "Yikes, someone asked us to reconcile CE storage while " + userId
21778                                + " was still locked; this would have caused massive data loss!");
21779            }
21780
21781            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21782            for (File file : files) {
21783                final String packageName = file.getName();
21784                try {
21785                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21786                } catch (PackageManagerException e) {
21787                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21788                    try {
21789                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21790                                StorageManager.FLAG_STORAGE_CE, 0);
21791                    } catch (InstallerException e2) {
21792                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21793                    }
21794                }
21795            }
21796        }
21797        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21798            final File[] files = FileUtils.listFilesOrEmpty(deDir);
21799            for (File file : files) {
21800                final String packageName = file.getName();
21801                try {
21802                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21803                } catch (PackageManagerException e) {
21804                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21805                    try {
21806                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21807                                StorageManager.FLAG_STORAGE_DE, 0);
21808                    } catch (InstallerException e2) {
21809                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21810                    }
21811                }
21812            }
21813        }
21814
21815        // Ensure that data directories are ready to roll for all packages
21816        // installed for this volume and user
21817        final List<PackageSetting> packages;
21818        synchronized (mPackages) {
21819            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21820        }
21821        int preparedCount = 0;
21822        for (PackageSetting ps : packages) {
21823            final String packageName = ps.name;
21824            if (ps.pkg == null) {
21825                Slog.w(TAG, "Odd, missing scanned package " + packageName);
21826                // TODO: might be due to legacy ASEC apps; we should circle back
21827                // and reconcile again once they're scanned
21828                continue;
21829            }
21830            // Skip non-core apps if requested
21831            if (onlyCoreApps && !ps.pkg.coreApp) {
21832                result.add(packageName);
21833                continue;
21834            }
21835
21836            if (ps.getInstalled(userId)) {
21837                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21838                preparedCount++;
21839            }
21840        }
21841
21842        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21843        return result;
21844    }
21845
21846    /**
21847     * Prepare app data for the given app just after it was installed or
21848     * upgraded. This method carefully only touches users that it's installed
21849     * for, and it forces a restorecon to handle any seinfo changes.
21850     * <p>
21851     * Verifies that directories exist and that ownership and labeling is
21852     * correct for all installed apps. If there is an ownership mismatch, it
21853     * will try recovering system apps by wiping data; third-party app data is
21854     * left intact.
21855     * <p>
21856     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21857     */
21858    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21859        final PackageSetting ps;
21860        synchronized (mPackages) {
21861            ps = mSettings.mPackages.get(pkg.packageName);
21862            mSettings.writeKernelMappingLPr(ps);
21863        }
21864
21865        final UserManager um = mContext.getSystemService(UserManager.class);
21866        UserManagerInternal umInternal = getUserManagerInternal();
21867        for (UserInfo user : um.getUsers()) {
21868            final int flags;
21869            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21870                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21871            } else if (umInternal.isUserRunning(user.id)) {
21872                flags = StorageManager.FLAG_STORAGE_DE;
21873            } else {
21874                continue;
21875            }
21876
21877            if (ps.getInstalled(user.id)) {
21878                // TODO: when user data is locked, mark that we're still dirty
21879                prepareAppDataLIF(pkg, user.id, flags);
21880            }
21881        }
21882    }
21883
21884    /**
21885     * Prepare app data for the given app.
21886     * <p>
21887     * Verifies that directories exist and that ownership and labeling is
21888     * correct for all installed apps. If there is an ownership mismatch, this
21889     * will try recovering system apps by wiping data; third-party app data is
21890     * left intact.
21891     */
21892    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21893        if (pkg == null) {
21894            Slog.wtf(TAG, "Package was null!", new Throwable());
21895            return;
21896        }
21897        prepareAppDataLeafLIF(pkg, userId, flags);
21898        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21899        for (int i = 0; i < childCount; i++) {
21900            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21901        }
21902    }
21903
21904    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
21905            boolean maybeMigrateAppData) {
21906        prepareAppDataLIF(pkg, userId, flags);
21907
21908        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21909            // We may have just shuffled around app data directories, so
21910            // prepare them one more time
21911            prepareAppDataLIF(pkg, userId, flags);
21912        }
21913    }
21914
21915    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21916        if (DEBUG_APP_DATA) {
21917            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21918                    + Integer.toHexString(flags));
21919        }
21920
21921        final String volumeUuid = pkg.volumeUuid;
21922        final String packageName = pkg.packageName;
21923        final ApplicationInfo app = pkg.applicationInfo;
21924        final int appId = UserHandle.getAppId(app.uid);
21925
21926        Preconditions.checkNotNull(app.seInfo);
21927
21928        long ceDataInode = -1;
21929        try {
21930            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21931                    appId, app.seInfo, app.targetSdkVersion);
21932        } catch (InstallerException e) {
21933            if (app.isSystemApp()) {
21934                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21935                        + ", but trying to recover: " + e);
21936                destroyAppDataLeafLIF(pkg, userId, flags);
21937                try {
21938                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21939                            appId, app.seInfo, app.targetSdkVersion);
21940                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21941                } catch (InstallerException e2) {
21942                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
21943                }
21944            } else {
21945                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21946            }
21947        }
21948
21949        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21950            // TODO: mark this structure as dirty so we persist it!
21951            synchronized (mPackages) {
21952                final PackageSetting ps = mSettings.mPackages.get(packageName);
21953                if (ps != null) {
21954                    ps.setCeDataInode(ceDataInode, userId);
21955                }
21956            }
21957        }
21958
21959        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21960    }
21961
21962    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21963        if (pkg == null) {
21964            Slog.wtf(TAG, "Package was null!", new Throwable());
21965            return;
21966        }
21967        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21968        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21969        for (int i = 0; i < childCount; i++) {
21970            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21971        }
21972    }
21973
21974    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21975        final String volumeUuid = pkg.volumeUuid;
21976        final String packageName = pkg.packageName;
21977        final ApplicationInfo app = pkg.applicationInfo;
21978
21979        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21980            // Create a native library symlink only if we have native libraries
21981            // and if the native libraries are 32 bit libraries. We do not provide
21982            // this symlink for 64 bit libraries.
21983            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21984                final String nativeLibPath = app.nativeLibraryDir;
21985                try {
21986                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21987                            nativeLibPath, userId);
21988                } catch (InstallerException e) {
21989                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21990                }
21991            }
21992        }
21993    }
21994
21995    /**
21996     * For system apps on non-FBE devices, this method migrates any existing
21997     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21998     * requested by the app.
21999     */
22000    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22001        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22002                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22003            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22004                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22005            try {
22006                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22007                        storageTarget);
22008            } catch (InstallerException e) {
22009                logCriticalInfo(Log.WARN,
22010                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22011            }
22012            return true;
22013        } else {
22014            return false;
22015        }
22016    }
22017
22018    public PackageFreezer freezePackage(String packageName, String killReason) {
22019        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22020    }
22021
22022    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22023        return new PackageFreezer(packageName, userId, killReason);
22024    }
22025
22026    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22027            String killReason) {
22028        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22029    }
22030
22031    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22032            String killReason) {
22033        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22034            return new PackageFreezer();
22035        } else {
22036            return freezePackage(packageName, userId, killReason);
22037        }
22038    }
22039
22040    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22041            String killReason) {
22042        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22043    }
22044
22045    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22046            String killReason) {
22047        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22048            return new PackageFreezer();
22049        } else {
22050            return freezePackage(packageName, userId, killReason);
22051        }
22052    }
22053
22054    /**
22055     * Class that freezes and kills the given package upon creation, and
22056     * unfreezes it upon closing. This is typically used when doing surgery on
22057     * app code/data to prevent the app from running while you're working.
22058     */
22059    private class PackageFreezer implements AutoCloseable {
22060        private final String mPackageName;
22061        private final PackageFreezer[] mChildren;
22062
22063        private final boolean mWeFroze;
22064
22065        private final AtomicBoolean mClosed = new AtomicBoolean();
22066        private final CloseGuard mCloseGuard = CloseGuard.get();
22067
22068        /**
22069         * Create and return a stub freezer that doesn't actually do anything,
22070         * typically used when someone requested
22071         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22072         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22073         */
22074        public PackageFreezer() {
22075            mPackageName = null;
22076            mChildren = null;
22077            mWeFroze = false;
22078            mCloseGuard.open("close");
22079        }
22080
22081        public PackageFreezer(String packageName, int userId, String killReason) {
22082            synchronized (mPackages) {
22083                mPackageName = packageName;
22084                mWeFroze = mFrozenPackages.add(mPackageName);
22085
22086                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22087                if (ps != null) {
22088                    killApplication(ps.name, ps.appId, userId, killReason);
22089                }
22090
22091                final PackageParser.Package p = mPackages.get(packageName);
22092                if (p != null && p.childPackages != null) {
22093                    final int N = p.childPackages.size();
22094                    mChildren = new PackageFreezer[N];
22095                    for (int i = 0; i < N; i++) {
22096                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22097                                userId, killReason);
22098                    }
22099                } else {
22100                    mChildren = null;
22101                }
22102            }
22103            mCloseGuard.open("close");
22104        }
22105
22106        @Override
22107        protected void finalize() throws Throwable {
22108            try {
22109                if (mCloseGuard != null) {
22110                    mCloseGuard.warnIfOpen();
22111                }
22112
22113                close();
22114            } finally {
22115                super.finalize();
22116            }
22117        }
22118
22119        @Override
22120        public void close() {
22121            mCloseGuard.close();
22122            if (mClosed.compareAndSet(false, true)) {
22123                synchronized (mPackages) {
22124                    if (mWeFroze) {
22125                        mFrozenPackages.remove(mPackageName);
22126                    }
22127
22128                    if (mChildren != null) {
22129                        for (PackageFreezer freezer : mChildren) {
22130                            freezer.close();
22131                        }
22132                    }
22133                }
22134            }
22135        }
22136    }
22137
22138    /**
22139     * Verify that given package is currently frozen.
22140     */
22141    private void checkPackageFrozen(String packageName) {
22142        synchronized (mPackages) {
22143            if (!mFrozenPackages.contains(packageName)) {
22144                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22145            }
22146        }
22147    }
22148
22149    @Override
22150    public int movePackage(final String packageName, final String volumeUuid) {
22151        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22152
22153        final int callingUid = Binder.getCallingUid();
22154        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22155        final int moveId = mNextMoveId.getAndIncrement();
22156        mHandler.post(new Runnable() {
22157            @Override
22158            public void run() {
22159                try {
22160                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22161                } catch (PackageManagerException e) {
22162                    Slog.w(TAG, "Failed to move " + packageName, e);
22163                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22164                }
22165            }
22166        });
22167        return moveId;
22168    }
22169
22170    private void movePackageInternal(final String packageName, final String volumeUuid,
22171            final int moveId, final int callingUid, UserHandle user)
22172                    throws PackageManagerException {
22173        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22174        final PackageManager pm = mContext.getPackageManager();
22175
22176        final boolean currentAsec;
22177        final String currentVolumeUuid;
22178        final File codeFile;
22179        final String installerPackageName;
22180        final String packageAbiOverride;
22181        final int appId;
22182        final String seinfo;
22183        final String label;
22184        final int targetSdkVersion;
22185        final PackageFreezer freezer;
22186        final int[] installedUserIds;
22187
22188        // reader
22189        synchronized (mPackages) {
22190            final PackageParser.Package pkg = mPackages.get(packageName);
22191            final PackageSetting ps = mSettings.mPackages.get(packageName);
22192            if (pkg == null
22193                    || ps == null
22194                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22195                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22196            }
22197            if (pkg.applicationInfo.isSystemApp()) {
22198                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22199                        "Cannot move system application");
22200            }
22201
22202            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22203            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22204                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22205            if (isInternalStorage && !allow3rdPartyOnInternal) {
22206                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22207                        "3rd party apps are not allowed on internal storage");
22208            }
22209
22210            if (pkg.applicationInfo.isExternalAsec()) {
22211                currentAsec = true;
22212                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22213            } else if (pkg.applicationInfo.isForwardLocked()) {
22214                currentAsec = true;
22215                currentVolumeUuid = "forward_locked";
22216            } else {
22217                currentAsec = false;
22218                currentVolumeUuid = ps.volumeUuid;
22219
22220                final File probe = new File(pkg.codePath);
22221                final File probeOat = new File(probe, "oat");
22222                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22223                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22224                            "Move only supported for modern cluster style installs");
22225                }
22226            }
22227
22228            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22229                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22230                        "Package already moved to " + volumeUuid);
22231            }
22232            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22233                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22234                        "Device admin cannot be moved");
22235            }
22236
22237            if (mFrozenPackages.contains(packageName)) {
22238                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22239                        "Failed to move already frozen package");
22240            }
22241
22242            codeFile = new File(pkg.codePath);
22243            installerPackageName = ps.installerPackageName;
22244            packageAbiOverride = ps.cpuAbiOverrideString;
22245            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22246            seinfo = pkg.applicationInfo.seInfo;
22247            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22248            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22249            freezer = freezePackage(packageName, "movePackageInternal");
22250            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22251        }
22252
22253        final Bundle extras = new Bundle();
22254        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22255        extras.putString(Intent.EXTRA_TITLE, label);
22256        mMoveCallbacks.notifyCreated(moveId, extras);
22257
22258        int installFlags;
22259        final boolean moveCompleteApp;
22260        final File measurePath;
22261
22262        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22263            installFlags = INSTALL_INTERNAL;
22264            moveCompleteApp = !currentAsec;
22265            measurePath = Environment.getDataAppDirectory(volumeUuid);
22266        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22267            installFlags = INSTALL_EXTERNAL;
22268            moveCompleteApp = false;
22269            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22270        } else {
22271            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22272            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22273                    || !volume.isMountedWritable()) {
22274                freezer.close();
22275                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22276                        "Move location not mounted private volume");
22277            }
22278
22279            Preconditions.checkState(!currentAsec);
22280
22281            installFlags = INSTALL_INTERNAL;
22282            moveCompleteApp = true;
22283            measurePath = Environment.getDataAppDirectory(volumeUuid);
22284        }
22285
22286        // If we're moving app data around, we need all the users unlocked
22287        if (moveCompleteApp) {
22288            for (int userId : installedUserIds) {
22289                if (StorageManager.isFileEncryptedNativeOrEmulated()
22290                        && !StorageManager.isUserKeyUnlocked(userId)) {
22291                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22292                            "User " + userId + " must be unlocked");
22293                }
22294            }
22295        }
22296
22297        final PackageStats stats = new PackageStats(null, -1);
22298        synchronized (mInstaller) {
22299            for (int userId : installedUserIds) {
22300                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22301                    freezer.close();
22302                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22303                            "Failed to measure package size");
22304                }
22305            }
22306        }
22307
22308        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22309                + stats.dataSize);
22310
22311        final long startFreeBytes = measurePath.getUsableSpace();
22312        final long sizeBytes;
22313        if (moveCompleteApp) {
22314            sizeBytes = stats.codeSize + stats.dataSize;
22315        } else {
22316            sizeBytes = stats.codeSize;
22317        }
22318
22319        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22320            freezer.close();
22321            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22322                    "Not enough free space to move");
22323        }
22324
22325        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22326
22327        final CountDownLatch installedLatch = new CountDownLatch(1);
22328        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22329            @Override
22330            public void onUserActionRequired(Intent intent) throws RemoteException {
22331                throw new IllegalStateException();
22332            }
22333
22334            @Override
22335            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22336                    Bundle extras) throws RemoteException {
22337                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22338                        + PackageManager.installStatusToString(returnCode, msg));
22339
22340                installedLatch.countDown();
22341                freezer.close();
22342
22343                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22344                switch (status) {
22345                    case PackageInstaller.STATUS_SUCCESS:
22346                        mMoveCallbacks.notifyStatusChanged(moveId,
22347                                PackageManager.MOVE_SUCCEEDED);
22348                        break;
22349                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22350                        mMoveCallbacks.notifyStatusChanged(moveId,
22351                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22352                        break;
22353                    default:
22354                        mMoveCallbacks.notifyStatusChanged(moveId,
22355                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22356                        break;
22357                }
22358            }
22359        };
22360
22361        final MoveInfo move;
22362        if (moveCompleteApp) {
22363            // Kick off a thread to report progress estimates
22364            new Thread() {
22365                @Override
22366                public void run() {
22367                    while (true) {
22368                        try {
22369                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22370                                break;
22371                            }
22372                        } catch (InterruptedException ignored) {
22373                        }
22374
22375                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22376                        final int progress = 10 + (int) MathUtils.constrain(
22377                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22378                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22379                    }
22380                }
22381            }.start();
22382
22383            final String dataAppName = codeFile.getName();
22384            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22385                    dataAppName, appId, seinfo, targetSdkVersion);
22386        } else {
22387            move = null;
22388        }
22389
22390        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22391
22392        final Message msg = mHandler.obtainMessage(INIT_COPY);
22393        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22394        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22395                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22396                packageAbiOverride, null /*grantedPermissions*/,
22397                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
22398        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22399        msg.obj = params;
22400
22401        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22402                System.identityHashCode(msg.obj));
22403        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22404                System.identityHashCode(msg.obj));
22405
22406        mHandler.sendMessage(msg);
22407    }
22408
22409    @Override
22410    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22411        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22412
22413        final int realMoveId = mNextMoveId.getAndIncrement();
22414        final Bundle extras = new Bundle();
22415        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22416        mMoveCallbacks.notifyCreated(realMoveId, extras);
22417
22418        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22419            @Override
22420            public void onCreated(int moveId, Bundle extras) {
22421                // Ignored
22422            }
22423
22424            @Override
22425            public void onStatusChanged(int moveId, int status, long estMillis) {
22426                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22427            }
22428        };
22429
22430        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22431        storage.setPrimaryStorageUuid(volumeUuid, callback);
22432        return realMoveId;
22433    }
22434
22435    @Override
22436    public int getMoveStatus(int moveId) {
22437        mContext.enforceCallingOrSelfPermission(
22438                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22439        return mMoveCallbacks.mLastStatus.get(moveId);
22440    }
22441
22442    @Override
22443    public void registerMoveCallback(IPackageMoveObserver callback) {
22444        mContext.enforceCallingOrSelfPermission(
22445                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22446        mMoveCallbacks.register(callback);
22447    }
22448
22449    @Override
22450    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22451        mContext.enforceCallingOrSelfPermission(
22452                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22453        mMoveCallbacks.unregister(callback);
22454    }
22455
22456    @Override
22457    public boolean setInstallLocation(int loc) {
22458        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22459                null);
22460        if (getInstallLocation() == loc) {
22461            return true;
22462        }
22463        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22464                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22465            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22466                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22467            return true;
22468        }
22469        return false;
22470   }
22471
22472    @Override
22473    public int getInstallLocation() {
22474        // allow instant app access
22475        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22476                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22477                PackageHelper.APP_INSTALL_AUTO);
22478    }
22479
22480    /** Called by UserManagerService */
22481    void cleanUpUser(UserManagerService userManager, int userHandle) {
22482        synchronized (mPackages) {
22483            mDirtyUsers.remove(userHandle);
22484            mUserNeedsBadging.delete(userHandle);
22485            mSettings.removeUserLPw(userHandle);
22486            mPendingBroadcasts.remove(userHandle);
22487            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22488            removeUnusedPackagesLPw(userManager, userHandle);
22489        }
22490    }
22491
22492    /**
22493     * We're removing userHandle and would like to remove any downloaded packages
22494     * that are no longer in use by any other user.
22495     * @param userHandle the user being removed
22496     */
22497    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22498        final boolean DEBUG_CLEAN_APKS = false;
22499        int [] users = userManager.getUserIds();
22500        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22501        while (psit.hasNext()) {
22502            PackageSetting ps = psit.next();
22503            if (ps.pkg == null) {
22504                continue;
22505            }
22506            final String packageName = ps.pkg.packageName;
22507            // Skip over if system app
22508            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22509                continue;
22510            }
22511            if (DEBUG_CLEAN_APKS) {
22512                Slog.i(TAG, "Checking package " + packageName);
22513            }
22514            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22515            if (keep) {
22516                if (DEBUG_CLEAN_APKS) {
22517                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22518                }
22519            } else {
22520                for (int i = 0; i < users.length; i++) {
22521                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22522                        keep = true;
22523                        if (DEBUG_CLEAN_APKS) {
22524                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22525                                    + users[i]);
22526                        }
22527                        break;
22528                    }
22529                }
22530            }
22531            if (!keep) {
22532                if (DEBUG_CLEAN_APKS) {
22533                    Slog.i(TAG, "  Removing package " + packageName);
22534                }
22535                mHandler.post(new Runnable() {
22536                    public void run() {
22537                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22538                                userHandle, 0);
22539                    } //end run
22540                });
22541            }
22542        }
22543    }
22544
22545    /** Called by UserManagerService */
22546    void createNewUser(int userId, String[] disallowedPackages) {
22547        synchronized (mInstallLock) {
22548            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22549        }
22550        synchronized (mPackages) {
22551            scheduleWritePackageRestrictionsLocked(userId);
22552            scheduleWritePackageListLocked(userId);
22553            applyFactoryDefaultBrowserLPw(userId);
22554            primeDomainVerificationsLPw(userId);
22555        }
22556    }
22557
22558    void onNewUserCreated(final int userId) {
22559        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22560        synchronized(mPackages) {
22561            // If permission review for legacy apps is required, we represent
22562            // dagerous permissions for such apps as always granted runtime
22563            // permissions to keep per user flag state whether review is needed.
22564            // Hence, if a new user is added we have to propagate dangerous
22565            // permission grants for these legacy apps.
22566            if (mSettings.mPermissions.mPermissionReviewRequired) {
22567// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22568                mPermissionManager.updateAllPermissions(
22569                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22570                        mPermissionCallback);
22571            }
22572        }
22573    }
22574
22575    @Override
22576    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22577        mContext.enforceCallingOrSelfPermission(
22578                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22579                "Only package verification agents can read the verifier device identity");
22580
22581        synchronized (mPackages) {
22582            return mSettings.getVerifierDeviceIdentityLPw();
22583        }
22584    }
22585
22586    @Override
22587    public void setPermissionEnforced(String permission, boolean enforced) {
22588        // TODO: Now that we no longer change GID for storage, this should to away.
22589        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22590                "setPermissionEnforced");
22591        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22592            synchronized (mPackages) {
22593                if (mSettings.mReadExternalStorageEnforced == null
22594                        || mSettings.mReadExternalStorageEnforced != enforced) {
22595                    mSettings.mReadExternalStorageEnforced =
22596                            enforced ? Boolean.TRUE : Boolean.FALSE;
22597                    mSettings.writeLPr();
22598                }
22599            }
22600            // kill any non-foreground processes so we restart them and
22601            // grant/revoke the GID.
22602            final IActivityManager am = ActivityManager.getService();
22603            if (am != null) {
22604                final long token = Binder.clearCallingIdentity();
22605                try {
22606                    am.killProcessesBelowForeground("setPermissionEnforcement");
22607                } catch (RemoteException e) {
22608                } finally {
22609                    Binder.restoreCallingIdentity(token);
22610                }
22611            }
22612        } else {
22613            throw new IllegalArgumentException("No selective enforcement for " + permission);
22614        }
22615    }
22616
22617    @Override
22618    @Deprecated
22619    public boolean isPermissionEnforced(String permission) {
22620        // allow instant applications
22621        return true;
22622    }
22623
22624    @Override
22625    public boolean isStorageLow() {
22626        // allow instant applications
22627        final long token = Binder.clearCallingIdentity();
22628        try {
22629            final DeviceStorageMonitorInternal
22630                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22631            if (dsm != null) {
22632                return dsm.isMemoryLow();
22633            } else {
22634                return false;
22635            }
22636        } finally {
22637            Binder.restoreCallingIdentity(token);
22638        }
22639    }
22640
22641    @Override
22642    public IPackageInstaller getPackageInstaller() {
22643        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22644            return null;
22645        }
22646        return mInstallerService;
22647    }
22648
22649    @Override
22650    public IArtManager getArtManager() {
22651        return mArtManagerService;
22652    }
22653
22654    private boolean userNeedsBadging(int userId) {
22655        int index = mUserNeedsBadging.indexOfKey(userId);
22656        if (index < 0) {
22657            final UserInfo userInfo;
22658            final long token = Binder.clearCallingIdentity();
22659            try {
22660                userInfo = sUserManager.getUserInfo(userId);
22661            } finally {
22662                Binder.restoreCallingIdentity(token);
22663            }
22664            final boolean b;
22665            if (userInfo != null && userInfo.isManagedProfile()) {
22666                b = true;
22667            } else {
22668                b = false;
22669            }
22670            mUserNeedsBadging.put(userId, b);
22671            return b;
22672        }
22673        return mUserNeedsBadging.valueAt(index);
22674    }
22675
22676    @Override
22677    public KeySet getKeySetByAlias(String packageName, String alias) {
22678        if (packageName == null || alias == null) {
22679            return null;
22680        }
22681        synchronized(mPackages) {
22682            final PackageParser.Package pkg = mPackages.get(packageName);
22683            if (pkg == null) {
22684                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22685                throw new IllegalArgumentException("Unknown package: " + packageName);
22686            }
22687            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22688            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22689                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22690                throw new IllegalArgumentException("Unknown package: " + packageName);
22691            }
22692            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22693            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22694        }
22695    }
22696
22697    @Override
22698    public KeySet getSigningKeySet(String packageName) {
22699        if (packageName == null) {
22700            return null;
22701        }
22702        synchronized(mPackages) {
22703            final int callingUid = Binder.getCallingUid();
22704            final int callingUserId = UserHandle.getUserId(callingUid);
22705            final PackageParser.Package pkg = mPackages.get(packageName);
22706            if (pkg == null) {
22707                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22708                throw new IllegalArgumentException("Unknown package: " + packageName);
22709            }
22710            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22711            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
22712                // filter and pretend the package doesn't exist
22713                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22714                        + ", uid:" + callingUid);
22715                throw new IllegalArgumentException("Unknown package: " + packageName);
22716            }
22717            if (pkg.applicationInfo.uid != callingUid
22718                    && Process.SYSTEM_UID != callingUid) {
22719                throw new SecurityException("May not access signing KeySet of other apps.");
22720            }
22721            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22722            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22723        }
22724    }
22725
22726    @Override
22727    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22728        final int callingUid = Binder.getCallingUid();
22729        if (getInstantAppPackageName(callingUid) != null) {
22730            return false;
22731        }
22732        if (packageName == null || ks == null) {
22733            return false;
22734        }
22735        synchronized(mPackages) {
22736            final PackageParser.Package pkg = mPackages.get(packageName);
22737            if (pkg == null
22738                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22739                            UserHandle.getUserId(callingUid))) {
22740                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22741                throw new IllegalArgumentException("Unknown package: " + packageName);
22742            }
22743            IBinder ksh = ks.getToken();
22744            if (ksh instanceof KeySetHandle) {
22745                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22746                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22747            }
22748            return false;
22749        }
22750    }
22751
22752    @Override
22753    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22754        final int callingUid = Binder.getCallingUid();
22755        if (getInstantAppPackageName(callingUid) != null) {
22756            return false;
22757        }
22758        if (packageName == null || ks == null) {
22759            return false;
22760        }
22761        synchronized(mPackages) {
22762            final PackageParser.Package pkg = mPackages.get(packageName);
22763            if (pkg == null
22764                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22765                            UserHandle.getUserId(callingUid))) {
22766                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22767                throw new IllegalArgumentException("Unknown package: " + packageName);
22768            }
22769            IBinder ksh = ks.getToken();
22770            if (ksh instanceof KeySetHandle) {
22771                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22772                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22773            }
22774            return false;
22775        }
22776    }
22777
22778    private void deletePackageIfUnusedLPr(final String packageName) {
22779        PackageSetting ps = mSettings.mPackages.get(packageName);
22780        if (ps == null) {
22781            return;
22782        }
22783        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22784            // TODO Implement atomic delete if package is unused
22785            // It is currently possible that the package will be deleted even if it is installed
22786            // after this method returns.
22787            mHandler.post(new Runnable() {
22788                public void run() {
22789                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22790                            0, PackageManager.DELETE_ALL_USERS);
22791                }
22792            });
22793        }
22794    }
22795
22796    /**
22797     * Check and throw if the given before/after packages would be considered a
22798     * downgrade.
22799     */
22800    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22801            throws PackageManagerException {
22802        if (after.getLongVersionCode() < before.getLongVersionCode()) {
22803            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22804                    "Update version code " + after.versionCode + " is older than current "
22805                    + before.getLongVersionCode());
22806        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22807            if (after.baseRevisionCode < before.baseRevisionCode) {
22808                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22809                        "Update base revision code " + after.baseRevisionCode
22810                        + " is older than current " + before.baseRevisionCode);
22811            }
22812
22813            if (!ArrayUtils.isEmpty(after.splitNames)) {
22814                for (int i = 0; i < after.splitNames.length; i++) {
22815                    final String splitName = after.splitNames[i];
22816                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22817                    if (j != -1) {
22818                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22819                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22820                                    "Update split " + splitName + " revision code "
22821                                    + after.splitRevisionCodes[i] + " is older than current "
22822                                    + before.splitRevisionCodes[j]);
22823                        }
22824                    }
22825                }
22826            }
22827        }
22828    }
22829
22830    private static class MoveCallbacks extends Handler {
22831        private static final int MSG_CREATED = 1;
22832        private static final int MSG_STATUS_CHANGED = 2;
22833
22834        private final RemoteCallbackList<IPackageMoveObserver>
22835                mCallbacks = new RemoteCallbackList<>();
22836
22837        private final SparseIntArray mLastStatus = new SparseIntArray();
22838
22839        public MoveCallbacks(Looper looper) {
22840            super(looper);
22841        }
22842
22843        public void register(IPackageMoveObserver callback) {
22844            mCallbacks.register(callback);
22845        }
22846
22847        public void unregister(IPackageMoveObserver callback) {
22848            mCallbacks.unregister(callback);
22849        }
22850
22851        @Override
22852        public void handleMessage(Message msg) {
22853            final SomeArgs args = (SomeArgs) msg.obj;
22854            final int n = mCallbacks.beginBroadcast();
22855            for (int i = 0; i < n; i++) {
22856                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22857                try {
22858                    invokeCallback(callback, msg.what, args);
22859                } catch (RemoteException ignored) {
22860                }
22861            }
22862            mCallbacks.finishBroadcast();
22863            args.recycle();
22864        }
22865
22866        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22867                throws RemoteException {
22868            switch (what) {
22869                case MSG_CREATED: {
22870                    callback.onCreated(args.argi1, (Bundle) args.arg2);
22871                    break;
22872                }
22873                case MSG_STATUS_CHANGED: {
22874                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22875                    break;
22876                }
22877            }
22878        }
22879
22880        private void notifyCreated(int moveId, Bundle extras) {
22881            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22882
22883            final SomeArgs args = SomeArgs.obtain();
22884            args.argi1 = moveId;
22885            args.arg2 = extras;
22886            obtainMessage(MSG_CREATED, args).sendToTarget();
22887        }
22888
22889        private void notifyStatusChanged(int moveId, int status) {
22890            notifyStatusChanged(moveId, status, -1);
22891        }
22892
22893        private void notifyStatusChanged(int moveId, int status, long estMillis) {
22894            Slog.v(TAG, "Move " + moveId + " status " + status);
22895
22896            final SomeArgs args = SomeArgs.obtain();
22897            args.argi1 = moveId;
22898            args.argi2 = status;
22899            args.arg3 = estMillis;
22900            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22901
22902            synchronized (mLastStatus) {
22903                mLastStatus.put(moveId, status);
22904            }
22905        }
22906    }
22907
22908    private final static class OnPermissionChangeListeners extends Handler {
22909        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22910
22911        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22912                new RemoteCallbackList<>();
22913
22914        public OnPermissionChangeListeners(Looper looper) {
22915            super(looper);
22916        }
22917
22918        @Override
22919        public void handleMessage(Message msg) {
22920            switch (msg.what) {
22921                case MSG_ON_PERMISSIONS_CHANGED: {
22922                    final int uid = msg.arg1;
22923                    handleOnPermissionsChanged(uid);
22924                } break;
22925            }
22926        }
22927
22928        public void addListenerLocked(IOnPermissionsChangeListener listener) {
22929            mPermissionListeners.register(listener);
22930
22931        }
22932
22933        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22934            mPermissionListeners.unregister(listener);
22935        }
22936
22937        public void onPermissionsChanged(int uid) {
22938            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22939                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22940            }
22941        }
22942
22943        private void handleOnPermissionsChanged(int uid) {
22944            final int count = mPermissionListeners.beginBroadcast();
22945            try {
22946                for (int i = 0; i < count; i++) {
22947                    IOnPermissionsChangeListener callback = mPermissionListeners
22948                            .getBroadcastItem(i);
22949                    try {
22950                        callback.onPermissionsChanged(uid);
22951                    } catch (RemoteException e) {
22952                        Log.e(TAG, "Permission listener is dead", e);
22953                    }
22954                }
22955            } finally {
22956                mPermissionListeners.finishBroadcast();
22957            }
22958        }
22959    }
22960
22961    private class PackageManagerNative extends IPackageManagerNative.Stub {
22962        @Override
22963        public String[] getNamesForUids(int[] uids) throws RemoteException {
22964            final String[] results = PackageManagerService.this.getNamesForUids(uids);
22965            // massage results so they can be parsed by the native binder
22966            for (int i = results.length - 1; i >= 0; --i) {
22967                if (results[i] == null) {
22968                    results[i] = "";
22969                }
22970            }
22971            return results;
22972        }
22973
22974        // NB: this differentiates between preloads and sideloads
22975        @Override
22976        public String getInstallerForPackage(String packageName) throws RemoteException {
22977            final String installerName = getInstallerPackageName(packageName);
22978            if (!TextUtils.isEmpty(installerName)) {
22979                return installerName;
22980            }
22981            // differentiate between preload and sideload
22982            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22983            ApplicationInfo appInfo = getApplicationInfo(packageName,
22984                                    /*flags*/ 0,
22985                                    /*userId*/ callingUser);
22986            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22987                return "preload";
22988            }
22989            return "";
22990        }
22991
22992        @Override
22993        public long getVersionCodeForPackage(String packageName) throws RemoteException {
22994            try {
22995                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22996                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22997                if (pInfo != null) {
22998                    return pInfo.getLongVersionCode();
22999                }
23000            } catch (Exception e) {
23001            }
23002            return 0;
23003        }
23004    }
23005
23006    private class PackageManagerInternalImpl extends PackageManagerInternal {
23007        @Override
23008        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23009                int flagValues, int userId) {
23010            PackageManagerService.this.updatePermissionFlags(
23011                    permName, packageName, flagMask, flagValues, userId);
23012        }
23013
23014        @Override
23015        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23016            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23017        }
23018
23019        @Override
23020        public boolean isInstantApp(String packageName, int userId) {
23021            return PackageManagerService.this.isInstantApp(packageName, userId);
23022        }
23023
23024        @Override
23025        public String getInstantAppPackageName(int uid) {
23026            return PackageManagerService.this.getInstantAppPackageName(uid);
23027        }
23028
23029        @Override
23030        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23031            synchronized (mPackages) {
23032                return PackageManagerService.this.filterAppAccessLPr(
23033                        (PackageSetting) pkg.mExtras, callingUid, userId);
23034            }
23035        }
23036
23037        @Override
23038        public PackageParser.Package getPackage(String packageName) {
23039            synchronized (mPackages) {
23040                packageName = resolveInternalPackageNameLPr(
23041                        packageName, PackageManager.VERSION_CODE_HIGHEST);
23042                return mPackages.get(packageName);
23043            }
23044        }
23045
23046        @Override
23047        public PackageList getPackageList(PackageListObserver observer) {
23048            synchronized (mPackages) {
23049                final int N = mPackages.size();
23050                final ArrayList<String> list = new ArrayList<>(N);
23051                for (int i = 0; i < N; i++) {
23052                    list.add(mPackages.keyAt(i));
23053                }
23054                final PackageList packageList = new PackageList(list, observer);
23055                if (observer != null) {
23056                    mPackageListObservers.add(packageList);
23057                }
23058                return packageList;
23059            }
23060        }
23061
23062        @Override
23063        public void removePackageListObserver(PackageListObserver observer) {
23064            synchronized (mPackages) {
23065                mPackageListObservers.remove(observer);
23066            }
23067        }
23068
23069        @Override
23070        public PackageParser.Package getDisabledPackage(String packageName) {
23071            synchronized (mPackages) {
23072                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
23073                return (ps != null) ? ps.pkg : null;
23074            }
23075        }
23076
23077        @Override
23078        public String getKnownPackageName(int knownPackage, int userId) {
23079            switch(knownPackage) {
23080                case PackageManagerInternal.PACKAGE_BROWSER:
23081                    return getDefaultBrowserPackageName(userId);
23082                case PackageManagerInternal.PACKAGE_INSTALLER:
23083                    return mRequiredInstallerPackage;
23084                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23085                    return mSetupWizardPackage;
23086                case PackageManagerInternal.PACKAGE_SYSTEM:
23087                    return "android";
23088                case PackageManagerInternal.PACKAGE_VERIFIER:
23089                    return mRequiredVerifierPackage;
23090            }
23091            return null;
23092        }
23093
23094        @Override
23095        public boolean isResolveActivityComponent(ComponentInfo component) {
23096            return mResolveActivity.packageName.equals(component.packageName)
23097                    && mResolveActivity.name.equals(component.name);
23098        }
23099
23100        @Override
23101        public void setLocationPackagesProvider(PackagesProvider provider) {
23102            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
23103        }
23104
23105        @Override
23106        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23107            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
23108        }
23109
23110        @Override
23111        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23112            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
23113        }
23114
23115        @Override
23116        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23117            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
23118        }
23119
23120        @Override
23121        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23122            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
23123        }
23124
23125        @Override
23126        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
23127            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
23128        }
23129
23130        @Override
23131        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23132            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
23133        }
23134
23135        @Override
23136        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23137            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
23138        }
23139
23140        @Override
23141        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23142            synchronized (mPackages) {
23143                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23144            }
23145            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
23146        }
23147
23148        @Override
23149        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23150            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
23151                    packageName, userId);
23152        }
23153
23154        @Override
23155        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
23156            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
23157                    packageName, userId);
23158        }
23159
23160        @Override
23161        public void setKeepUninstalledPackages(final List<String> packageList) {
23162            Preconditions.checkNotNull(packageList);
23163            List<String> removedFromList = null;
23164            synchronized (mPackages) {
23165                if (mKeepUninstalledPackages != null) {
23166                    final int packagesCount = mKeepUninstalledPackages.size();
23167                    for (int i = 0; i < packagesCount; i++) {
23168                        String oldPackage = mKeepUninstalledPackages.get(i);
23169                        if (packageList != null && packageList.contains(oldPackage)) {
23170                            continue;
23171                        }
23172                        if (removedFromList == null) {
23173                            removedFromList = new ArrayList<>();
23174                        }
23175                        removedFromList.add(oldPackage);
23176                    }
23177                }
23178                mKeepUninstalledPackages = new ArrayList<>(packageList);
23179                if (removedFromList != null) {
23180                    final int removedCount = removedFromList.size();
23181                    for (int i = 0; i < removedCount; i++) {
23182                        deletePackageIfUnusedLPr(removedFromList.get(i));
23183                    }
23184                }
23185            }
23186        }
23187
23188        @Override
23189        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23190            synchronized (mPackages) {
23191                return mPermissionManager.isPermissionsReviewRequired(
23192                        mPackages.get(packageName), userId);
23193            }
23194        }
23195
23196        @Override
23197        public PackageInfo getPackageInfo(
23198                String packageName, int flags, int filterCallingUid, int userId) {
23199            return PackageManagerService.this
23200                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23201                            flags, filterCallingUid, userId);
23202        }
23203
23204        @Override
23205        public int getPackageUid(String packageName, int flags, int userId) {
23206            return PackageManagerService.this
23207                    .getPackageUid(packageName, flags, userId);
23208        }
23209
23210        @Override
23211        public ApplicationInfo getApplicationInfo(
23212                String packageName, int flags, int filterCallingUid, int userId) {
23213            return PackageManagerService.this
23214                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23215        }
23216
23217        @Override
23218        public ActivityInfo getActivityInfo(
23219                ComponentName component, int flags, int filterCallingUid, int userId) {
23220            return PackageManagerService.this
23221                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23222        }
23223
23224        @Override
23225        public List<ResolveInfo> queryIntentActivities(
23226                Intent intent, int flags, int filterCallingUid, int userId) {
23227            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23228            return PackageManagerService.this
23229                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23230                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23231        }
23232
23233        @Override
23234        public List<ResolveInfo> queryIntentServices(
23235                Intent intent, int flags, int callingUid, int userId) {
23236            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23237            return PackageManagerService.this
23238                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23239                            false);
23240        }
23241
23242        @Override
23243        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23244                int userId) {
23245            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23246        }
23247
23248        @Override
23249        public void setDeviceAndProfileOwnerPackages(
23250                int deviceOwnerUserId, String deviceOwnerPackage,
23251                SparseArray<String> profileOwnerPackages) {
23252            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23253                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23254        }
23255
23256        @Override
23257        public boolean isPackageDataProtected(int userId, String packageName) {
23258            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23259        }
23260
23261        @Override
23262        public boolean isPackageEphemeral(int userId, String packageName) {
23263            synchronized (mPackages) {
23264                final PackageSetting ps = mSettings.mPackages.get(packageName);
23265                return ps != null ? ps.getInstantApp(userId) : false;
23266            }
23267        }
23268
23269        @Override
23270        public boolean wasPackageEverLaunched(String packageName, int userId) {
23271            synchronized (mPackages) {
23272                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23273            }
23274        }
23275
23276        @Override
23277        public void grantRuntimePermission(String packageName, String permName, int userId,
23278                boolean overridePolicy) {
23279            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23280                    permName, packageName, overridePolicy, getCallingUid(), userId,
23281                    mPermissionCallback);
23282        }
23283
23284        @Override
23285        public void revokeRuntimePermission(String packageName, String permName, int userId,
23286                boolean overridePolicy) {
23287            mPermissionManager.revokeRuntimePermission(
23288                    permName, packageName, overridePolicy, getCallingUid(), userId,
23289                    mPermissionCallback);
23290        }
23291
23292        @Override
23293        public String getNameForUid(int uid) {
23294            return PackageManagerService.this.getNameForUid(uid);
23295        }
23296
23297        @Override
23298        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23299                Intent origIntent, String resolvedType, String callingPackage,
23300                Bundle verificationBundle, int userId) {
23301            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23302                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23303                    userId);
23304        }
23305
23306        @Override
23307        public void grantEphemeralAccess(int userId, Intent intent,
23308                int targetAppId, int ephemeralAppId) {
23309            synchronized (mPackages) {
23310                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23311                        targetAppId, ephemeralAppId);
23312            }
23313        }
23314
23315        @Override
23316        public boolean isInstantAppInstallerComponent(ComponentName component) {
23317            synchronized (mPackages) {
23318                return mInstantAppInstallerActivity != null
23319                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23320            }
23321        }
23322
23323        @Override
23324        public void pruneInstantApps() {
23325            mInstantAppRegistry.pruneInstantApps();
23326        }
23327
23328        @Override
23329        public String getSetupWizardPackageName() {
23330            return mSetupWizardPackage;
23331        }
23332
23333        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23334            if (policy != null) {
23335                mExternalSourcesPolicy = policy;
23336            }
23337        }
23338
23339        @Override
23340        public boolean isPackagePersistent(String packageName) {
23341            synchronized (mPackages) {
23342                PackageParser.Package pkg = mPackages.get(packageName);
23343                return pkg != null
23344                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23345                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23346                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23347                        : false;
23348            }
23349        }
23350
23351        @Override
23352        public boolean isLegacySystemApp(Package pkg) {
23353            synchronized (mPackages) {
23354                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23355                return mPromoteSystemApps
23356                        && ps.isSystem()
23357                        && mExistingSystemPackages.contains(ps.name);
23358            }
23359        }
23360
23361        @Override
23362        public List<PackageInfo> getOverlayPackages(int userId) {
23363            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23364            synchronized (mPackages) {
23365                for (PackageParser.Package p : mPackages.values()) {
23366                    if (p.mOverlayTarget != null) {
23367                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23368                        if (pkg != null) {
23369                            overlayPackages.add(pkg);
23370                        }
23371                    }
23372                }
23373            }
23374            return overlayPackages;
23375        }
23376
23377        @Override
23378        public List<String> getTargetPackageNames(int userId) {
23379            List<String> targetPackages = new ArrayList<>();
23380            synchronized (mPackages) {
23381                for (PackageParser.Package p : mPackages.values()) {
23382                    if (p.mOverlayTarget == null) {
23383                        targetPackages.add(p.packageName);
23384                    }
23385                }
23386            }
23387            return targetPackages;
23388        }
23389
23390        @Override
23391        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23392                @Nullable List<String> overlayPackageNames) {
23393            synchronized (mPackages) {
23394                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23395                    Slog.e(TAG, "failed to find package " + targetPackageName);
23396                    return false;
23397                }
23398                ArrayList<String> overlayPaths = null;
23399                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23400                    final int N = overlayPackageNames.size();
23401                    overlayPaths = new ArrayList<>(N);
23402                    for (int i = 0; i < N; i++) {
23403                        final String packageName = overlayPackageNames.get(i);
23404                        final PackageParser.Package pkg = mPackages.get(packageName);
23405                        if (pkg == null) {
23406                            Slog.e(TAG, "failed to find package " + packageName);
23407                            return false;
23408                        }
23409                        overlayPaths.add(pkg.baseCodePath);
23410                    }
23411                }
23412
23413                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23414                ps.setOverlayPaths(overlayPaths, userId);
23415                return true;
23416            }
23417        }
23418
23419        @Override
23420        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23421                int flags, int userId, boolean resolveForStart) {
23422            return resolveIntentInternal(
23423                    intent, resolvedType, flags, userId, resolveForStart);
23424        }
23425
23426        @Override
23427        public ResolveInfo resolveService(Intent intent, String resolvedType,
23428                int flags, int userId, int callingUid) {
23429            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23430        }
23431
23432        @Override
23433        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23434            return PackageManagerService.this.resolveContentProviderInternal(
23435                    name, flags, userId);
23436        }
23437
23438        @Override
23439        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23440            synchronized (mPackages) {
23441                mIsolatedOwners.put(isolatedUid, ownerUid);
23442            }
23443        }
23444
23445        @Override
23446        public void removeIsolatedUid(int isolatedUid) {
23447            synchronized (mPackages) {
23448                mIsolatedOwners.delete(isolatedUid);
23449            }
23450        }
23451
23452        @Override
23453        public int getUidTargetSdkVersion(int uid) {
23454            synchronized (mPackages) {
23455                return getUidTargetSdkVersionLockedLPr(uid);
23456            }
23457        }
23458
23459        @Override
23460        public int getPackageTargetSdkVersion(String packageName) {
23461            synchronized (mPackages) {
23462                return getPackageTargetSdkVersionLockedLPr(packageName);
23463            }
23464        }
23465
23466        @Override
23467        public boolean canAccessInstantApps(int callingUid, int userId) {
23468            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23469        }
23470
23471        @Override
23472        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23473            synchronized (mPackages) {
23474                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23475            }
23476        }
23477
23478        @Override
23479        public void notifyPackageUse(String packageName, int reason) {
23480            synchronized (mPackages) {
23481                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23482            }
23483        }
23484    }
23485
23486    @Override
23487    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23488        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23489        synchronized (mPackages) {
23490            final long identity = Binder.clearCallingIdentity();
23491            try {
23492                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23493                        packageNames, userId);
23494            } finally {
23495                Binder.restoreCallingIdentity(identity);
23496            }
23497        }
23498    }
23499
23500    @Override
23501    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23502        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23503        synchronized (mPackages) {
23504            final long identity = Binder.clearCallingIdentity();
23505            try {
23506                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23507                        packageNames, userId);
23508            } finally {
23509                Binder.restoreCallingIdentity(identity);
23510            }
23511        }
23512    }
23513
23514    private static void enforceSystemOrPhoneCaller(String tag) {
23515        int callingUid = Binder.getCallingUid();
23516        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23517            throw new SecurityException(
23518                    "Cannot call " + tag + " from UID " + callingUid);
23519        }
23520    }
23521
23522    boolean isHistoricalPackageUsageAvailable() {
23523        return mPackageUsage.isHistoricalPackageUsageAvailable();
23524    }
23525
23526    /**
23527     * Return a <b>copy</b> of the collection of packages known to the package manager.
23528     * @return A copy of the values of mPackages.
23529     */
23530    Collection<PackageParser.Package> getPackages() {
23531        synchronized (mPackages) {
23532            return new ArrayList<>(mPackages.values());
23533        }
23534    }
23535
23536    /**
23537     * Logs process start information (including base APK hash) to the security log.
23538     * @hide
23539     */
23540    @Override
23541    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23542            String apkFile, int pid) {
23543        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23544            return;
23545        }
23546        if (!SecurityLog.isLoggingEnabled()) {
23547            return;
23548        }
23549        Bundle data = new Bundle();
23550        data.putLong("startTimestamp", System.currentTimeMillis());
23551        data.putString("processName", processName);
23552        data.putInt("uid", uid);
23553        data.putString("seinfo", seinfo);
23554        data.putString("apkFile", apkFile);
23555        data.putInt("pid", pid);
23556        Message msg = mProcessLoggingHandler.obtainMessage(
23557                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23558        msg.setData(data);
23559        mProcessLoggingHandler.sendMessage(msg);
23560    }
23561
23562    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23563        return mCompilerStats.getPackageStats(pkgName);
23564    }
23565
23566    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23567        return getOrCreateCompilerPackageStats(pkg.packageName);
23568    }
23569
23570    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23571        return mCompilerStats.getOrCreatePackageStats(pkgName);
23572    }
23573
23574    public void deleteCompilerPackageStats(String pkgName) {
23575        mCompilerStats.deletePackageStats(pkgName);
23576    }
23577
23578    @Override
23579    public int getInstallReason(String packageName, int userId) {
23580        final int callingUid = Binder.getCallingUid();
23581        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23582                true /* requireFullPermission */, false /* checkShell */,
23583                "get install reason");
23584        synchronized (mPackages) {
23585            final PackageSetting ps = mSettings.mPackages.get(packageName);
23586            if (filterAppAccessLPr(ps, callingUid, userId)) {
23587                return PackageManager.INSTALL_REASON_UNKNOWN;
23588            }
23589            if (ps != null) {
23590                return ps.getInstallReason(userId);
23591            }
23592        }
23593        return PackageManager.INSTALL_REASON_UNKNOWN;
23594    }
23595
23596    @Override
23597    public boolean canRequestPackageInstalls(String packageName, int userId) {
23598        return canRequestPackageInstallsInternal(packageName, 0, userId,
23599                true /* throwIfPermNotDeclared*/);
23600    }
23601
23602    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23603            boolean throwIfPermNotDeclared) {
23604        int callingUid = Binder.getCallingUid();
23605        int uid = getPackageUid(packageName, 0, userId);
23606        if (callingUid != uid && callingUid != Process.ROOT_UID
23607                && callingUid != Process.SYSTEM_UID) {
23608            throw new SecurityException(
23609                    "Caller uid " + callingUid + " does not own package " + packageName);
23610        }
23611        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23612        if (info == null) {
23613            return false;
23614        }
23615        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23616            return false;
23617        }
23618        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23619        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23620        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23621            if (throwIfPermNotDeclared) {
23622                throw new SecurityException("Need to declare " + appOpPermission
23623                        + " to call this api");
23624            } else {
23625                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23626                return false;
23627            }
23628        }
23629        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23630            return false;
23631        }
23632        if (mExternalSourcesPolicy != null) {
23633            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23634            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23635                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23636            }
23637        }
23638        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23639    }
23640
23641    @Override
23642    public ComponentName getInstantAppResolverSettingsComponent() {
23643        return mInstantAppResolverSettingsComponent;
23644    }
23645
23646    @Override
23647    public ComponentName getInstantAppInstallerComponent() {
23648        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23649            return null;
23650        }
23651        return mInstantAppInstallerActivity == null
23652                ? null : mInstantAppInstallerActivity.getComponentName();
23653    }
23654
23655    @Override
23656    public String getInstantAppAndroidId(String packageName, int userId) {
23657        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
23658                "getInstantAppAndroidId");
23659        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
23660                true /* requireFullPermission */, false /* checkShell */,
23661                "getInstantAppAndroidId");
23662        // Make sure the target is an Instant App.
23663        if (!isInstantApp(packageName, userId)) {
23664            return null;
23665        }
23666        synchronized (mPackages) {
23667            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
23668        }
23669    }
23670
23671    boolean canHaveOatDir(String packageName) {
23672        synchronized (mPackages) {
23673            PackageParser.Package p = mPackages.get(packageName);
23674            if (p == null) {
23675                return false;
23676            }
23677            return p.canHaveOatDir();
23678        }
23679    }
23680
23681    private String getOatDir(PackageParser.Package pkg) {
23682        if (!pkg.canHaveOatDir()) {
23683            return null;
23684        }
23685        File codePath = new File(pkg.codePath);
23686        if (codePath.isDirectory()) {
23687            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
23688        }
23689        return null;
23690    }
23691
23692    void deleteOatArtifactsOfPackage(String packageName) {
23693        final String[] instructionSets;
23694        final List<String> codePaths;
23695        final String oatDir;
23696        final PackageParser.Package pkg;
23697        synchronized (mPackages) {
23698            pkg = mPackages.get(packageName);
23699        }
23700        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
23701        codePaths = pkg.getAllCodePaths();
23702        oatDir = getOatDir(pkg);
23703
23704        for (String codePath : codePaths) {
23705            for (String isa : instructionSets) {
23706                try {
23707                    mInstaller.deleteOdex(codePath, isa, oatDir);
23708                } catch (InstallerException e) {
23709                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
23710                }
23711            }
23712        }
23713    }
23714
23715    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
23716        Set<String> unusedPackages = new HashSet<>();
23717        long currentTimeInMillis = System.currentTimeMillis();
23718        synchronized (mPackages) {
23719            for (PackageParser.Package pkg : mPackages.values()) {
23720                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
23721                if (ps == null) {
23722                    continue;
23723                }
23724                PackageDexUsage.PackageUseInfo packageUseInfo =
23725                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
23726                if (PackageManagerServiceUtils
23727                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
23728                                downgradeTimeThresholdMillis, packageUseInfo,
23729                                pkg.getLatestPackageUseTimeInMills(),
23730                                pkg.getLatestForegroundPackageUseTimeInMills())) {
23731                    unusedPackages.add(pkg.packageName);
23732                }
23733            }
23734        }
23735        return unusedPackages;
23736    }
23737
23738    @Override
23739    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
23740            int userId) {
23741        final int callingUid = Binder.getCallingUid();
23742        final int callingAppId = UserHandle.getAppId(callingUid);
23743
23744        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23745                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
23746
23747        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
23748                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
23749            throw new SecurityException("Caller must have the "
23750                    + SET_HARMFUL_APP_WARNINGS + " permission.");
23751        }
23752
23753        synchronized(mPackages) {
23754            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
23755            scheduleWritePackageRestrictionsLocked(userId);
23756        }
23757    }
23758
23759    @Nullable
23760    @Override
23761    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
23762        final int callingUid = Binder.getCallingUid();
23763        final int callingAppId = UserHandle.getAppId(callingUid);
23764
23765        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23766                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
23767
23768        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
23769                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
23770            throw new SecurityException("Caller must have the "
23771                    + SET_HARMFUL_APP_WARNINGS + " permission.");
23772        }
23773
23774        synchronized(mPackages) {
23775            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
23776        }
23777    }
23778}
23779
23780interface PackageSender {
23781    /**
23782     * @param userIds User IDs where the action occurred on a full application
23783     * @param instantUserIds User IDs where the action occurred on an instant application
23784     */
23785    void sendPackageBroadcast(final String action, final String pkg,
23786        final Bundle extras, final int flags, final String targetPkg,
23787        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
23788    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
23789        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
23790    void notifyPackageAdded(String packageName);
23791    void notifyPackageRemoved(String packageName);
23792}
23793