PackageManagerService.java revision cdc2e6734e4a40cfb9b5735c428136bc18d401d3
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_NEWER_SDK;
51import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
52import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
56import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
57import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
58import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.isApkFile;
86import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
87import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
88import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
89import static android.system.OsConstants.O_CREAT;
90import static android.system.OsConstants.O_RDWR;
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
93import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
94import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
95import static com.android.internal.util.ArrayUtils.appendInt;
96import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
99import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
100import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
104import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
105import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
106import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
107import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
108import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
109import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
110import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
111import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
112import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
114import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
115
116import android.Manifest;
117import android.annotation.IntDef;
118import android.annotation.NonNull;
119import android.annotation.Nullable;
120import android.app.ActivityManager;
121import android.app.AppOpsManager;
122import android.app.IActivityManager;
123import android.app.ResourcesManager;
124import android.app.admin.IDevicePolicyManager;
125import android.app.admin.SecurityLog;
126import android.app.backup.IBackupManager;
127import android.content.BroadcastReceiver;
128import android.content.ComponentName;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.IIntentReceiver;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.IntentSender.SendIntentException;
136import android.content.ServiceConnection;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.AppsQueryHelper;
140import android.content.pm.AuxiliaryResolveInfo;
141import android.content.pm.ChangedPackages;
142import android.content.pm.ComponentInfo;
143import android.content.pm.FallbackCategoryProvider;
144import android.content.pm.FeatureInfo;
145import android.content.pm.IDexModuleRegisterCallback;
146import android.content.pm.IOnPermissionsChangeListener;
147import android.content.pm.IPackageDataObserver;
148import android.content.pm.IPackageDeleteObserver;
149import android.content.pm.IPackageDeleteObserver2;
150import android.content.pm.IPackageInstallObserver2;
151import android.content.pm.IPackageInstaller;
152import android.content.pm.IPackageManager;
153import android.content.pm.IPackageManagerNative;
154import android.content.pm.IPackageMoveObserver;
155import android.content.pm.IPackageStatsObserver;
156import android.content.pm.InstantAppInfo;
157import android.content.pm.InstantAppRequest;
158import android.content.pm.InstantAppResolveInfo;
159import android.content.pm.InstrumentationInfo;
160import android.content.pm.IntentFilterVerificationInfo;
161import android.content.pm.KeySet;
162import android.content.pm.PackageCleanItem;
163import android.content.pm.PackageInfo;
164import android.content.pm.PackageInfoLite;
165import android.content.pm.PackageInstaller;
166import android.content.pm.PackageList;
167import android.content.pm.PackageManager;
168import android.content.pm.PackageManagerInternal;
169import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
170import android.content.pm.PackageManager.PackageInfoFlags;
171import android.content.pm.PackageManagerInternal.PackageListObserver;
172import android.content.pm.PackageParser;
173import android.content.pm.PackageParser.ActivityIntentInfo;
174import android.content.pm.PackageParser.Package;
175import android.content.pm.PackageParser.PackageLite;
176import android.content.pm.PackageParser.PackageParserException;
177import android.content.pm.PackageParser.ParseFlags;
178import android.content.pm.PackageParser.ServiceIntentInfo;
179import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
180import android.content.pm.PackageStats;
181import android.content.pm.PackageUserState;
182import android.content.pm.ParceledListSlice;
183import android.content.pm.PermissionGroupInfo;
184import android.content.pm.PermissionInfo;
185import android.content.pm.ProviderInfo;
186import android.content.pm.ResolveInfo;
187import android.content.pm.ServiceInfo;
188import android.content.pm.SharedLibraryInfo;
189import android.content.pm.Signature;
190import android.content.pm.UserInfo;
191import android.content.pm.VerifierDeviceIdentity;
192import android.content.pm.VerifierInfo;
193import android.content.pm.VersionedPackage;
194import android.content.pm.dex.IArtManager;
195import android.content.res.Resources;
196import android.database.ContentObserver;
197import android.graphics.Bitmap;
198import android.hardware.display.DisplayManager;
199import android.net.Uri;
200import android.os.Binder;
201import android.os.Build;
202import android.os.Bundle;
203import android.os.Debug;
204import android.os.Environment;
205import android.os.Environment.UserEnvironment;
206import android.os.FileUtils;
207import android.os.Handler;
208import android.os.IBinder;
209import android.os.Looper;
210import android.os.Message;
211import android.os.Parcel;
212import android.os.ParcelFileDescriptor;
213import android.os.PatternMatcher;
214import android.os.Process;
215import android.os.RemoteCallbackList;
216import android.os.RemoteException;
217import android.os.ResultReceiver;
218import android.os.SELinux;
219import android.os.ServiceManager;
220import android.os.ShellCallback;
221import android.os.SystemClock;
222import android.os.SystemProperties;
223import android.os.Trace;
224import android.os.UserHandle;
225import android.os.UserManager;
226import android.os.UserManagerInternal;
227import android.os.storage.IStorageManager;
228import android.os.storage.StorageEventListener;
229import android.os.storage.StorageManager;
230import android.os.storage.StorageManagerInternal;
231import android.os.storage.VolumeInfo;
232import android.os.storage.VolumeRecord;
233import android.provider.Settings.Global;
234import android.provider.Settings.Secure;
235import android.security.KeyStore;
236import android.security.SystemKeyStore;
237import android.service.pm.PackageServiceDumpProto;
238import android.system.ErrnoException;
239import android.system.Os;
240import android.text.TextUtils;
241import android.text.format.DateUtils;
242import android.util.ArrayMap;
243import android.util.ArraySet;
244import android.util.Base64;
245import android.util.DisplayMetrics;
246import android.util.EventLog;
247import android.util.ExceptionUtils;
248import android.util.Log;
249import android.util.LogPrinter;
250import android.util.LongSparseArray;
251import android.util.LongSparseLongArray;
252import android.util.MathUtils;
253import android.util.PackageUtils;
254import android.util.Pair;
255import android.util.PrintStreamPrinter;
256import android.util.Slog;
257import android.util.SparseArray;
258import android.util.SparseBooleanArray;
259import android.util.SparseIntArray;
260import android.util.TimingsTraceLog;
261import android.util.Xml;
262import android.util.jar.StrictJarFile;
263import android.util.proto.ProtoOutputStream;
264import android.view.Display;
265
266import com.android.internal.R;
267import com.android.internal.annotations.GuardedBy;
268import com.android.internal.app.IMediaContainerService;
269import com.android.internal.app.ResolverActivity;
270import com.android.internal.content.NativeLibraryHelper;
271import com.android.internal.content.PackageHelper;
272import com.android.internal.logging.MetricsLogger;
273import com.android.internal.os.IParcelFileDescriptorFactory;
274import com.android.internal.os.SomeArgs;
275import com.android.internal.os.Zygote;
276import com.android.internal.telephony.CarrierAppUtils;
277import com.android.internal.util.ArrayUtils;
278import com.android.internal.util.ConcurrentUtils;
279import com.android.internal.util.DumpUtils;
280import com.android.internal.util.FastXmlSerializer;
281import com.android.internal.util.IndentingPrintWriter;
282import com.android.internal.util.Preconditions;
283import com.android.internal.util.XmlUtils;
284import com.android.server.AttributeCache;
285import com.android.server.DeviceIdleController;
286import com.android.server.EventLogTags;
287import com.android.server.FgThread;
288import com.android.server.IntentResolver;
289import com.android.server.LocalServices;
290import com.android.server.LockGuard;
291import com.android.server.ServiceThread;
292import com.android.server.SystemConfig;
293import com.android.server.SystemServerInitThreadPool;
294import com.android.server.Watchdog;
295import com.android.server.net.NetworkPolicyManagerInternal;
296import com.android.server.pm.Installer.InstallerException;
297import com.android.server.pm.Settings.DatabaseVersion;
298import com.android.server.pm.Settings.VersionInfo;
299import com.android.server.pm.dex.ArtManagerService;
300import com.android.server.pm.dex.DexLogger;
301import com.android.server.pm.dex.DexManager;
302import com.android.server.pm.dex.DexoptOptions;
303import com.android.server.pm.dex.PackageDexUsage;
304import com.android.server.pm.permission.BasePermission;
305import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
306import com.android.server.pm.permission.PermissionManagerService;
307import com.android.server.pm.permission.PermissionManagerInternal;
308import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
309import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
310import com.android.server.pm.permission.PermissionsState;
311import com.android.server.pm.permission.PermissionsState.PermissionState;
312import com.android.server.storage.DeviceStorageMonitorInternal;
313
314import dalvik.system.CloseGuard;
315import dalvik.system.VMRuntime;
316
317import libcore.io.IoUtils;
318
319import org.xmlpull.v1.XmlPullParser;
320import org.xmlpull.v1.XmlPullParserException;
321import org.xmlpull.v1.XmlSerializer;
322
323import java.io.BufferedOutputStream;
324import java.io.ByteArrayInputStream;
325import java.io.ByteArrayOutputStream;
326import java.io.File;
327import java.io.FileDescriptor;
328import java.io.FileInputStream;
329import java.io.FileOutputStream;
330import java.io.FilenameFilter;
331import java.io.IOException;
332import java.io.PrintWriter;
333import java.lang.annotation.Retention;
334import java.lang.annotation.RetentionPolicy;
335import java.nio.charset.StandardCharsets;
336import java.security.DigestInputStream;
337import java.security.MessageDigest;
338import java.security.NoSuchAlgorithmException;
339import java.security.PublicKey;
340import java.security.SecureRandom;
341import java.security.cert.CertificateException;
342import java.util.ArrayList;
343import java.util.Arrays;
344import java.util.Collection;
345import java.util.Collections;
346import java.util.Comparator;
347import java.util.HashMap;
348import java.util.HashSet;
349import java.util.Iterator;
350import java.util.LinkedHashSet;
351import java.util.List;
352import java.util.Map;
353import java.util.Objects;
354import java.util.Set;
355import java.util.concurrent.CountDownLatch;
356import java.util.concurrent.Future;
357import java.util.concurrent.TimeUnit;
358import java.util.concurrent.atomic.AtomicBoolean;
359import java.util.concurrent.atomic.AtomicInteger;
360
361/**
362 * Keep track of all those APKs everywhere.
363 * <p>
364 * Internally there are two important locks:
365 * <ul>
366 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
367 * and other related state. It is a fine-grained lock that should only be held
368 * momentarily, as it's one of the most contended locks in the system.
369 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
370 * operations typically involve heavy lifting of application data on disk. Since
371 * {@code installd} is single-threaded, and it's operations can often be slow,
372 * this lock should never be acquired while already holding {@link #mPackages}.
373 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
374 * holding {@link #mInstallLock}.
375 * </ul>
376 * Many internal methods rely on the caller to hold the appropriate locks, and
377 * this contract is expressed through method name suffixes:
378 * <ul>
379 * <li>fooLI(): the caller must hold {@link #mInstallLock}
380 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
381 * being modified must be frozen
382 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
383 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
384 * </ul>
385 * <p>
386 * Because this class is very central to the platform's security; please run all
387 * CTS and unit tests whenever making modifications:
388 *
389 * <pre>
390 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
391 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
392 * </pre>
393 */
394public class PackageManagerService extends IPackageManager.Stub
395        implements PackageSender {
396    static final String TAG = "PackageManager";
397    public static final boolean DEBUG_SETTINGS = false;
398    static final boolean DEBUG_PREFERRED = false;
399    static final boolean DEBUG_UPGRADE = false;
400    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
401    private static final boolean DEBUG_BACKUP = false;
402    public static final boolean DEBUG_INSTALL = false;
403    public static final boolean DEBUG_REMOVE = false;
404    private static final boolean DEBUG_BROADCASTS = false;
405    private static final boolean DEBUG_SHOW_INFO = false;
406    private static final boolean DEBUG_PACKAGE_INFO = false;
407    private static final boolean DEBUG_INTENT_MATCHING = false;
408    public static final boolean DEBUG_PACKAGE_SCANNING = false;
409    private static final boolean DEBUG_VERIFY = false;
410    private static final boolean DEBUG_FILTERS = false;
411    public static final boolean DEBUG_PERMISSIONS = false;
412    private static final boolean DEBUG_SHARED_LIBRARIES = false;
413    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
414
415    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
416    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
417    // user, but by default initialize to this.
418    public static final boolean DEBUG_DEXOPT = false;
419
420    private static final boolean DEBUG_ABI_SELECTION = false;
421    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
422    private static final boolean DEBUG_TRIAGED_MISSING = false;
423    private static final boolean DEBUG_APP_DATA = false;
424
425    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
426    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
427
428    private static final boolean HIDE_EPHEMERAL_APIS = false;
429
430    private static final boolean ENABLE_FREE_CACHE_V2 =
431            SystemProperties.getBoolean("fw.free_cache_v2", true);
432
433    private static final int RADIO_UID = Process.PHONE_UID;
434    private static final int LOG_UID = Process.LOG_UID;
435    private static final int NFC_UID = Process.NFC_UID;
436    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
437    private static final int SHELL_UID = Process.SHELL_UID;
438
439    // Suffix used during package installation when copying/moving
440    // package apks to install directory.
441    private static final String INSTALL_PACKAGE_SUFFIX = "-";
442
443    static final int SCAN_NO_DEX = 1<<0;
444    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
445    static final int SCAN_NEW_INSTALL = 1<<2;
446    static final int SCAN_UPDATE_TIME = 1<<3;
447    static final int SCAN_BOOTING = 1<<4;
448    static final int SCAN_TRUSTED_OVERLAY = 1<<5;
449    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
450    static final int SCAN_REQUIRE_KNOWN = 1<<7;
451    static final int SCAN_MOVE = 1<<8;
452    static final int SCAN_INITIAL = 1<<9;
453    static final int SCAN_CHECK_ONLY = 1<<10;
454    static final int SCAN_DONT_KILL_APP = 1<<11;
455    static final int SCAN_IGNORE_FROZEN = 1<<12;
456    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
457    static final int SCAN_AS_INSTANT_APP = 1<<14;
458    static final int SCAN_AS_FULL_APP = 1<<15;
459    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
460    static final int SCAN_AS_SYSTEM = 1<<17;
461    static final int SCAN_AS_PRIVILEGED = 1<<18;
462    static final int SCAN_AS_OEM = 1<<19;
463    static final int SCAN_AS_VENDOR = 1<<20;
464
465    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
466            SCAN_NO_DEX,
467            SCAN_UPDATE_SIGNATURE,
468            SCAN_NEW_INSTALL,
469            SCAN_UPDATE_TIME,
470            SCAN_BOOTING,
471            SCAN_TRUSTED_OVERLAY,
472            SCAN_DELETE_DATA_ON_FAILURES,
473            SCAN_REQUIRE_KNOWN,
474            SCAN_MOVE,
475            SCAN_INITIAL,
476            SCAN_CHECK_ONLY,
477            SCAN_DONT_KILL_APP,
478            SCAN_IGNORE_FROZEN,
479            SCAN_FIRST_BOOT_OR_UPGRADE,
480            SCAN_AS_INSTANT_APP,
481            SCAN_AS_FULL_APP,
482            SCAN_AS_VIRTUAL_PRELOAD,
483    })
484    @Retention(RetentionPolicy.SOURCE)
485    public @interface ScanFlags {}
486
487    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
488    /** Extension of the compressed packages */
489    public final static String COMPRESSED_EXTENSION = ".gz";
490    /** Suffix of stub packages on the system partition */
491    public final static String STUB_SUFFIX = "-Stub";
492
493    private static final int[] EMPTY_INT_ARRAY = new int[0];
494
495    private static final int TYPE_UNKNOWN = 0;
496    private static final int TYPE_ACTIVITY = 1;
497    private static final int TYPE_RECEIVER = 2;
498    private static final int TYPE_SERVICE = 3;
499    private static final int TYPE_PROVIDER = 4;
500    @IntDef(prefix = { "TYPE_" }, value = {
501            TYPE_UNKNOWN,
502            TYPE_ACTIVITY,
503            TYPE_RECEIVER,
504            TYPE_SERVICE,
505            TYPE_PROVIDER,
506    })
507    @Retention(RetentionPolicy.SOURCE)
508    public @interface ComponentType {}
509
510    /**
511     * Timeout (in milliseconds) after which the watchdog should declare that
512     * our handler thread is wedged.  The usual default for such things is one
513     * minute but we sometimes do very lengthy I/O operations on this thread,
514     * such as installing multi-gigabyte applications, so ours needs to be longer.
515     */
516    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
517
518    /**
519     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
520     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
521     * settings entry if available, otherwise we use the hardcoded default.  If it's been
522     * more than this long since the last fstrim, we force one during the boot sequence.
523     *
524     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
525     * one gets run at the next available charging+idle time.  This final mandatory
526     * no-fstrim check kicks in only of the other scheduling criteria is never met.
527     */
528    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
529
530    /**
531     * Whether verification is enabled by default.
532     */
533    private static final boolean DEFAULT_VERIFY_ENABLE = true;
534
535    /**
536     * The default maximum time to wait for the verification agent to return in
537     * milliseconds.
538     */
539    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
540
541    /**
542     * The default response for package verification timeout.
543     *
544     * This can be either PackageManager.VERIFICATION_ALLOW or
545     * PackageManager.VERIFICATION_REJECT.
546     */
547    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
548
549    public static final String PLATFORM_PACKAGE_NAME = "android";
550
551    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
552
553    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
554            DEFAULT_CONTAINER_PACKAGE,
555            "com.android.defcontainer.DefaultContainerService");
556
557    private static final String KILL_APP_REASON_GIDS_CHANGED =
558            "permission grant or revoke changed gids";
559
560    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
561            "permissions revoked";
562
563    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
564
565    private static final String PACKAGE_SCHEME = "package";
566
567    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
568
569    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
570
571    /** Canonical intent used to identify what counts as a "web browser" app */
572    private static final Intent sBrowserIntent;
573    static {
574        sBrowserIntent = new Intent();
575        sBrowserIntent.setAction(Intent.ACTION_VIEW);
576        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
577        sBrowserIntent.setData(Uri.parse("http:"));
578    }
579
580    /**
581     * The set of all protected actions [i.e. those actions for which a high priority
582     * intent filter is disallowed].
583     */
584    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
585    static {
586        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
587        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
588        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
589        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
590    }
591
592    // Compilation reasons.
593    public static final int REASON_FIRST_BOOT = 0;
594    public static final int REASON_BOOT = 1;
595    public static final int REASON_INSTALL = 2;
596    public static final int REASON_BACKGROUND_DEXOPT = 3;
597    public static final int REASON_AB_OTA = 4;
598    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
599    public static final int REASON_SHARED = 6;
600
601    public static final int REASON_LAST = REASON_SHARED;
602
603    /**
604     * Version number for the package parser cache. Increment this whenever the format or
605     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
606     */
607    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
608
609    /**
610     * Whether the package parser cache is enabled.
611     */
612    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
613
614    /**
615     * Permissions required in order to receive instant application lifecycle broadcasts.
616     */
617    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
618            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
619
620    final ServiceThread mHandlerThread;
621
622    final PackageHandler mHandler;
623
624    private final ProcessLoggingHandler mProcessLoggingHandler;
625
626    /**
627     * Messages for {@link #mHandler} that need to wait for system ready before
628     * being dispatched.
629     */
630    private ArrayList<Message> mPostSystemReadyMessages;
631
632    final int mSdkVersion = Build.VERSION.SDK_INT;
633
634    final Context mContext;
635    final boolean mFactoryTest;
636    final boolean mOnlyCore;
637    final DisplayMetrics mMetrics;
638    final int mDefParseFlags;
639    final String[] mSeparateProcesses;
640    final boolean mIsUpgrade;
641    final boolean mIsPreNUpgrade;
642    final boolean mIsPreNMR1Upgrade;
643
644    // Have we told the Activity Manager to whitelist the default container service by uid yet?
645    @GuardedBy("mPackages")
646    boolean mDefaultContainerWhitelisted = false;
647
648    @GuardedBy("mPackages")
649    private boolean mDexOptDialogShown;
650
651    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
652    // LOCK HELD.  Can be called with mInstallLock held.
653    @GuardedBy("mInstallLock")
654    final Installer mInstaller;
655
656    /** Directory where installed applications are stored */
657    private static final File sAppInstallDir =
658            new File(Environment.getDataDirectory(), "app");
659    /** Directory where installed application's 32-bit native libraries are copied. */
660    private static final File sAppLib32InstallDir =
661            new File(Environment.getDataDirectory(), "app-lib");
662    /** Directory where code and non-resource assets of forward-locked applications are stored */
663    private static final File sDrmAppPrivateInstallDir =
664            new File(Environment.getDataDirectory(), "app-private");
665
666    // ----------------------------------------------------------------
667
668    // Lock for state used when installing and doing other long running
669    // operations.  Methods that must be called with this lock held have
670    // the suffix "LI".
671    final Object mInstallLock = new Object();
672
673    // ----------------------------------------------------------------
674
675    // Keys are String (package name), values are Package.  This also serves
676    // as the lock for the global state.  Methods that must be called with
677    // this lock held have the prefix "LP".
678    @GuardedBy("mPackages")
679    final ArrayMap<String, PackageParser.Package> mPackages =
680            new ArrayMap<String, PackageParser.Package>();
681
682    final ArrayMap<String, Set<String>> mKnownCodebase =
683            new ArrayMap<String, Set<String>>();
684
685    // Keys are isolated uids and values are the uid of the application
686    // that created the isolated proccess.
687    @GuardedBy("mPackages")
688    final SparseIntArray mIsolatedOwners = new SparseIntArray();
689
690    /**
691     * Tracks new system packages [received in an OTA] that we expect to
692     * find updated user-installed versions. Keys are package name, values
693     * are package location.
694     */
695    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
696    /**
697     * Tracks high priority intent filters for protected actions. During boot, certain
698     * filter actions are protected and should never be allowed to have a high priority
699     * intent filter for them. However, there is one, and only one exception -- the
700     * setup wizard. It must be able to define a high priority intent filter for these
701     * actions to ensure there are no escapes from the wizard. We need to delay processing
702     * of these during boot as we need to look at all of the system packages in order
703     * to know which component is the setup wizard.
704     */
705    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
706    /**
707     * Whether or not processing protected filters should be deferred.
708     */
709    private boolean mDeferProtectedFilters = true;
710
711    /**
712     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
713     */
714    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
715    /**
716     * Whether or not system app permissions should be promoted from install to runtime.
717     */
718    boolean mPromoteSystemApps;
719
720    @GuardedBy("mPackages")
721    final Settings mSettings;
722
723    /**
724     * Set of package names that are currently "frozen", which means active
725     * surgery is being done on the code/data for that package. The platform
726     * will refuse to launch frozen packages to avoid race conditions.
727     *
728     * @see PackageFreezer
729     */
730    @GuardedBy("mPackages")
731    final ArraySet<String> mFrozenPackages = new ArraySet<>();
732
733    final ProtectedPackages mProtectedPackages;
734
735    @GuardedBy("mLoadedVolumes")
736    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
737
738    boolean mFirstBoot;
739
740    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
741
742    @GuardedBy("mAvailableFeatures")
743    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
744
745    private final InstantAppRegistry mInstantAppRegistry;
746
747    @GuardedBy("mPackages")
748    int mChangedPackagesSequenceNumber;
749    /**
750     * List of changed [installed, removed or updated] packages.
751     * mapping from user id -> sequence number -> package name
752     */
753    @GuardedBy("mPackages")
754    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
755    /**
756     * The sequence number of the last change to a package.
757     * mapping from user id -> package name -> sequence number
758     */
759    @GuardedBy("mPackages")
760    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
761
762    @GuardedBy("mPackages")
763    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
764
765    class PackageParserCallback implements PackageParser.Callback {
766        @Override public final boolean hasFeature(String feature) {
767            return PackageManagerService.this.hasSystemFeature(feature, 0);
768        }
769
770        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
771                Collection<PackageParser.Package> allPackages, String targetPackageName) {
772            List<PackageParser.Package> overlayPackages = null;
773            for (PackageParser.Package p : allPackages) {
774                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
775                    if (overlayPackages == null) {
776                        overlayPackages = new ArrayList<PackageParser.Package>();
777                    }
778                    overlayPackages.add(p);
779                }
780            }
781            if (overlayPackages != null) {
782                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
783                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
784                        return p1.mOverlayPriority - p2.mOverlayPriority;
785                    }
786                };
787                Collections.sort(overlayPackages, cmp);
788            }
789            return overlayPackages;
790        }
791
792        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
793                String targetPackageName, String targetPath) {
794            if ("android".equals(targetPackageName)) {
795                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
796                // native AssetManager.
797                return null;
798            }
799            List<PackageParser.Package> overlayPackages =
800                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
801            if (overlayPackages == null || overlayPackages.isEmpty()) {
802                return null;
803            }
804            List<String> overlayPathList = null;
805            for (PackageParser.Package overlayPackage : overlayPackages) {
806                if (targetPath == null) {
807                    if (overlayPathList == null) {
808                        overlayPathList = new ArrayList<String>();
809                    }
810                    overlayPathList.add(overlayPackage.baseCodePath);
811                    continue;
812                }
813
814                try {
815                    // Creates idmaps for system to parse correctly the Android manifest of the
816                    // target package.
817                    //
818                    // OverlayManagerService will update each of them with a correct gid from its
819                    // target package app id.
820                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
821                            UserHandle.getSharedAppGid(
822                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
823                    if (overlayPathList == null) {
824                        overlayPathList = new ArrayList<String>();
825                    }
826                    overlayPathList.add(overlayPackage.baseCodePath);
827                } catch (InstallerException e) {
828                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
829                            overlayPackage.baseCodePath);
830                }
831            }
832            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
833        }
834
835        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
836            synchronized (mPackages) {
837                return getStaticOverlayPathsLocked(
838                        mPackages.values(), targetPackageName, targetPath);
839            }
840        }
841
842        @Override public final String[] getOverlayApks(String targetPackageName) {
843            return getStaticOverlayPaths(targetPackageName, null);
844        }
845
846        @Override public final String[] getOverlayPaths(String targetPackageName,
847                String targetPath) {
848            return getStaticOverlayPaths(targetPackageName, targetPath);
849        }
850    }
851
852    class ParallelPackageParserCallback extends PackageParserCallback {
853        List<PackageParser.Package> mOverlayPackages = null;
854
855        void findStaticOverlayPackages() {
856            synchronized (mPackages) {
857                for (PackageParser.Package p : mPackages.values()) {
858                    if (p.mIsStaticOverlay) {
859                        if (mOverlayPackages == null) {
860                            mOverlayPackages = new ArrayList<PackageParser.Package>();
861                        }
862                        mOverlayPackages.add(p);
863                    }
864                }
865            }
866        }
867
868        @Override
869        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
870            // We can trust mOverlayPackages without holding mPackages because package uninstall
871            // can't happen while running parallel parsing.
872            // Moreover holding mPackages on each parsing thread causes dead-lock.
873            return mOverlayPackages == null ? null :
874                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
875        }
876    }
877
878    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
879    final ParallelPackageParserCallback mParallelPackageParserCallback =
880            new ParallelPackageParserCallback();
881
882    public static final class SharedLibraryEntry {
883        public final @Nullable String path;
884        public final @Nullable String apk;
885        public final @NonNull SharedLibraryInfo info;
886
887        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
888                String declaringPackageName, long declaringPackageVersionCode) {
889            path = _path;
890            apk = _apk;
891            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
892                    declaringPackageName, declaringPackageVersionCode), null);
893        }
894    }
895
896    // Currently known shared libraries.
897    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
898    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
899            new ArrayMap<>();
900
901    // All available activities, for your resolving pleasure.
902    final ActivityIntentResolver mActivities =
903            new ActivityIntentResolver();
904
905    // All available receivers, for your resolving pleasure.
906    final ActivityIntentResolver mReceivers =
907            new ActivityIntentResolver();
908
909    // All available services, for your resolving pleasure.
910    final ServiceIntentResolver mServices = new ServiceIntentResolver();
911
912    // All available providers, for your resolving pleasure.
913    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
914
915    // Mapping from provider base names (first directory in content URI codePath)
916    // to the provider information.
917    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
918            new ArrayMap<String, PackageParser.Provider>();
919
920    // Mapping from instrumentation class names to info about them.
921    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
922            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
923
924    // Packages whose data we have transfered into another package, thus
925    // should no longer exist.
926    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
927
928    // Broadcast actions that are only available to the system.
929    @GuardedBy("mProtectedBroadcasts")
930    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
931
932    /** List of packages waiting for verification. */
933    final SparseArray<PackageVerificationState> mPendingVerification
934            = new SparseArray<PackageVerificationState>();
935
936    final PackageInstallerService mInstallerService;
937
938    final ArtManagerService mArtManagerService;
939
940    private final PackageDexOptimizer mPackageDexOptimizer;
941    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
942    // is used by other apps).
943    private final DexManager mDexManager;
944
945    private AtomicInteger mNextMoveId = new AtomicInteger();
946    private final MoveCallbacks mMoveCallbacks;
947
948    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
949
950    // Cache of users who need badging.
951    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
952
953    /** Token for keys in mPendingVerification. */
954    private int mPendingVerificationToken = 0;
955
956    volatile boolean mSystemReady;
957    volatile boolean mSafeMode;
958    volatile boolean mHasSystemUidErrors;
959    private volatile boolean mEphemeralAppsDisabled;
960
961    ApplicationInfo mAndroidApplication;
962    final ActivityInfo mResolveActivity = new ActivityInfo();
963    final ResolveInfo mResolveInfo = new ResolveInfo();
964    ComponentName mResolveComponentName;
965    PackageParser.Package mPlatformPackage;
966    ComponentName mCustomResolverComponentName;
967
968    boolean mResolverReplaced = false;
969
970    private final @Nullable ComponentName mIntentFilterVerifierComponent;
971    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
972
973    private int mIntentFilterVerificationToken = 0;
974
975    /** The service connection to the ephemeral resolver */
976    final EphemeralResolverConnection mInstantAppResolverConnection;
977    /** Component used to show resolver settings for Instant Apps */
978    final ComponentName mInstantAppResolverSettingsComponent;
979
980    /** Activity used to install instant applications */
981    ActivityInfo mInstantAppInstallerActivity;
982    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
983
984    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
985            = new SparseArray<IntentFilterVerificationState>();
986
987    // TODO remove this and go through mPermissonManager directly
988    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
989    private final PermissionManagerInternal mPermissionManager;
990
991    // List of packages names to keep cached, even if they are uninstalled for all users
992    private List<String> mKeepUninstalledPackages;
993
994    private UserManagerInternal mUserManagerInternal;
995
996    private DeviceIdleController.LocalService mDeviceIdleController;
997
998    private File mCacheDir;
999
1000    private Future<?> mPrepareAppDataFuture;
1001
1002    private static class IFVerificationParams {
1003        PackageParser.Package pkg;
1004        boolean replacing;
1005        int userId;
1006        int verifierUid;
1007
1008        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1009                int _userId, int _verifierUid) {
1010            pkg = _pkg;
1011            replacing = _replacing;
1012            userId = _userId;
1013            replacing = _replacing;
1014            verifierUid = _verifierUid;
1015        }
1016    }
1017
1018    private interface IntentFilterVerifier<T extends IntentFilter> {
1019        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1020                                               T filter, String packageName);
1021        void startVerifications(int userId);
1022        void receiveVerificationResponse(int verificationId);
1023    }
1024
1025    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1026        private Context mContext;
1027        private ComponentName mIntentFilterVerifierComponent;
1028        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1029
1030        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1031            mContext = context;
1032            mIntentFilterVerifierComponent = verifierComponent;
1033        }
1034
1035        private String getDefaultScheme() {
1036            return IntentFilter.SCHEME_HTTPS;
1037        }
1038
1039        @Override
1040        public void startVerifications(int userId) {
1041            // Launch verifications requests
1042            int count = mCurrentIntentFilterVerifications.size();
1043            for (int n=0; n<count; n++) {
1044                int verificationId = mCurrentIntentFilterVerifications.get(n);
1045                final IntentFilterVerificationState ivs =
1046                        mIntentFilterVerificationStates.get(verificationId);
1047
1048                String packageName = ivs.getPackageName();
1049
1050                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1051                final int filterCount = filters.size();
1052                ArraySet<String> domainsSet = new ArraySet<>();
1053                for (int m=0; m<filterCount; m++) {
1054                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1055                    domainsSet.addAll(filter.getHostsList());
1056                }
1057                synchronized (mPackages) {
1058                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1059                            packageName, domainsSet) != null) {
1060                        scheduleWriteSettingsLocked();
1061                    }
1062                }
1063                sendVerificationRequest(verificationId, ivs);
1064            }
1065            mCurrentIntentFilterVerifications.clear();
1066        }
1067
1068        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1069            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1070            verificationIntent.putExtra(
1071                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1072                    verificationId);
1073            verificationIntent.putExtra(
1074                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1075                    getDefaultScheme());
1076            verificationIntent.putExtra(
1077                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1078                    ivs.getHostsString());
1079            verificationIntent.putExtra(
1080                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1081                    ivs.getPackageName());
1082            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1083            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1084
1085            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1086            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1087                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1088                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1089
1090            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1091            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1092                    "Sending IntentFilter verification broadcast");
1093        }
1094
1095        public void receiveVerificationResponse(int verificationId) {
1096            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1097
1098            final boolean verified = ivs.isVerified();
1099
1100            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1101            final int count = filters.size();
1102            if (DEBUG_DOMAIN_VERIFICATION) {
1103                Slog.i(TAG, "Received verification response " + verificationId
1104                        + " for " + count + " filters, verified=" + verified);
1105            }
1106            for (int n=0; n<count; n++) {
1107                PackageParser.ActivityIntentInfo filter = filters.get(n);
1108                filter.setVerified(verified);
1109
1110                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1111                        + " verified with result:" + verified + " and hosts:"
1112                        + ivs.getHostsString());
1113            }
1114
1115            mIntentFilterVerificationStates.remove(verificationId);
1116
1117            final String packageName = ivs.getPackageName();
1118            IntentFilterVerificationInfo ivi = null;
1119
1120            synchronized (mPackages) {
1121                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1122            }
1123            if (ivi == null) {
1124                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1125                        + verificationId + " packageName:" + packageName);
1126                return;
1127            }
1128            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1129                    "Updating IntentFilterVerificationInfo for package " + packageName
1130                            +" verificationId:" + verificationId);
1131
1132            synchronized (mPackages) {
1133                if (verified) {
1134                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1135                } else {
1136                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1137                }
1138                scheduleWriteSettingsLocked();
1139
1140                final int userId = ivs.getUserId();
1141                if (userId != UserHandle.USER_ALL) {
1142                    final int userStatus =
1143                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1144
1145                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1146                    boolean needUpdate = false;
1147
1148                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1149                    // already been set by the User thru the Disambiguation dialog
1150                    switch (userStatus) {
1151                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1152                            if (verified) {
1153                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1154                            } else {
1155                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1156                            }
1157                            needUpdate = true;
1158                            break;
1159
1160                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1161                            if (verified) {
1162                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1163                                needUpdate = true;
1164                            }
1165                            break;
1166
1167                        default:
1168                            // Nothing to do
1169                    }
1170
1171                    if (needUpdate) {
1172                        mSettings.updateIntentFilterVerificationStatusLPw(
1173                                packageName, updatedStatus, userId);
1174                        scheduleWritePackageRestrictionsLocked(userId);
1175                    }
1176                }
1177            }
1178        }
1179
1180        @Override
1181        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1182                    ActivityIntentInfo filter, String packageName) {
1183            if (!hasValidDomains(filter)) {
1184                return false;
1185            }
1186            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1187            if (ivs == null) {
1188                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1189                        packageName);
1190            }
1191            if (DEBUG_DOMAIN_VERIFICATION) {
1192                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1193            }
1194            ivs.addFilter(filter);
1195            return true;
1196        }
1197
1198        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1199                int userId, int verificationId, String packageName) {
1200            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1201                    verifierUid, userId, packageName);
1202            ivs.setPendingState();
1203            synchronized (mPackages) {
1204                mIntentFilterVerificationStates.append(verificationId, ivs);
1205                mCurrentIntentFilterVerifications.add(verificationId);
1206            }
1207            return ivs;
1208        }
1209    }
1210
1211    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1212        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1213                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1214                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1215    }
1216
1217    // Set of pending broadcasts for aggregating enable/disable of components.
1218    static class PendingPackageBroadcasts {
1219        // for each user id, a map of <package name -> components within that package>
1220        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1221
1222        public PendingPackageBroadcasts() {
1223            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1224        }
1225
1226        public ArrayList<String> get(int userId, String packageName) {
1227            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1228            return packages.get(packageName);
1229        }
1230
1231        public void put(int userId, String packageName, ArrayList<String> components) {
1232            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1233            packages.put(packageName, components);
1234        }
1235
1236        public void remove(int userId, String packageName) {
1237            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1238            if (packages != null) {
1239                packages.remove(packageName);
1240            }
1241        }
1242
1243        public void remove(int userId) {
1244            mUidMap.remove(userId);
1245        }
1246
1247        public int userIdCount() {
1248            return mUidMap.size();
1249        }
1250
1251        public int userIdAt(int n) {
1252            return mUidMap.keyAt(n);
1253        }
1254
1255        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1256            return mUidMap.get(userId);
1257        }
1258
1259        public int size() {
1260            // total number of pending broadcast entries across all userIds
1261            int num = 0;
1262            for (int i = 0; i< mUidMap.size(); i++) {
1263                num += mUidMap.valueAt(i).size();
1264            }
1265            return num;
1266        }
1267
1268        public void clear() {
1269            mUidMap.clear();
1270        }
1271
1272        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1273            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1274            if (map == null) {
1275                map = new ArrayMap<String, ArrayList<String>>();
1276                mUidMap.put(userId, map);
1277            }
1278            return map;
1279        }
1280    }
1281    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1282
1283    // Service Connection to remote media container service to copy
1284    // package uri's from external media onto secure containers
1285    // or internal storage.
1286    private IMediaContainerService mContainerService = null;
1287
1288    static final int SEND_PENDING_BROADCAST = 1;
1289    static final int MCS_BOUND = 3;
1290    static final int END_COPY = 4;
1291    static final int INIT_COPY = 5;
1292    static final int MCS_UNBIND = 6;
1293    static final int START_CLEANING_PACKAGE = 7;
1294    static final int FIND_INSTALL_LOC = 8;
1295    static final int POST_INSTALL = 9;
1296    static final int MCS_RECONNECT = 10;
1297    static final int MCS_GIVE_UP = 11;
1298    static final int WRITE_SETTINGS = 13;
1299    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1300    static final int PACKAGE_VERIFIED = 15;
1301    static final int CHECK_PENDING_VERIFICATION = 16;
1302    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1303    static final int INTENT_FILTER_VERIFIED = 18;
1304    static final int WRITE_PACKAGE_LIST = 19;
1305    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1306
1307    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1308
1309    // Delay time in millisecs
1310    static final int BROADCAST_DELAY = 10 * 1000;
1311
1312    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1313            2 * 60 * 60 * 1000L; /* two hours */
1314
1315    static UserManagerService sUserManager;
1316
1317    // Stores a list of users whose package restrictions file needs to be updated
1318    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1319
1320    final private DefaultContainerConnection mDefContainerConn =
1321            new DefaultContainerConnection();
1322    class DefaultContainerConnection implements ServiceConnection {
1323        public void onServiceConnected(ComponentName name, IBinder service) {
1324            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1325            final IMediaContainerService imcs = IMediaContainerService.Stub
1326                    .asInterface(Binder.allowBlocking(service));
1327            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1328        }
1329
1330        public void onServiceDisconnected(ComponentName name) {
1331            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1332        }
1333    }
1334
1335    // Recordkeeping of restore-after-install operations that are currently in flight
1336    // between the Package Manager and the Backup Manager
1337    static class PostInstallData {
1338        public InstallArgs args;
1339        public PackageInstalledInfo res;
1340
1341        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1342            args = _a;
1343            res = _r;
1344        }
1345    }
1346
1347    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1348    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1349
1350    // XML tags for backup/restore of various bits of state
1351    private static final String TAG_PREFERRED_BACKUP = "pa";
1352    private static final String TAG_DEFAULT_APPS = "da";
1353    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1354
1355    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1356    private static final String TAG_ALL_GRANTS = "rt-grants";
1357    private static final String TAG_GRANT = "grant";
1358    private static final String ATTR_PACKAGE_NAME = "pkg";
1359
1360    private static final String TAG_PERMISSION = "perm";
1361    private static final String ATTR_PERMISSION_NAME = "name";
1362    private static final String ATTR_IS_GRANTED = "g";
1363    private static final String ATTR_USER_SET = "set";
1364    private static final String ATTR_USER_FIXED = "fixed";
1365    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1366
1367    // System/policy permission grants are not backed up
1368    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1369            FLAG_PERMISSION_POLICY_FIXED
1370            | FLAG_PERMISSION_SYSTEM_FIXED
1371            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1372
1373    // And we back up these user-adjusted states
1374    private static final int USER_RUNTIME_GRANT_MASK =
1375            FLAG_PERMISSION_USER_SET
1376            | FLAG_PERMISSION_USER_FIXED
1377            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1378
1379    final @Nullable String mRequiredVerifierPackage;
1380    final @NonNull String mRequiredInstallerPackage;
1381    final @NonNull String mRequiredUninstallerPackage;
1382    final @Nullable String mSetupWizardPackage;
1383    final @Nullable String mStorageManagerPackage;
1384    final @NonNull String mServicesSystemSharedLibraryPackageName;
1385    final @NonNull String mSharedSystemSharedLibraryPackageName;
1386
1387    private final PackageUsage mPackageUsage = new PackageUsage();
1388    private final CompilerStats mCompilerStats = new CompilerStats();
1389
1390    class PackageHandler extends Handler {
1391        private boolean mBound = false;
1392        final ArrayList<HandlerParams> mPendingInstalls =
1393            new ArrayList<HandlerParams>();
1394
1395        private boolean connectToService() {
1396            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1397                    " DefaultContainerService");
1398            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1399            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1400            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1401                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1402                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1403                mBound = true;
1404                return true;
1405            }
1406            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1407            return false;
1408        }
1409
1410        private void disconnectService() {
1411            mContainerService = null;
1412            mBound = false;
1413            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1414            mContext.unbindService(mDefContainerConn);
1415            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1416        }
1417
1418        PackageHandler(Looper looper) {
1419            super(looper);
1420        }
1421
1422        public void handleMessage(Message msg) {
1423            try {
1424                doHandleMessage(msg);
1425            } finally {
1426                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1427            }
1428        }
1429
1430        void doHandleMessage(Message msg) {
1431            switch (msg.what) {
1432                case INIT_COPY: {
1433                    HandlerParams params = (HandlerParams) msg.obj;
1434                    int idx = mPendingInstalls.size();
1435                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1436                    // If a bind was already initiated we dont really
1437                    // need to do anything. The pending install
1438                    // will be processed later on.
1439                    if (!mBound) {
1440                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1441                                System.identityHashCode(mHandler));
1442                        // If this is the only one pending we might
1443                        // have to bind to the service again.
1444                        if (!connectToService()) {
1445                            Slog.e(TAG, "Failed to bind to media container service");
1446                            params.serviceError();
1447                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1448                                    System.identityHashCode(mHandler));
1449                            if (params.traceMethod != null) {
1450                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1451                                        params.traceCookie);
1452                            }
1453                            return;
1454                        } else {
1455                            // Once we bind to the service, the first
1456                            // pending request will be processed.
1457                            mPendingInstalls.add(idx, params);
1458                        }
1459                    } else {
1460                        mPendingInstalls.add(idx, params);
1461                        // Already bound to the service. Just make
1462                        // sure we trigger off processing the first request.
1463                        if (idx == 0) {
1464                            mHandler.sendEmptyMessage(MCS_BOUND);
1465                        }
1466                    }
1467                    break;
1468                }
1469                case MCS_BOUND: {
1470                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1471                    if (msg.obj != null) {
1472                        mContainerService = (IMediaContainerService) msg.obj;
1473                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1474                                System.identityHashCode(mHandler));
1475                    }
1476                    if (mContainerService == null) {
1477                        if (!mBound) {
1478                            // Something seriously wrong since we are not bound and we are not
1479                            // waiting for connection. Bail out.
1480                            Slog.e(TAG, "Cannot bind to media container service");
1481                            for (HandlerParams params : mPendingInstalls) {
1482                                // Indicate service bind error
1483                                params.serviceError();
1484                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1485                                        System.identityHashCode(params));
1486                                if (params.traceMethod != null) {
1487                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1488                                            params.traceMethod, params.traceCookie);
1489                                }
1490                                return;
1491                            }
1492                            mPendingInstalls.clear();
1493                        } else {
1494                            Slog.w(TAG, "Waiting to connect to media container service");
1495                        }
1496                    } else if (mPendingInstalls.size() > 0) {
1497                        HandlerParams params = mPendingInstalls.get(0);
1498                        if (params != null) {
1499                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1500                                    System.identityHashCode(params));
1501                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1502                            if (params.startCopy()) {
1503                                // We are done...  look for more work or to
1504                                // go idle.
1505                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1506                                        "Checking for more work or unbind...");
1507                                // Delete pending install
1508                                if (mPendingInstalls.size() > 0) {
1509                                    mPendingInstalls.remove(0);
1510                                }
1511                                if (mPendingInstalls.size() == 0) {
1512                                    if (mBound) {
1513                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1514                                                "Posting delayed MCS_UNBIND");
1515                                        removeMessages(MCS_UNBIND);
1516                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1517                                        // Unbind after a little delay, to avoid
1518                                        // continual thrashing.
1519                                        sendMessageDelayed(ubmsg, 10000);
1520                                    }
1521                                } else {
1522                                    // There are more pending requests in queue.
1523                                    // Just post MCS_BOUND message to trigger processing
1524                                    // of next pending install.
1525                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1526                                            "Posting MCS_BOUND for next work");
1527                                    mHandler.sendEmptyMessage(MCS_BOUND);
1528                                }
1529                            }
1530                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1531                        }
1532                    } else {
1533                        // Should never happen ideally.
1534                        Slog.w(TAG, "Empty queue");
1535                    }
1536                    break;
1537                }
1538                case MCS_RECONNECT: {
1539                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1540                    if (mPendingInstalls.size() > 0) {
1541                        if (mBound) {
1542                            disconnectService();
1543                        }
1544                        if (!connectToService()) {
1545                            Slog.e(TAG, "Failed to bind to media container service");
1546                            for (HandlerParams params : mPendingInstalls) {
1547                                // Indicate service bind error
1548                                params.serviceError();
1549                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1550                                        System.identityHashCode(params));
1551                            }
1552                            mPendingInstalls.clear();
1553                        }
1554                    }
1555                    break;
1556                }
1557                case MCS_UNBIND: {
1558                    // If there is no actual work left, then time to unbind.
1559                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1560
1561                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1562                        if (mBound) {
1563                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1564
1565                            disconnectService();
1566                        }
1567                    } else if (mPendingInstalls.size() > 0) {
1568                        // There are more pending requests in queue.
1569                        // Just post MCS_BOUND message to trigger processing
1570                        // of next pending install.
1571                        mHandler.sendEmptyMessage(MCS_BOUND);
1572                    }
1573
1574                    break;
1575                }
1576                case MCS_GIVE_UP: {
1577                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1578                    HandlerParams params = mPendingInstalls.remove(0);
1579                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1580                            System.identityHashCode(params));
1581                    break;
1582                }
1583                case SEND_PENDING_BROADCAST: {
1584                    String packages[];
1585                    ArrayList<String> components[];
1586                    int size = 0;
1587                    int uids[];
1588                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1589                    synchronized (mPackages) {
1590                        if (mPendingBroadcasts == null) {
1591                            return;
1592                        }
1593                        size = mPendingBroadcasts.size();
1594                        if (size <= 0) {
1595                            // Nothing to be done. Just return
1596                            return;
1597                        }
1598                        packages = new String[size];
1599                        components = new ArrayList[size];
1600                        uids = new int[size];
1601                        int i = 0;  // filling out the above arrays
1602
1603                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1604                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1605                            Iterator<Map.Entry<String, ArrayList<String>>> it
1606                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1607                                            .entrySet().iterator();
1608                            while (it.hasNext() && i < size) {
1609                                Map.Entry<String, ArrayList<String>> ent = it.next();
1610                                packages[i] = ent.getKey();
1611                                components[i] = ent.getValue();
1612                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1613                                uids[i] = (ps != null)
1614                                        ? UserHandle.getUid(packageUserId, ps.appId)
1615                                        : -1;
1616                                i++;
1617                            }
1618                        }
1619                        size = i;
1620                        mPendingBroadcasts.clear();
1621                    }
1622                    // Send broadcasts
1623                    for (int i = 0; i < size; i++) {
1624                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1625                    }
1626                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1627                    break;
1628                }
1629                case START_CLEANING_PACKAGE: {
1630                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1631                    final String packageName = (String)msg.obj;
1632                    final int userId = msg.arg1;
1633                    final boolean andCode = msg.arg2 != 0;
1634                    synchronized (mPackages) {
1635                        if (userId == UserHandle.USER_ALL) {
1636                            int[] users = sUserManager.getUserIds();
1637                            for (int user : users) {
1638                                mSettings.addPackageToCleanLPw(
1639                                        new PackageCleanItem(user, packageName, andCode));
1640                            }
1641                        } else {
1642                            mSettings.addPackageToCleanLPw(
1643                                    new PackageCleanItem(userId, packageName, andCode));
1644                        }
1645                    }
1646                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1647                    startCleaningPackages();
1648                } break;
1649                case POST_INSTALL: {
1650                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1651
1652                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1653                    final boolean didRestore = (msg.arg2 != 0);
1654                    mRunningInstalls.delete(msg.arg1);
1655
1656                    if (data != null) {
1657                        InstallArgs args = data.args;
1658                        PackageInstalledInfo parentRes = data.res;
1659
1660                        final boolean grantPermissions = (args.installFlags
1661                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1662                        final boolean killApp = (args.installFlags
1663                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1664                        final boolean virtualPreload = ((args.installFlags
1665                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1666                        final String[] grantedPermissions = args.installGrantPermissions;
1667
1668                        // Handle the parent package
1669                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1670                                virtualPreload, grantedPermissions, didRestore,
1671                                args.installerPackageName, args.observer);
1672
1673                        // Handle the child packages
1674                        final int childCount = (parentRes.addedChildPackages != null)
1675                                ? parentRes.addedChildPackages.size() : 0;
1676                        for (int i = 0; i < childCount; i++) {
1677                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1678                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1679                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1680                                    args.installerPackageName, args.observer);
1681                        }
1682
1683                        // Log tracing if needed
1684                        if (args.traceMethod != null) {
1685                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1686                                    args.traceCookie);
1687                        }
1688                    } else {
1689                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1690                    }
1691
1692                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1693                } break;
1694                case WRITE_SETTINGS: {
1695                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1696                    synchronized (mPackages) {
1697                        removeMessages(WRITE_SETTINGS);
1698                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1699                        mSettings.writeLPr();
1700                        mDirtyUsers.clear();
1701                    }
1702                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1703                } break;
1704                case WRITE_PACKAGE_RESTRICTIONS: {
1705                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1706                    synchronized (mPackages) {
1707                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1708                        for (int userId : mDirtyUsers) {
1709                            mSettings.writePackageRestrictionsLPr(userId);
1710                        }
1711                        mDirtyUsers.clear();
1712                    }
1713                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1714                } break;
1715                case WRITE_PACKAGE_LIST: {
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1717                    synchronized (mPackages) {
1718                        removeMessages(WRITE_PACKAGE_LIST);
1719                        mSettings.writePackageListLPr(msg.arg1);
1720                    }
1721                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1722                } break;
1723                case CHECK_PENDING_VERIFICATION: {
1724                    final int verificationId = msg.arg1;
1725                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1726
1727                    if ((state != null) && !state.timeoutExtended()) {
1728                        final InstallArgs args = state.getInstallArgs();
1729                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1730
1731                        Slog.i(TAG, "Verification timed out for " + originUri);
1732                        mPendingVerification.remove(verificationId);
1733
1734                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1735
1736                        final UserHandle user = args.getUser();
1737                        if (getDefaultVerificationResponse(user)
1738                                == PackageManager.VERIFICATION_ALLOW) {
1739                            Slog.i(TAG, "Continuing with installation of " + originUri);
1740                            state.setVerifierResponse(Binder.getCallingUid(),
1741                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1742                            broadcastPackageVerified(verificationId, originUri,
1743                                    PackageManager.VERIFICATION_ALLOW, user);
1744                            try {
1745                                ret = args.copyApk(mContainerService, true);
1746                            } catch (RemoteException e) {
1747                                Slog.e(TAG, "Could not contact the ContainerService");
1748                            }
1749                        } else {
1750                            broadcastPackageVerified(verificationId, originUri,
1751                                    PackageManager.VERIFICATION_REJECT, user);
1752                        }
1753
1754                        Trace.asyncTraceEnd(
1755                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1756
1757                        processPendingInstall(args, ret);
1758                        mHandler.sendEmptyMessage(MCS_UNBIND);
1759                    }
1760                    break;
1761                }
1762                case PACKAGE_VERIFIED: {
1763                    final int verificationId = msg.arg1;
1764
1765                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1766                    if (state == null) {
1767                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1768                        break;
1769                    }
1770
1771                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1772
1773                    state.setVerifierResponse(response.callerUid, response.code);
1774
1775                    if (state.isVerificationComplete()) {
1776                        mPendingVerification.remove(verificationId);
1777
1778                        final InstallArgs args = state.getInstallArgs();
1779                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1780
1781                        int ret;
1782                        if (state.isInstallAllowed()) {
1783                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1784                            broadcastPackageVerified(verificationId, originUri,
1785                                    response.code, state.getInstallArgs().getUser());
1786                            try {
1787                                ret = args.copyApk(mContainerService, true);
1788                            } catch (RemoteException e) {
1789                                Slog.e(TAG, "Could not contact the ContainerService");
1790                            }
1791                        } else {
1792                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1793                        }
1794
1795                        Trace.asyncTraceEnd(
1796                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1797
1798                        processPendingInstall(args, ret);
1799                        mHandler.sendEmptyMessage(MCS_UNBIND);
1800                    }
1801
1802                    break;
1803                }
1804                case START_INTENT_FILTER_VERIFICATIONS: {
1805                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1806                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1807                            params.replacing, params.pkg);
1808                    break;
1809                }
1810                case INTENT_FILTER_VERIFIED: {
1811                    final int verificationId = msg.arg1;
1812
1813                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1814                            verificationId);
1815                    if (state == null) {
1816                        Slog.w(TAG, "Invalid IntentFilter verification token "
1817                                + verificationId + " received");
1818                        break;
1819                    }
1820
1821                    final int userId = state.getUserId();
1822
1823                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1824                            "Processing IntentFilter verification with token:"
1825                            + verificationId + " and userId:" + userId);
1826
1827                    final IntentFilterVerificationResponse response =
1828                            (IntentFilterVerificationResponse) msg.obj;
1829
1830                    state.setVerifierResponse(response.callerUid, response.code);
1831
1832                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1833                            "IntentFilter verification with token:" + verificationId
1834                            + " and userId:" + userId
1835                            + " is settings verifier response with response code:"
1836                            + response.code);
1837
1838                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1839                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1840                                + response.getFailedDomainsString());
1841                    }
1842
1843                    if (state.isVerificationComplete()) {
1844                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1845                    } else {
1846                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1847                                "IntentFilter verification with token:" + verificationId
1848                                + " was not said to be complete");
1849                    }
1850
1851                    break;
1852                }
1853                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1854                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1855                            mInstantAppResolverConnection,
1856                            (InstantAppRequest) msg.obj,
1857                            mInstantAppInstallerActivity,
1858                            mHandler);
1859                }
1860            }
1861        }
1862    }
1863
1864    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1865        @Override
1866        public void onGidsChanged(int appId, int userId) {
1867            mHandler.post(new Runnable() {
1868                @Override
1869                public void run() {
1870                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1871                }
1872            });
1873        }
1874        @Override
1875        public void onPermissionGranted(int uid, int userId) {
1876            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1877
1878            // Not critical; if this is lost, the application has to request again.
1879            synchronized (mPackages) {
1880                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1881            }
1882        }
1883        @Override
1884        public void onInstallPermissionGranted() {
1885            synchronized (mPackages) {
1886                scheduleWriteSettingsLocked();
1887            }
1888        }
1889        @Override
1890        public void onPermissionRevoked(int uid, int userId) {
1891            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1892
1893            synchronized (mPackages) {
1894                // Critical; after this call the application should never have the permission
1895                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1896            }
1897
1898            final int appId = UserHandle.getAppId(uid);
1899            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1900        }
1901        @Override
1902        public void onInstallPermissionRevoked() {
1903            synchronized (mPackages) {
1904                scheduleWriteSettingsLocked();
1905            }
1906        }
1907        @Override
1908        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1909            synchronized (mPackages) {
1910                for (int userId : updatedUserIds) {
1911                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1912                }
1913            }
1914        }
1915        @Override
1916        public void onInstallPermissionUpdated() {
1917            synchronized (mPackages) {
1918                scheduleWriteSettingsLocked();
1919            }
1920        }
1921        @Override
1922        public void onPermissionRemoved() {
1923            synchronized (mPackages) {
1924                mSettings.writeLPr();
1925            }
1926        }
1927    };
1928
1929    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1930            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1931            boolean launchedForRestore, String installerPackage,
1932            IPackageInstallObserver2 installObserver) {
1933        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1934            // Send the removed broadcasts
1935            if (res.removedInfo != null) {
1936                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1937            }
1938
1939            // Now that we successfully installed the package, grant runtime
1940            // permissions if requested before broadcasting the install. Also
1941            // for legacy apps in permission review mode we clear the permission
1942            // review flag which is used to emulate runtime permissions for
1943            // legacy apps.
1944            if (grantPermissions) {
1945                final int callingUid = Binder.getCallingUid();
1946                mPermissionManager.grantRequestedRuntimePermissions(
1947                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1948                        mPermissionCallback);
1949            }
1950
1951            final boolean update = res.removedInfo != null
1952                    && res.removedInfo.removedPackage != null;
1953            final String installerPackageName =
1954                    res.installerPackageName != null
1955                            ? res.installerPackageName
1956                            : res.removedInfo != null
1957                                    ? res.removedInfo.installerPackageName
1958                                    : null;
1959
1960            // If this is the first time we have child packages for a disabled privileged
1961            // app that had no children, we grant requested runtime permissions to the new
1962            // children if the parent on the system image had them already granted.
1963            if (res.pkg.parentPackage != null) {
1964                final int callingUid = Binder.getCallingUid();
1965                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1966                        res.pkg, callingUid, mPermissionCallback);
1967            }
1968
1969            synchronized (mPackages) {
1970                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1971            }
1972
1973            final String packageName = res.pkg.applicationInfo.packageName;
1974
1975            // Determine the set of users who are adding this package for
1976            // the first time vs. those who are seeing an update.
1977            int[] firstUserIds = EMPTY_INT_ARRAY;
1978            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1979            int[] updateUserIds = EMPTY_INT_ARRAY;
1980            int[] instantUserIds = EMPTY_INT_ARRAY;
1981            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1982            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1983            for (int newUser : res.newUsers) {
1984                final boolean isInstantApp = ps.getInstantApp(newUser);
1985                if (allNewUsers) {
1986                    if (isInstantApp) {
1987                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
1988                    } else {
1989                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
1990                    }
1991                    continue;
1992                }
1993                boolean isNew = true;
1994                for (int origUser : res.origUsers) {
1995                    if (origUser == newUser) {
1996                        isNew = false;
1997                        break;
1998                    }
1999                }
2000                if (isNew) {
2001                    if (isInstantApp) {
2002                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2003                    } else {
2004                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2005                    }
2006                } else {
2007                    if (isInstantApp) {
2008                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2009                    } else {
2010                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2011                    }
2012                }
2013            }
2014
2015            // Send installed broadcasts if the package is not a static shared lib.
2016            if (res.pkg.staticSharedLibName == null) {
2017                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2018
2019                // Send added for users that see the package for the first time
2020                // sendPackageAddedForNewUsers also deals with system apps
2021                int appId = UserHandle.getAppId(res.uid);
2022                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2023                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2024                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2025
2026                // Send added for users that don't see the package for the first time
2027                Bundle extras = new Bundle(1);
2028                extras.putInt(Intent.EXTRA_UID, res.uid);
2029                if (update) {
2030                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2031                }
2032                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2033                        extras, 0 /*flags*/,
2034                        null /*targetPackage*/, null /*finishedReceiver*/,
2035                        updateUserIds, instantUserIds);
2036                if (installerPackageName != null) {
2037                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2038                            extras, 0 /*flags*/,
2039                            installerPackageName, null /*finishedReceiver*/,
2040                            updateUserIds, instantUserIds);
2041                }
2042
2043                // Send replaced for users that don't see the package for the first time
2044                if (update) {
2045                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2046                            packageName, extras, 0 /*flags*/,
2047                            null /*targetPackage*/, null /*finishedReceiver*/,
2048                            updateUserIds, instantUserIds);
2049                    if (installerPackageName != null) {
2050                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2051                                extras, 0 /*flags*/,
2052                                installerPackageName, null /*finishedReceiver*/,
2053                                updateUserIds, instantUserIds);
2054                    }
2055                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2056                            null /*package*/, null /*extras*/, 0 /*flags*/,
2057                            packageName /*targetPackage*/,
2058                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2059                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2060                    // First-install and we did a restore, so we're responsible for the
2061                    // first-launch broadcast.
2062                    if (DEBUG_BACKUP) {
2063                        Slog.i(TAG, "Post-restore of " + packageName
2064                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2065                    }
2066                    sendFirstLaunchBroadcast(packageName, installerPackage,
2067                            firstUserIds, firstInstantUserIds);
2068                }
2069
2070                // Send broadcast package appeared if forward locked/external for all users
2071                // treat asec-hosted packages like removable media on upgrade
2072                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2073                    if (DEBUG_INSTALL) {
2074                        Slog.i(TAG, "upgrading pkg " + res.pkg
2075                                + " is ASEC-hosted -> AVAILABLE");
2076                    }
2077                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2078                    ArrayList<String> pkgList = new ArrayList<>(1);
2079                    pkgList.add(packageName);
2080                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2081                }
2082            }
2083
2084            // Work that needs to happen on first install within each user
2085            if (firstUserIds != null && firstUserIds.length > 0) {
2086                synchronized (mPackages) {
2087                    for (int userId : firstUserIds) {
2088                        // If this app is a browser and it's newly-installed for some
2089                        // users, clear any default-browser state in those users. The
2090                        // app's nature doesn't depend on the user, so we can just check
2091                        // its browser nature in any user and generalize.
2092                        if (packageIsBrowser(packageName, userId)) {
2093                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2094                        }
2095
2096                        // We may also need to apply pending (restored) runtime
2097                        // permission grants within these users.
2098                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2099                    }
2100                }
2101            }
2102
2103            if (allNewUsers && !update) {
2104                notifyPackageAdded(packageName);
2105            }
2106
2107            // Log current value of "unknown sources" setting
2108            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2109                    getUnknownSourcesSettings());
2110
2111            // Remove the replaced package's older resources safely now
2112            // We delete after a gc for applications  on sdcard.
2113            if (res.removedInfo != null && res.removedInfo.args != null) {
2114                Runtime.getRuntime().gc();
2115                synchronized (mInstallLock) {
2116                    res.removedInfo.args.doPostDeleteLI(true);
2117                }
2118            } else {
2119                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2120                // and not block here.
2121                VMRuntime.getRuntime().requestConcurrentGC();
2122            }
2123
2124            // Notify DexManager that the package was installed for new users.
2125            // The updated users should already be indexed and the package code paths
2126            // should not change.
2127            // Don't notify the manager for ephemeral apps as they are not expected to
2128            // survive long enough to benefit of background optimizations.
2129            for (int userId : firstUserIds) {
2130                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2131                // There's a race currently where some install events may interleave with an uninstall.
2132                // This can lead to package info being null (b/36642664).
2133                if (info != null) {
2134                    mDexManager.notifyPackageInstalled(info, userId);
2135                }
2136            }
2137        }
2138
2139        // If someone is watching installs - notify them
2140        if (installObserver != null) {
2141            try {
2142                Bundle extras = extrasForInstallResult(res);
2143                installObserver.onPackageInstalled(res.name, res.returnCode,
2144                        res.returnMsg, extras);
2145            } catch (RemoteException e) {
2146                Slog.i(TAG, "Observer no longer exists.");
2147            }
2148        }
2149    }
2150
2151    private StorageEventListener mStorageListener = new StorageEventListener() {
2152        @Override
2153        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2154            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2155                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2156                    final String volumeUuid = vol.getFsUuid();
2157
2158                    // Clean up any users or apps that were removed or recreated
2159                    // while this volume was missing
2160                    sUserManager.reconcileUsers(volumeUuid);
2161                    reconcileApps(volumeUuid);
2162
2163                    // Clean up any install sessions that expired or were
2164                    // cancelled while this volume was missing
2165                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2166
2167                    loadPrivatePackages(vol);
2168
2169                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2170                    unloadPrivatePackages(vol);
2171                }
2172            }
2173        }
2174
2175        @Override
2176        public void onVolumeForgotten(String fsUuid) {
2177            if (TextUtils.isEmpty(fsUuid)) {
2178                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2179                return;
2180            }
2181
2182            // Remove any apps installed on the forgotten volume
2183            synchronized (mPackages) {
2184                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2185                for (PackageSetting ps : packages) {
2186                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2187                    deletePackageVersioned(new VersionedPackage(ps.name,
2188                            PackageManager.VERSION_CODE_HIGHEST),
2189                            new LegacyPackageDeleteObserver(null).getBinder(),
2190                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2191                    // Try very hard to release any references to this package
2192                    // so we don't risk the system server being killed due to
2193                    // open FDs
2194                    AttributeCache.instance().removePackage(ps.name);
2195                }
2196
2197                mSettings.onVolumeForgotten(fsUuid);
2198                mSettings.writeLPr();
2199            }
2200        }
2201    };
2202
2203    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2204        Bundle extras = null;
2205        switch (res.returnCode) {
2206            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2207                extras = new Bundle();
2208                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2209                        res.origPermission);
2210                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2211                        res.origPackage);
2212                break;
2213            }
2214            case PackageManager.INSTALL_SUCCEEDED: {
2215                extras = new Bundle();
2216                extras.putBoolean(Intent.EXTRA_REPLACING,
2217                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2218                break;
2219            }
2220        }
2221        return extras;
2222    }
2223
2224    void scheduleWriteSettingsLocked() {
2225        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2226            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2227        }
2228    }
2229
2230    void scheduleWritePackageListLocked(int userId) {
2231        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2232            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2233            msg.arg1 = userId;
2234            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2235        }
2236    }
2237
2238    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2239        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2240        scheduleWritePackageRestrictionsLocked(userId);
2241    }
2242
2243    void scheduleWritePackageRestrictionsLocked(int userId) {
2244        final int[] userIds = (userId == UserHandle.USER_ALL)
2245                ? sUserManager.getUserIds() : new int[]{userId};
2246        for (int nextUserId : userIds) {
2247            if (!sUserManager.exists(nextUserId)) return;
2248            mDirtyUsers.add(nextUserId);
2249            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2250                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2251            }
2252        }
2253    }
2254
2255    public static PackageManagerService main(Context context, Installer installer,
2256            boolean factoryTest, boolean onlyCore) {
2257        // Self-check for initial settings.
2258        PackageManagerServiceCompilerMapping.checkProperties();
2259
2260        PackageManagerService m = new PackageManagerService(context, installer,
2261                factoryTest, onlyCore);
2262        m.enableSystemUserPackages();
2263        ServiceManager.addService("package", m);
2264        final PackageManagerNative pmn = m.new PackageManagerNative();
2265        ServiceManager.addService("package_native", pmn);
2266        return m;
2267    }
2268
2269    private void enableSystemUserPackages() {
2270        if (!UserManager.isSplitSystemUser()) {
2271            return;
2272        }
2273        // For system user, enable apps based on the following conditions:
2274        // - app is whitelisted or belong to one of these groups:
2275        //   -- system app which has no launcher icons
2276        //   -- system app which has INTERACT_ACROSS_USERS permission
2277        //   -- system IME app
2278        // - app is not in the blacklist
2279        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2280        Set<String> enableApps = new ArraySet<>();
2281        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2282                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2283                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2284        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2285        enableApps.addAll(wlApps);
2286        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2287                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2288        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2289        enableApps.removeAll(blApps);
2290        Log.i(TAG, "Applications installed for system user: " + enableApps);
2291        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2292                UserHandle.SYSTEM);
2293        final int allAppsSize = allAps.size();
2294        synchronized (mPackages) {
2295            for (int i = 0; i < allAppsSize; i++) {
2296                String pName = allAps.get(i);
2297                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2298                // Should not happen, but we shouldn't be failing if it does
2299                if (pkgSetting == null) {
2300                    continue;
2301                }
2302                boolean install = enableApps.contains(pName);
2303                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2304                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2305                            + " for system user");
2306                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2307                }
2308            }
2309            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2310        }
2311    }
2312
2313    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2314        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2315                Context.DISPLAY_SERVICE);
2316        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2317    }
2318
2319    /**
2320     * Requests that files preopted on a secondary system partition be copied to the data partition
2321     * if possible.  Note that the actual copying of the files is accomplished by init for security
2322     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2323     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2324     */
2325    private static void requestCopyPreoptedFiles() {
2326        final int WAIT_TIME_MS = 100;
2327        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2328        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2329            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2330            // We will wait for up to 100 seconds.
2331            final long timeStart = SystemClock.uptimeMillis();
2332            final long timeEnd = timeStart + 100 * 1000;
2333            long timeNow = timeStart;
2334            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2335                try {
2336                    Thread.sleep(WAIT_TIME_MS);
2337                } catch (InterruptedException e) {
2338                    // Do nothing
2339                }
2340                timeNow = SystemClock.uptimeMillis();
2341                if (timeNow > timeEnd) {
2342                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2343                    Slog.wtf(TAG, "cppreopt did not finish!");
2344                    break;
2345                }
2346            }
2347
2348            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2349        }
2350    }
2351
2352    public PackageManagerService(Context context, Installer installer,
2353            boolean factoryTest, boolean onlyCore) {
2354        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2355        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2356        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2357                SystemClock.uptimeMillis());
2358
2359        if (mSdkVersion <= 0) {
2360            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2361        }
2362
2363        mContext = context;
2364
2365        mFactoryTest = factoryTest;
2366        mOnlyCore = onlyCore;
2367        mMetrics = new DisplayMetrics();
2368        mInstaller = installer;
2369
2370        // Create sub-components that provide services / data. Order here is important.
2371        synchronized (mInstallLock) {
2372        synchronized (mPackages) {
2373            // Expose private service for system components to use.
2374            LocalServices.addService(
2375                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2376            sUserManager = new UserManagerService(context, this,
2377                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2378            mPermissionManager = PermissionManagerService.create(context,
2379                    new DefaultPermissionGrantedCallback() {
2380                        @Override
2381                        public void onDefaultRuntimePermissionsGranted(int userId) {
2382                            synchronized(mPackages) {
2383                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2384                            }
2385                        }
2386                    }, mPackages /*externalLock*/);
2387            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2388            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2389        }
2390        }
2391        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2392                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2393        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2394                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2395        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2396                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2397        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2398                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2399        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2400                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2401        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2402                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2403
2404        String separateProcesses = SystemProperties.get("debug.separate_processes");
2405        if (separateProcesses != null && separateProcesses.length() > 0) {
2406            if ("*".equals(separateProcesses)) {
2407                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2408                mSeparateProcesses = null;
2409                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2410            } else {
2411                mDefParseFlags = 0;
2412                mSeparateProcesses = separateProcesses.split(",");
2413                Slog.w(TAG, "Running with debug.separate_processes: "
2414                        + separateProcesses);
2415            }
2416        } else {
2417            mDefParseFlags = 0;
2418            mSeparateProcesses = null;
2419        }
2420
2421        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2422                "*dexopt*");
2423        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2424                installer, mInstallLock);
2425        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2426                dexManagerListener);
2427        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2428
2429        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2430                FgThread.get().getLooper());
2431
2432        getDefaultDisplayMetrics(context, mMetrics);
2433
2434        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2435        SystemConfig systemConfig = SystemConfig.getInstance();
2436        mAvailableFeatures = systemConfig.getAvailableFeatures();
2437        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2438
2439        mProtectedPackages = new ProtectedPackages(mContext);
2440
2441        synchronized (mInstallLock) {
2442        // writer
2443        synchronized (mPackages) {
2444            mHandlerThread = new ServiceThread(TAG,
2445                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2446            mHandlerThread.start();
2447            mHandler = new PackageHandler(mHandlerThread.getLooper());
2448            mProcessLoggingHandler = new ProcessLoggingHandler();
2449            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2450            mInstantAppRegistry = new InstantAppRegistry(this);
2451
2452            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2453            final int builtInLibCount = libConfig.size();
2454            for (int i = 0; i < builtInLibCount; i++) {
2455                String name = libConfig.keyAt(i);
2456                String path = libConfig.valueAt(i);
2457                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2458                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2459            }
2460
2461            SELinuxMMAC.readInstallPolicy();
2462
2463            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2464            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2465            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2466
2467            // Clean up orphaned packages for which the code path doesn't exist
2468            // and they are an update to a system app - caused by bug/32321269
2469            final int packageSettingCount = mSettings.mPackages.size();
2470            for (int i = packageSettingCount - 1; i >= 0; i--) {
2471                PackageSetting ps = mSettings.mPackages.valueAt(i);
2472                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2473                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2474                    mSettings.mPackages.removeAt(i);
2475                    mSettings.enableSystemPackageLPw(ps.name);
2476                }
2477            }
2478
2479            if (mFirstBoot) {
2480                requestCopyPreoptedFiles();
2481            }
2482
2483            String customResolverActivity = Resources.getSystem().getString(
2484                    R.string.config_customResolverActivity);
2485            if (TextUtils.isEmpty(customResolverActivity)) {
2486                customResolverActivity = null;
2487            } else {
2488                mCustomResolverComponentName = ComponentName.unflattenFromString(
2489                        customResolverActivity);
2490            }
2491
2492            long startTime = SystemClock.uptimeMillis();
2493
2494            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2495                    startTime);
2496
2497            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2498            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2499
2500            if (bootClassPath == null) {
2501                Slog.w(TAG, "No BOOTCLASSPATH found!");
2502            }
2503
2504            if (systemServerClassPath == null) {
2505                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2506            }
2507
2508            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2509
2510            final VersionInfo ver = mSettings.getInternalVersion();
2511            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2512            if (mIsUpgrade) {
2513                logCriticalInfo(Log.INFO,
2514                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2515            }
2516
2517            // when upgrading from pre-M, promote system app permissions from install to runtime
2518            mPromoteSystemApps =
2519                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2520
2521            // When upgrading from pre-N, we need to handle package extraction like first boot,
2522            // as there is no profiling data available.
2523            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2524
2525            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2526
2527            // save off the names of pre-existing system packages prior to scanning; we don't
2528            // want to automatically grant runtime permissions for new system apps
2529            if (mPromoteSystemApps) {
2530                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2531                while (pkgSettingIter.hasNext()) {
2532                    PackageSetting ps = pkgSettingIter.next();
2533                    if (isSystemApp(ps)) {
2534                        mExistingSystemPackages.add(ps.name);
2535                    }
2536                }
2537            }
2538
2539            mCacheDir = preparePackageParserCache(mIsUpgrade);
2540
2541            // Set flag to monitor and not change apk file paths when
2542            // scanning install directories.
2543            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2544
2545            if (mIsUpgrade || mFirstBoot) {
2546                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2547            }
2548
2549            // Collect vendor overlay packages. (Do this before scanning any apps.)
2550            // For security and version matching reason, only consider
2551            // overlay packages if they reside in the right directory.
2552            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2553                    mDefParseFlags
2554                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2555                    scanFlags
2556                    | SCAN_AS_SYSTEM
2557                    | SCAN_TRUSTED_OVERLAY,
2558                    0);
2559
2560            mParallelPackageParserCallback.findStaticOverlayPackages();
2561
2562            // Find base frameworks (resource packages without code).
2563            scanDirTracedLI(frameworkDir,
2564                    mDefParseFlags
2565                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2566                    scanFlags
2567                    | SCAN_NO_DEX
2568                    | SCAN_AS_SYSTEM
2569                    | SCAN_AS_PRIVILEGED,
2570                    0);
2571
2572            // Collected privileged system packages.
2573            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2574            scanDirTracedLI(privilegedAppDir,
2575                    mDefParseFlags
2576                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2577                    scanFlags
2578                    | SCAN_AS_SYSTEM
2579                    | SCAN_AS_PRIVILEGED,
2580                    0);
2581
2582            // Collect ordinary system packages.
2583            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2584            scanDirTracedLI(systemAppDir,
2585                    mDefParseFlags
2586                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2587                    scanFlags
2588                    | SCAN_AS_SYSTEM,
2589                    0);
2590
2591            // Collected privileged vendor packages.
2592                File privilegedVendorAppDir = new File(Environment.getVendorDirectory(),
2593                        "priv-app");
2594            try {
2595                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2596            } catch (IOException e) {
2597                // failed to look up canonical path, continue with original one
2598            }
2599            scanDirTracedLI(privilegedVendorAppDir,
2600                    mDefParseFlags
2601                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2602                    scanFlags
2603                    | SCAN_AS_SYSTEM
2604                    | SCAN_AS_VENDOR
2605                    | SCAN_AS_PRIVILEGED,
2606                    0);
2607
2608            // Collect ordinary vendor packages.
2609            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2610            try {
2611                vendorAppDir = vendorAppDir.getCanonicalFile();
2612            } catch (IOException e) {
2613                // failed to look up canonical path, continue with original one
2614            }
2615            scanDirTracedLI(vendorAppDir,
2616                    mDefParseFlags
2617                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2618                    scanFlags
2619                    | SCAN_AS_SYSTEM
2620                    | SCAN_AS_VENDOR,
2621                    0);
2622
2623            // Collect all OEM packages.
2624            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2625            scanDirTracedLI(oemAppDir,
2626                    mDefParseFlags
2627                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2628                    scanFlags
2629                    | SCAN_AS_SYSTEM
2630                    | SCAN_AS_OEM,
2631                    0);
2632
2633            // Prune any system packages that no longer exist.
2634            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2635            // Stub packages must either be replaced with full versions in the /data
2636            // partition or be disabled.
2637            final List<String> stubSystemApps = new ArrayList<>();
2638            if (!mOnlyCore) {
2639                // do this first before mucking with mPackages for the "expecting better" case
2640                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2641                while (pkgIterator.hasNext()) {
2642                    final PackageParser.Package pkg = pkgIterator.next();
2643                    if (pkg.isStub) {
2644                        stubSystemApps.add(pkg.packageName);
2645                    }
2646                }
2647
2648                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2649                while (psit.hasNext()) {
2650                    PackageSetting ps = psit.next();
2651
2652                    /*
2653                     * If this is not a system app, it can't be a
2654                     * disable system app.
2655                     */
2656                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2657                        continue;
2658                    }
2659
2660                    /*
2661                     * If the package is scanned, it's not erased.
2662                     */
2663                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2664                    if (scannedPkg != null) {
2665                        /*
2666                         * If the system app is both scanned and in the
2667                         * disabled packages list, then it must have been
2668                         * added via OTA. Remove it from the currently
2669                         * scanned package so the previously user-installed
2670                         * application can be scanned.
2671                         */
2672                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2673                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2674                                    + ps.name + "; removing system app.  Last known codePath="
2675                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2676                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2677                                    + scannedPkg.getLongVersionCode());
2678                            removePackageLI(scannedPkg, true);
2679                            mExpectingBetter.put(ps.name, ps.codePath);
2680                        }
2681
2682                        continue;
2683                    }
2684
2685                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2686                        psit.remove();
2687                        logCriticalInfo(Log.WARN, "System package " + ps.name
2688                                + " no longer exists; it's data will be wiped");
2689                        // Actual deletion of code and data will be handled by later
2690                        // reconciliation step
2691                    } else {
2692                        // we still have a disabled system package, but, it still might have
2693                        // been removed. check the code path still exists and check there's
2694                        // still a package. the latter can happen if an OTA keeps the same
2695                        // code path, but, changes the package name.
2696                        final PackageSetting disabledPs =
2697                                mSettings.getDisabledSystemPkgLPr(ps.name);
2698                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2699                                || disabledPs.pkg == null) {
2700                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2701                        }
2702                    }
2703                }
2704            }
2705
2706            //look for any incomplete package installations
2707            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2708            for (int i = 0; i < deletePkgsList.size(); i++) {
2709                // Actual deletion of code and data will be handled by later
2710                // reconciliation step
2711                final String packageName = deletePkgsList.get(i).name;
2712                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2713                synchronized (mPackages) {
2714                    mSettings.removePackageLPw(packageName);
2715                }
2716            }
2717
2718            //delete tmp files
2719            deleteTempPackageFiles();
2720
2721            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2722
2723            // Remove any shared userIDs that have no associated packages
2724            mSettings.pruneSharedUsersLPw();
2725            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2726            final int systemPackagesCount = mPackages.size();
2727            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2728                    + " ms, packageCount: " + systemPackagesCount
2729                    + " , timePerPackage: "
2730                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2731                    + " , cached: " + cachedSystemApps);
2732            if (mIsUpgrade && systemPackagesCount > 0) {
2733                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2734                        ((int) systemScanTime) / systemPackagesCount);
2735            }
2736            if (!mOnlyCore) {
2737                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2738                        SystemClock.uptimeMillis());
2739                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2740
2741                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2742                        | PackageParser.PARSE_FORWARD_LOCK,
2743                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2744
2745                // Remove disable package settings for updated system apps that were
2746                // removed via an OTA. If the update is no longer present, remove the
2747                // app completely. Otherwise, revoke their system privileges.
2748                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2749                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2750                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2751                    final String msg;
2752                    if (deletedPkg == null) {
2753                        // should have found an update, but, we didn't; remove everything
2754                        msg = "Updated system package " + deletedAppName
2755                                + " no longer exists; removing its data";
2756                        // Actual deletion of code and data will be handled by later
2757                        // reconciliation step
2758                    } else {
2759                        // found an update; revoke system privileges
2760                        msg = "Updated system package + " + deletedAppName
2761                                + " no longer exists; revoking system privileges";
2762
2763                        // Don't do anything if a stub is removed from the system image. If
2764                        // we were to remove the uncompressed version from the /data partition,
2765                        // this is where it'd be done.
2766
2767                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2768                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2769                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2770                    }
2771                    logCriticalInfo(Log.WARN, msg);
2772                }
2773
2774                /*
2775                 * Make sure all system apps that we expected to appear on
2776                 * the userdata partition actually showed up. If they never
2777                 * appeared, crawl back and revive the system version.
2778                 */
2779                for (int i = 0; i < mExpectingBetter.size(); i++) {
2780                    final String packageName = mExpectingBetter.keyAt(i);
2781                    if (!mPackages.containsKey(packageName)) {
2782                        final File scanFile = mExpectingBetter.valueAt(i);
2783
2784                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2785                                + " but never showed up; reverting to system");
2786
2787                        final @ParseFlags int reparseFlags;
2788                        final @ScanFlags int rescanFlags;
2789                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2790                            reparseFlags =
2791                                    mDefParseFlags |
2792                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2793                            rescanFlags =
2794                                    scanFlags
2795                                    | SCAN_AS_SYSTEM
2796                                    | SCAN_AS_PRIVILEGED;
2797                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2798                            reparseFlags =
2799                                    mDefParseFlags |
2800                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2801                            rescanFlags =
2802                                    scanFlags
2803                                    | SCAN_AS_SYSTEM;
2804                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2805                            reparseFlags =
2806                                    mDefParseFlags |
2807                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2808                            rescanFlags =
2809                                    scanFlags
2810                                    | SCAN_AS_SYSTEM
2811                                    | SCAN_AS_VENDOR
2812                                    | SCAN_AS_PRIVILEGED;
2813                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2814                            reparseFlags =
2815                                    mDefParseFlags |
2816                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2817                            rescanFlags =
2818                                    scanFlags
2819                                    | SCAN_AS_SYSTEM
2820                                    | SCAN_AS_VENDOR;
2821                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2822                            reparseFlags =
2823                                    mDefParseFlags |
2824                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2825                            rescanFlags =
2826                                    scanFlags
2827                                    | SCAN_AS_SYSTEM
2828                                    | SCAN_AS_OEM;
2829                        } else {
2830                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2831                            continue;
2832                        }
2833
2834                        mSettings.enableSystemPackageLPw(packageName);
2835
2836                        try {
2837                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2838                        } catch (PackageManagerException e) {
2839                            Slog.e(TAG, "Failed to parse original system package: "
2840                                    + e.getMessage());
2841                        }
2842                    }
2843                }
2844
2845                // Uncompress and install any stubbed system applications.
2846                // This must be done last to ensure all stubs are replaced or disabled.
2847                decompressSystemApplications(stubSystemApps, scanFlags);
2848
2849                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2850                                - cachedSystemApps;
2851
2852                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2853                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2854                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2855                        + " ms, packageCount: " + dataPackagesCount
2856                        + " , timePerPackage: "
2857                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2858                        + " , cached: " + cachedNonSystemApps);
2859                if (mIsUpgrade && dataPackagesCount > 0) {
2860                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2861                            ((int) dataScanTime) / dataPackagesCount);
2862                }
2863            }
2864            mExpectingBetter.clear();
2865
2866            // Resolve the storage manager.
2867            mStorageManagerPackage = getStorageManagerPackageName();
2868
2869            // Resolve protected action filters. Only the setup wizard is allowed to
2870            // have a high priority filter for these actions.
2871            mSetupWizardPackage = getSetupWizardPackageName();
2872            if (mProtectedFilters.size() > 0) {
2873                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2874                    Slog.i(TAG, "No setup wizard;"
2875                        + " All protected intents capped to priority 0");
2876                }
2877                for (ActivityIntentInfo filter : mProtectedFilters) {
2878                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2879                        if (DEBUG_FILTERS) {
2880                            Slog.i(TAG, "Found setup wizard;"
2881                                + " allow priority " + filter.getPriority() + ";"
2882                                + " package: " + filter.activity.info.packageName
2883                                + " activity: " + filter.activity.className
2884                                + " priority: " + filter.getPriority());
2885                        }
2886                        // skip setup wizard; allow it to keep the high priority filter
2887                        continue;
2888                    }
2889                    if (DEBUG_FILTERS) {
2890                        Slog.i(TAG, "Protected action; cap priority to 0;"
2891                                + " package: " + filter.activity.info.packageName
2892                                + " activity: " + filter.activity.className
2893                                + " origPrio: " + filter.getPriority());
2894                    }
2895                    filter.setPriority(0);
2896                }
2897            }
2898            mDeferProtectedFilters = false;
2899            mProtectedFilters.clear();
2900
2901            // Now that we know all of the shared libraries, update all clients to have
2902            // the correct library paths.
2903            updateAllSharedLibrariesLPw(null);
2904
2905            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2906                // NOTE: We ignore potential failures here during a system scan (like
2907                // the rest of the commands above) because there's precious little we
2908                // can do about it. A settings error is reported, though.
2909                final List<String> changedAbiCodePath =
2910                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2911                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
2912                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
2913                        final String codePathString = changedAbiCodePath.get(i);
2914                        try {
2915                            mInstaller.rmdex(codePathString,
2916                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
2917                        } catch (InstallerException ignored) {
2918                        }
2919                    }
2920                }
2921            }
2922
2923            // Now that we know all the packages we are keeping,
2924            // read and update their last usage times.
2925            mPackageUsage.read(mPackages);
2926            mCompilerStats.read();
2927
2928            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2929                    SystemClock.uptimeMillis());
2930            Slog.i(TAG, "Time to scan packages: "
2931                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2932                    + " seconds");
2933
2934            // If the platform SDK has changed since the last time we booted,
2935            // we need to re-grant app permission to catch any new ones that
2936            // appear.  This is really a hack, and means that apps can in some
2937            // cases get permissions that the user didn't initially explicitly
2938            // allow...  it would be nice to have some better way to handle
2939            // this situation.
2940            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
2941            if (sdkUpdated) {
2942                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2943                        + mSdkVersion + "; regranting permissions for internal storage");
2944            }
2945            mPermissionManager.updateAllPermissions(
2946                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
2947                    mPermissionCallback);
2948            ver.sdkVersion = mSdkVersion;
2949
2950            // If this is the first boot or an update from pre-M, and it is a normal
2951            // boot, then we need to initialize the default preferred apps across
2952            // all defined users.
2953            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2954                for (UserInfo user : sUserManager.getUsers(true)) {
2955                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2956                    applyFactoryDefaultBrowserLPw(user.id);
2957                    primeDomainVerificationsLPw(user.id);
2958                }
2959            }
2960
2961            // Prepare storage for system user really early during boot,
2962            // since core system apps like SettingsProvider and SystemUI
2963            // can't wait for user to start
2964            final int storageFlags;
2965            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2966                storageFlags = StorageManager.FLAG_STORAGE_DE;
2967            } else {
2968                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2969            }
2970            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2971                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2972                    true /* onlyCoreApps */);
2973            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2974                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2975                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2976                traceLog.traceBegin("AppDataFixup");
2977                try {
2978                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2979                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2980                } catch (InstallerException e) {
2981                    Slog.w(TAG, "Trouble fixing GIDs", e);
2982                }
2983                traceLog.traceEnd();
2984
2985                traceLog.traceBegin("AppDataPrepare");
2986                if (deferPackages == null || deferPackages.isEmpty()) {
2987                    return;
2988                }
2989                int count = 0;
2990                for (String pkgName : deferPackages) {
2991                    PackageParser.Package pkg = null;
2992                    synchronized (mPackages) {
2993                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2994                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2995                            pkg = ps.pkg;
2996                        }
2997                    }
2998                    if (pkg != null) {
2999                        synchronized (mInstallLock) {
3000                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3001                                    true /* maybeMigrateAppData */);
3002                        }
3003                        count++;
3004                    }
3005                }
3006                traceLog.traceEnd();
3007                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3008            }, "prepareAppData");
3009
3010            // If this is first boot after an OTA, and a normal boot, then
3011            // we need to clear code cache directories.
3012            // Note that we do *not* clear the application profiles. These remain valid
3013            // across OTAs and are used to drive profile verification (post OTA) and
3014            // profile compilation (without waiting to collect a fresh set of profiles).
3015            if (mIsUpgrade && !onlyCore) {
3016                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3017                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3018                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3019                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3020                        // No apps are running this early, so no need to freeze
3021                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3022                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3023                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3024                    }
3025                }
3026                ver.fingerprint = Build.FINGERPRINT;
3027            }
3028
3029            checkDefaultBrowser();
3030
3031            // clear only after permissions and other defaults have been updated
3032            mExistingSystemPackages.clear();
3033            mPromoteSystemApps = false;
3034
3035            // All the changes are done during package scanning.
3036            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3037
3038            // can downgrade to reader
3039            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3040            mSettings.writeLPr();
3041            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3042            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3043                    SystemClock.uptimeMillis());
3044
3045            if (!mOnlyCore) {
3046                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3047                mRequiredInstallerPackage = getRequiredInstallerLPr();
3048                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3049                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3050                if (mIntentFilterVerifierComponent != null) {
3051                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3052                            mIntentFilterVerifierComponent);
3053                } else {
3054                    mIntentFilterVerifier = null;
3055                }
3056                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3057                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3058                        SharedLibraryInfo.VERSION_UNDEFINED);
3059                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3060                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3061                        SharedLibraryInfo.VERSION_UNDEFINED);
3062            } else {
3063                mRequiredVerifierPackage = null;
3064                mRequiredInstallerPackage = null;
3065                mRequiredUninstallerPackage = null;
3066                mIntentFilterVerifierComponent = null;
3067                mIntentFilterVerifier = null;
3068                mServicesSystemSharedLibraryPackageName = null;
3069                mSharedSystemSharedLibraryPackageName = null;
3070            }
3071
3072            mInstallerService = new PackageInstallerService(context, this);
3073            mArtManagerService = new ArtManagerService(this, mInstaller, mInstallLock);
3074            final Pair<ComponentName, String> instantAppResolverComponent =
3075                    getInstantAppResolverLPr();
3076            if (instantAppResolverComponent != null) {
3077                if (DEBUG_EPHEMERAL) {
3078                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3079                }
3080                mInstantAppResolverConnection = new EphemeralResolverConnection(
3081                        mContext, instantAppResolverComponent.first,
3082                        instantAppResolverComponent.second);
3083                mInstantAppResolverSettingsComponent =
3084                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3085            } else {
3086                mInstantAppResolverConnection = null;
3087                mInstantAppResolverSettingsComponent = null;
3088            }
3089            updateInstantAppInstallerLocked(null);
3090
3091            // Read and update the usage of dex files.
3092            // Do this at the end of PM init so that all the packages have their
3093            // data directory reconciled.
3094            // At this point we know the code paths of the packages, so we can validate
3095            // the disk file and build the internal cache.
3096            // The usage file is expected to be small so loading and verifying it
3097            // should take a fairly small time compare to the other activities (e.g. package
3098            // scanning).
3099            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3100            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3101            for (int userId : currentUserIds) {
3102                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3103            }
3104            mDexManager.load(userPackages);
3105            if (mIsUpgrade) {
3106                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3107                        (int) (SystemClock.uptimeMillis() - startTime));
3108            }
3109        } // synchronized (mPackages)
3110        } // synchronized (mInstallLock)
3111
3112        // Now after opening every single application zip, make sure they
3113        // are all flushed.  Not really needed, but keeps things nice and
3114        // tidy.
3115        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3116        Runtime.getRuntime().gc();
3117        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3118
3119        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3120        FallbackCategoryProvider.loadFallbacks();
3121        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3122
3123        // The initial scanning above does many calls into installd while
3124        // holding the mPackages lock, but we're mostly interested in yelling
3125        // once we have a booted system.
3126        mInstaller.setWarnIfHeld(mPackages);
3127
3128        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3129    }
3130
3131    /**
3132     * Uncompress and install stub applications.
3133     * <p>In order to save space on the system partition, some applications are shipped in a
3134     * compressed form. In addition the compressed bits for the full application, the
3135     * system image contains a tiny stub comprised of only the Android manifest.
3136     * <p>During the first boot, attempt to uncompress and install the full application. If
3137     * the application can't be installed for any reason, disable the stub and prevent
3138     * uncompressing the full application during future boots.
3139     * <p>In order to forcefully attempt an installation of a full application, go to app
3140     * settings and enable the application.
3141     */
3142    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3143        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3144            final String pkgName = stubSystemApps.get(i);
3145            // skip if the system package is already disabled
3146            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3147                stubSystemApps.remove(i);
3148                continue;
3149            }
3150            // skip if the package isn't installed (?!); this should never happen
3151            final PackageParser.Package pkg = mPackages.get(pkgName);
3152            if (pkg == null) {
3153                stubSystemApps.remove(i);
3154                continue;
3155            }
3156            // skip if the package has been disabled by the user
3157            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3158            if (ps != null) {
3159                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3160                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3161                    stubSystemApps.remove(i);
3162                    continue;
3163                }
3164            }
3165
3166            if (DEBUG_COMPRESSION) {
3167                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3168            }
3169
3170            // uncompress the binary to its eventual destination on /data
3171            final File scanFile = decompressPackage(pkg);
3172            if (scanFile == null) {
3173                continue;
3174            }
3175
3176            // install the package to replace the stub on /system
3177            try {
3178                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3179                removePackageLI(pkg, true /*chatty*/);
3180                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3181                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3182                        UserHandle.USER_SYSTEM, "android");
3183                stubSystemApps.remove(i);
3184                continue;
3185            } catch (PackageManagerException e) {
3186                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3187            }
3188
3189            // any failed attempt to install the package will be cleaned up later
3190        }
3191
3192        // disable any stub still left; these failed to install the full application
3193        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3194            final String pkgName = stubSystemApps.get(i);
3195            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3196            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3197                    UserHandle.USER_SYSTEM, "android");
3198            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3199        }
3200    }
3201
3202    /**
3203     * Decompresses the given package on the system image onto
3204     * the /data partition.
3205     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3206     */
3207    private File decompressPackage(PackageParser.Package pkg) {
3208        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3209        if (compressedFiles == null || compressedFiles.length == 0) {
3210            if (DEBUG_COMPRESSION) {
3211                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3212            }
3213            return null;
3214        }
3215        final File dstCodePath =
3216                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3217        int ret = PackageManager.INSTALL_SUCCEEDED;
3218        try {
3219            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3220            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3221            for (File srcFile : compressedFiles) {
3222                final String srcFileName = srcFile.getName();
3223                final String dstFileName = srcFileName.substring(
3224                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3225                final File dstFile = new File(dstCodePath, dstFileName);
3226                ret = decompressFile(srcFile, dstFile);
3227                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3228                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3229                            + "; pkg: " + pkg.packageName
3230                            + ", file: " + dstFileName);
3231                    break;
3232                }
3233            }
3234        } catch (ErrnoException e) {
3235            logCriticalInfo(Log.ERROR, "Failed to decompress"
3236                    + "; pkg: " + pkg.packageName
3237                    + ", err: " + e.errno);
3238        }
3239        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3240            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3241            NativeLibraryHelper.Handle handle = null;
3242            try {
3243                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3244                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3245                        null /*abiOverride*/);
3246            } catch (IOException e) {
3247                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3248                        + "; pkg: " + pkg.packageName);
3249                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3250            } finally {
3251                IoUtils.closeQuietly(handle);
3252            }
3253        }
3254        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3255            if (dstCodePath == null || !dstCodePath.exists()) {
3256                return null;
3257            }
3258            removeCodePathLI(dstCodePath);
3259            return null;
3260        }
3261
3262        return dstCodePath;
3263    }
3264
3265    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3266        // we're only interested in updating the installer appliction when 1) it's not
3267        // already set or 2) the modified package is the installer
3268        if (mInstantAppInstallerActivity != null
3269                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3270                        .equals(modifiedPackage)) {
3271            return;
3272        }
3273        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3274    }
3275
3276    private static File preparePackageParserCache(boolean isUpgrade) {
3277        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3278            return null;
3279        }
3280
3281        // Disable package parsing on eng builds to allow for faster incremental development.
3282        if (Build.IS_ENG) {
3283            return null;
3284        }
3285
3286        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3287            Slog.i(TAG, "Disabling package parser cache due to system property.");
3288            return null;
3289        }
3290
3291        // The base directory for the package parser cache lives under /data/system/.
3292        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3293                "package_cache");
3294        if (cacheBaseDir == null) {
3295            return null;
3296        }
3297
3298        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3299        // This also serves to "GC" unused entries when the package cache version changes (which
3300        // can only happen during upgrades).
3301        if (isUpgrade) {
3302            FileUtils.deleteContents(cacheBaseDir);
3303        }
3304
3305
3306        // Return the versioned package cache directory. This is something like
3307        // "/data/system/package_cache/1"
3308        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3309
3310        // The following is a workaround to aid development on non-numbered userdebug
3311        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3312        // the system partition is newer.
3313        //
3314        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3315        // that starts with "eng." to signify that this is an engineering build and not
3316        // destined for release.
3317        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3318            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3319
3320            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3321            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3322            // in general and should not be used for production changes. In this specific case,
3323            // we know that they will work.
3324            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3325            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3326                FileUtils.deleteContents(cacheBaseDir);
3327                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3328            }
3329        }
3330
3331        return cacheDir;
3332    }
3333
3334    @Override
3335    public boolean isFirstBoot() {
3336        // allow instant applications
3337        return mFirstBoot;
3338    }
3339
3340    @Override
3341    public boolean isOnlyCoreApps() {
3342        // allow instant applications
3343        return mOnlyCore;
3344    }
3345
3346    @Override
3347    public boolean isUpgrade() {
3348        // allow instant applications
3349        // The system property allows testing ota flow when upgraded to the same image.
3350        return mIsUpgrade || SystemProperties.getBoolean(
3351                "persist.pm.mock-upgrade", false /* default */);
3352    }
3353
3354    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3355        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3356
3357        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3358                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3359                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3360        if (matches.size() == 1) {
3361            return matches.get(0).getComponentInfo().packageName;
3362        } else if (matches.size() == 0) {
3363            Log.e(TAG, "There should probably be a verifier, but, none were found");
3364            return null;
3365        }
3366        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3367    }
3368
3369    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3370        synchronized (mPackages) {
3371            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3372            if (libraryEntry == null) {
3373                throw new IllegalStateException("Missing required shared library:" + name);
3374            }
3375            return libraryEntry.apk;
3376        }
3377    }
3378
3379    private @NonNull String getRequiredInstallerLPr() {
3380        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3381        intent.addCategory(Intent.CATEGORY_DEFAULT);
3382        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3383
3384        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3385                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3386                UserHandle.USER_SYSTEM);
3387        if (matches.size() == 1) {
3388            ResolveInfo resolveInfo = matches.get(0);
3389            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3390                throw new RuntimeException("The installer must be a privileged app");
3391            }
3392            return matches.get(0).getComponentInfo().packageName;
3393        } else {
3394            throw new RuntimeException("There must be exactly one installer; found " + matches);
3395        }
3396    }
3397
3398    private @NonNull String getRequiredUninstallerLPr() {
3399        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3400        intent.addCategory(Intent.CATEGORY_DEFAULT);
3401        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3402
3403        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3404                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3405                UserHandle.USER_SYSTEM);
3406        if (resolveInfo == null ||
3407                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3408            throw new RuntimeException("There must be exactly one uninstaller; found "
3409                    + resolveInfo);
3410        }
3411        return resolveInfo.getComponentInfo().packageName;
3412    }
3413
3414    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3415        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3416
3417        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3418                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3419                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3420        ResolveInfo best = null;
3421        final int N = matches.size();
3422        for (int i = 0; i < N; i++) {
3423            final ResolveInfo cur = matches.get(i);
3424            final String packageName = cur.getComponentInfo().packageName;
3425            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3426                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3427                continue;
3428            }
3429
3430            if (best == null || cur.priority > best.priority) {
3431                best = cur;
3432            }
3433        }
3434
3435        if (best != null) {
3436            return best.getComponentInfo().getComponentName();
3437        }
3438        Slog.w(TAG, "Intent filter verifier not found");
3439        return null;
3440    }
3441
3442    @Override
3443    public @Nullable ComponentName getInstantAppResolverComponent() {
3444        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3445            return null;
3446        }
3447        synchronized (mPackages) {
3448            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3449            if (instantAppResolver == null) {
3450                return null;
3451            }
3452            return instantAppResolver.first;
3453        }
3454    }
3455
3456    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3457        final String[] packageArray =
3458                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3459        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3460            if (DEBUG_EPHEMERAL) {
3461                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3462            }
3463            return null;
3464        }
3465
3466        final int callingUid = Binder.getCallingUid();
3467        final int resolveFlags =
3468                MATCH_DIRECT_BOOT_AWARE
3469                | MATCH_DIRECT_BOOT_UNAWARE
3470                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3471        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3472        final Intent resolverIntent = new Intent(actionName);
3473        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3474                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3475        // temporarily look for the old action
3476        if (resolvers.size() == 0) {
3477            if (DEBUG_EPHEMERAL) {
3478                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3479            }
3480            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3481            resolverIntent.setAction(actionName);
3482            resolvers = queryIntentServicesInternal(resolverIntent, null,
3483                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3484        }
3485        final int N = resolvers.size();
3486        if (N == 0) {
3487            if (DEBUG_EPHEMERAL) {
3488                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3489            }
3490            return null;
3491        }
3492
3493        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3494        for (int i = 0; i < N; i++) {
3495            final ResolveInfo info = resolvers.get(i);
3496
3497            if (info.serviceInfo == null) {
3498                continue;
3499            }
3500
3501            final String packageName = info.serviceInfo.packageName;
3502            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3503                if (DEBUG_EPHEMERAL) {
3504                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3505                            + " pkg: " + packageName + ", info:" + info);
3506                }
3507                continue;
3508            }
3509
3510            if (DEBUG_EPHEMERAL) {
3511                Slog.v(TAG, "Ephemeral resolver found;"
3512                        + " pkg: " + packageName + ", info:" + info);
3513            }
3514            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3515        }
3516        if (DEBUG_EPHEMERAL) {
3517            Slog.v(TAG, "Ephemeral resolver NOT found");
3518        }
3519        return null;
3520    }
3521
3522    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3523        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3524        intent.addCategory(Intent.CATEGORY_DEFAULT);
3525        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3526
3527        final int resolveFlags =
3528                MATCH_DIRECT_BOOT_AWARE
3529                | MATCH_DIRECT_BOOT_UNAWARE
3530                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3531        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3532                resolveFlags, UserHandle.USER_SYSTEM);
3533        // temporarily look for the old action
3534        if (matches.isEmpty()) {
3535            if (DEBUG_EPHEMERAL) {
3536                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3537            }
3538            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3539            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3540                    resolveFlags, UserHandle.USER_SYSTEM);
3541        }
3542        Iterator<ResolveInfo> iter = matches.iterator();
3543        while (iter.hasNext()) {
3544            final ResolveInfo rInfo = iter.next();
3545            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3546            if (ps != null) {
3547                final PermissionsState permissionsState = ps.getPermissionsState();
3548                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3549                    continue;
3550                }
3551            }
3552            iter.remove();
3553        }
3554        if (matches.size() == 0) {
3555            return null;
3556        } else if (matches.size() == 1) {
3557            return (ActivityInfo) matches.get(0).getComponentInfo();
3558        } else {
3559            throw new RuntimeException(
3560                    "There must be at most one ephemeral installer; found " + matches);
3561        }
3562    }
3563
3564    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3565            @NonNull ComponentName resolver) {
3566        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3567                .addCategory(Intent.CATEGORY_DEFAULT)
3568                .setPackage(resolver.getPackageName());
3569        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3570        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3571                UserHandle.USER_SYSTEM);
3572        // temporarily look for the old action
3573        if (matches.isEmpty()) {
3574            if (DEBUG_EPHEMERAL) {
3575                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3576            }
3577            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3578            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3579                    UserHandle.USER_SYSTEM);
3580        }
3581        if (matches.isEmpty()) {
3582            return null;
3583        }
3584        return matches.get(0).getComponentInfo().getComponentName();
3585    }
3586
3587    private void primeDomainVerificationsLPw(int userId) {
3588        if (DEBUG_DOMAIN_VERIFICATION) {
3589            Slog.d(TAG, "Priming domain verifications in user " + userId);
3590        }
3591
3592        SystemConfig systemConfig = SystemConfig.getInstance();
3593        ArraySet<String> packages = systemConfig.getLinkedApps();
3594
3595        for (String packageName : packages) {
3596            PackageParser.Package pkg = mPackages.get(packageName);
3597            if (pkg != null) {
3598                if (!pkg.isSystem()) {
3599                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3600                    continue;
3601                }
3602
3603                ArraySet<String> domains = null;
3604                for (PackageParser.Activity a : pkg.activities) {
3605                    for (ActivityIntentInfo filter : a.intents) {
3606                        if (hasValidDomains(filter)) {
3607                            if (domains == null) {
3608                                domains = new ArraySet<String>();
3609                            }
3610                            domains.addAll(filter.getHostsList());
3611                        }
3612                    }
3613                }
3614
3615                if (domains != null && domains.size() > 0) {
3616                    if (DEBUG_DOMAIN_VERIFICATION) {
3617                        Slog.v(TAG, "      + " + packageName);
3618                    }
3619                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3620                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3621                    // and then 'always' in the per-user state actually used for intent resolution.
3622                    final IntentFilterVerificationInfo ivi;
3623                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3624                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3625                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3626                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3627                } else {
3628                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3629                            + "' does not handle web links");
3630                }
3631            } else {
3632                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3633            }
3634        }
3635
3636        scheduleWritePackageRestrictionsLocked(userId);
3637        scheduleWriteSettingsLocked();
3638    }
3639
3640    private void applyFactoryDefaultBrowserLPw(int userId) {
3641        // The default browser app's package name is stored in a string resource,
3642        // with a product-specific overlay used for vendor customization.
3643        String browserPkg = mContext.getResources().getString(
3644                com.android.internal.R.string.default_browser);
3645        if (!TextUtils.isEmpty(browserPkg)) {
3646            // non-empty string => required to be a known package
3647            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3648            if (ps == null) {
3649                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3650                browserPkg = null;
3651            } else {
3652                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3653            }
3654        }
3655
3656        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3657        // default.  If there's more than one, just leave everything alone.
3658        if (browserPkg == null) {
3659            calculateDefaultBrowserLPw(userId);
3660        }
3661    }
3662
3663    private void calculateDefaultBrowserLPw(int userId) {
3664        List<String> allBrowsers = resolveAllBrowserApps(userId);
3665        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3666        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3667    }
3668
3669    private List<String> resolveAllBrowserApps(int userId) {
3670        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3671        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3672                PackageManager.MATCH_ALL, userId);
3673
3674        final int count = list.size();
3675        List<String> result = new ArrayList<String>(count);
3676        for (int i=0; i<count; i++) {
3677            ResolveInfo info = list.get(i);
3678            if (info.activityInfo == null
3679                    || !info.handleAllWebDataURI
3680                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3681                    || result.contains(info.activityInfo.packageName)) {
3682                continue;
3683            }
3684            result.add(info.activityInfo.packageName);
3685        }
3686
3687        return result;
3688    }
3689
3690    private boolean packageIsBrowser(String packageName, int userId) {
3691        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3692                PackageManager.MATCH_ALL, userId);
3693        final int N = list.size();
3694        for (int i = 0; i < N; i++) {
3695            ResolveInfo info = list.get(i);
3696            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3697                return true;
3698            }
3699        }
3700        return false;
3701    }
3702
3703    private void checkDefaultBrowser() {
3704        final int myUserId = UserHandle.myUserId();
3705        final String packageName = getDefaultBrowserPackageName(myUserId);
3706        if (packageName != null) {
3707            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3708            if (info == null) {
3709                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3710                synchronized (mPackages) {
3711                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3712                }
3713            }
3714        }
3715    }
3716
3717    @Override
3718    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3719            throws RemoteException {
3720        try {
3721            return super.onTransact(code, data, reply, flags);
3722        } catch (RuntimeException e) {
3723            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3724                Slog.wtf(TAG, "Package Manager Crash", e);
3725            }
3726            throw e;
3727        }
3728    }
3729
3730    static int[] appendInts(int[] cur, int[] add) {
3731        if (add == null) return cur;
3732        if (cur == null) return add;
3733        final int N = add.length;
3734        for (int i=0; i<N; i++) {
3735            cur = appendInt(cur, add[i]);
3736        }
3737        return cur;
3738    }
3739
3740    /**
3741     * Returns whether or not a full application can see an instant application.
3742     * <p>
3743     * Currently, there are three cases in which this can occur:
3744     * <ol>
3745     * <li>The calling application is a "special" process. Special processes
3746     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3747     * <li>The calling application has the permission
3748     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3749     * <li>The calling application is the default launcher on the
3750     *     system partition.</li>
3751     * </ol>
3752     */
3753    private boolean canViewInstantApps(int callingUid, int userId) {
3754        if (callingUid < Process.FIRST_APPLICATION_UID) {
3755            return true;
3756        }
3757        if (mContext.checkCallingOrSelfPermission(
3758                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3759            return true;
3760        }
3761        if (mContext.checkCallingOrSelfPermission(
3762                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3763            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3764            if (homeComponent != null
3765                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3766                return true;
3767            }
3768        }
3769        return false;
3770    }
3771
3772    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3773        if (!sUserManager.exists(userId)) return null;
3774        if (ps == null) {
3775            return null;
3776        }
3777        PackageParser.Package p = ps.pkg;
3778        if (p == null) {
3779            return null;
3780        }
3781        final int callingUid = Binder.getCallingUid();
3782        // Filter out ephemeral app metadata:
3783        //   * The system/shell/root can see metadata for any app
3784        //   * An installed app can see metadata for 1) other installed apps
3785        //     and 2) ephemeral apps that have explicitly interacted with it
3786        //   * Ephemeral apps can only see their own data and exposed installed apps
3787        //   * Holding a signature permission allows seeing instant apps
3788        if (filterAppAccessLPr(ps, callingUid, userId)) {
3789            return null;
3790        }
3791
3792        final PermissionsState permissionsState = ps.getPermissionsState();
3793
3794        // Compute GIDs only if requested
3795        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3796                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3797        // Compute granted permissions only if package has requested permissions
3798        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3799                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3800        final PackageUserState state = ps.readUserState(userId);
3801
3802        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3803                && ps.isSystem()) {
3804            flags |= MATCH_ANY_USER;
3805        }
3806
3807        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3808                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3809
3810        if (packageInfo == null) {
3811            return null;
3812        }
3813
3814        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3815                resolveExternalPackageNameLPr(p);
3816
3817        return packageInfo;
3818    }
3819
3820    @Override
3821    public void checkPackageStartable(String packageName, int userId) {
3822        final int callingUid = Binder.getCallingUid();
3823        if (getInstantAppPackageName(callingUid) != null) {
3824            throw new SecurityException("Instant applications don't have access to this method");
3825        }
3826        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3827        synchronized (mPackages) {
3828            final PackageSetting ps = mSettings.mPackages.get(packageName);
3829            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3830                throw new SecurityException("Package " + packageName + " was not found!");
3831            }
3832
3833            if (!ps.getInstalled(userId)) {
3834                throw new SecurityException(
3835                        "Package " + packageName + " was not installed for user " + userId + "!");
3836            }
3837
3838            if (mSafeMode && !ps.isSystem()) {
3839                throw new SecurityException("Package " + packageName + " not a system app!");
3840            }
3841
3842            if (mFrozenPackages.contains(packageName)) {
3843                throw new SecurityException("Package " + packageName + " is currently frozen!");
3844            }
3845
3846            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3847                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3848            }
3849        }
3850    }
3851
3852    @Override
3853    public boolean isPackageAvailable(String packageName, int userId) {
3854        if (!sUserManager.exists(userId)) return false;
3855        final int callingUid = Binder.getCallingUid();
3856        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3857                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3858        synchronized (mPackages) {
3859            PackageParser.Package p = mPackages.get(packageName);
3860            if (p != null) {
3861                final PackageSetting ps = (PackageSetting) p.mExtras;
3862                if (filterAppAccessLPr(ps, callingUid, userId)) {
3863                    return false;
3864                }
3865                if (ps != null) {
3866                    final PackageUserState state = ps.readUserState(userId);
3867                    if (state != null) {
3868                        return PackageParser.isAvailable(state);
3869                    }
3870                }
3871            }
3872        }
3873        return false;
3874    }
3875
3876    @Override
3877    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3878        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3879                flags, Binder.getCallingUid(), userId);
3880    }
3881
3882    @Override
3883    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3884            int flags, int userId) {
3885        return getPackageInfoInternal(versionedPackage.getPackageName(),
3886                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3887    }
3888
3889    /**
3890     * Important: The provided filterCallingUid is used exclusively to filter out packages
3891     * that can be seen based on user state. It's typically the original caller uid prior
3892     * to clearing. Because it can only be provided by trusted code, it's value can be
3893     * trusted and will be used as-is; unlike userId which will be validated by this method.
3894     */
3895    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3896            int flags, int filterCallingUid, int userId) {
3897        if (!sUserManager.exists(userId)) return null;
3898        flags = updateFlagsForPackage(flags, userId, packageName);
3899        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
3900                false /* requireFullPermission */, false /* checkShell */, "get package info");
3901
3902        // reader
3903        synchronized (mPackages) {
3904            // Normalize package name to handle renamed packages and static libs
3905            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3906
3907            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3908            if (matchFactoryOnly) {
3909                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3910                if (ps != null) {
3911                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3912                        return null;
3913                    }
3914                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3915                        return null;
3916                    }
3917                    return generatePackageInfo(ps, flags, userId);
3918                }
3919            }
3920
3921            PackageParser.Package p = mPackages.get(packageName);
3922            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3923                return null;
3924            }
3925            if (DEBUG_PACKAGE_INFO)
3926                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3927            if (p != null) {
3928                final PackageSetting ps = (PackageSetting) p.mExtras;
3929                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3930                    return null;
3931                }
3932                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3933                    return null;
3934                }
3935                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3936            }
3937            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3938                final PackageSetting ps = mSettings.mPackages.get(packageName);
3939                if (ps == null) return null;
3940                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3941                    return null;
3942                }
3943                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3944                    return null;
3945                }
3946                return generatePackageInfo(ps, flags, userId);
3947            }
3948        }
3949        return null;
3950    }
3951
3952    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3953        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3954            return true;
3955        }
3956        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3957            return true;
3958        }
3959        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3960            return true;
3961        }
3962        return false;
3963    }
3964
3965    private boolean isComponentVisibleToInstantApp(
3966            @Nullable ComponentName component, @ComponentType int type) {
3967        if (type == TYPE_ACTIVITY) {
3968            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3969            return activity != null
3970                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3971                    : false;
3972        } else if (type == TYPE_RECEIVER) {
3973            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3974            return activity != null
3975                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3976                    : false;
3977        } else if (type == TYPE_SERVICE) {
3978            final PackageParser.Service service = mServices.mServices.get(component);
3979            return service != null
3980                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3981                    : false;
3982        } else if (type == TYPE_PROVIDER) {
3983            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3984            return provider != null
3985                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3986                    : false;
3987        } else if (type == TYPE_UNKNOWN) {
3988            return isComponentVisibleToInstantApp(component);
3989        }
3990        return false;
3991    }
3992
3993    /**
3994     * Returns whether or not access to the application should be filtered.
3995     * <p>
3996     * Access may be limited based upon whether the calling or target applications
3997     * are instant applications.
3998     *
3999     * @see #canAccessInstantApps(int)
4000     */
4001    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4002            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4003        // if we're in an isolated process, get the real calling UID
4004        if (Process.isIsolated(callingUid)) {
4005            callingUid = mIsolatedOwners.get(callingUid);
4006        }
4007        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4008        final boolean callerIsInstantApp = instantAppPkgName != null;
4009        if (ps == null) {
4010            if (callerIsInstantApp) {
4011                // pretend the application exists, but, needs to be filtered
4012                return true;
4013            }
4014            return false;
4015        }
4016        // if the target and caller are the same application, don't filter
4017        if (isCallerSameApp(ps.name, callingUid)) {
4018            return false;
4019        }
4020        if (callerIsInstantApp) {
4021            // request for a specific component; if it hasn't been explicitly exposed, filter
4022            if (component != null) {
4023                return !isComponentVisibleToInstantApp(component, componentType);
4024            }
4025            // request for application; if no components have been explicitly exposed, filter
4026            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4027        }
4028        if (ps.getInstantApp(userId)) {
4029            // caller can see all components of all instant applications, don't filter
4030            if (canViewInstantApps(callingUid, userId)) {
4031                return false;
4032            }
4033            // request for a specific instant application component, filter
4034            if (component != null) {
4035                return true;
4036            }
4037            // request for an instant application; if the caller hasn't been granted access, filter
4038            return !mInstantAppRegistry.isInstantAccessGranted(
4039                    userId, UserHandle.getAppId(callingUid), ps.appId);
4040        }
4041        return false;
4042    }
4043
4044    /**
4045     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4046     */
4047    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4048        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4049    }
4050
4051    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4052            int flags) {
4053        // Callers can access only the libs they depend on, otherwise they need to explicitly
4054        // ask for the shared libraries given the caller is allowed to access all static libs.
4055        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4056            // System/shell/root get to see all static libs
4057            final int appId = UserHandle.getAppId(uid);
4058            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4059                    || appId == Process.ROOT_UID) {
4060                return false;
4061            }
4062        }
4063
4064        // No package means no static lib as it is always on internal storage
4065        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4066            return false;
4067        }
4068
4069        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4070                ps.pkg.staticSharedLibVersion);
4071        if (libEntry == null) {
4072            return false;
4073        }
4074
4075        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4076        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4077        if (uidPackageNames == null) {
4078            return true;
4079        }
4080
4081        for (String uidPackageName : uidPackageNames) {
4082            if (ps.name.equals(uidPackageName)) {
4083                return false;
4084            }
4085            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4086            if (uidPs != null) {
4087                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4088                        libEntry.info.getName());
4089                if (index < 0) {
4090                    continue;
4091                }
4092                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4093                    return false;
4094                }
4095            }
4096        }
4097        return true;
4098    }
4099
4100    @Override
4101    public String[] currentToCanonicalPackageNames(String[] names) {
4102        final int callingUid = Binder.getCallingUid();
4103        if (getInstantAppPackageName(callingUid) != null) {
4104            return names;
4105        }
4106        final String[] out = new String[names.length];
4107        // reader
4108        synchronized (mPackages) {
4109            final int callingUserId = UserHandle.getUserId(callingUid);
4110            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4111            for (int i=names.length-1; i>=0; i--) {
4112                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4113                boolean translateName = false;
4114                if (ps != null && ps.realName != null) {
4115                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4116                    translateName = !targetIsInstantApp
4117                            || canViewInstantApps
4118                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4119                                    UserHandle.getAppId(callingUid), ps.appId);
4120                }
4121                out[i] = translateName ? ps.realName : names[i];
4122            }
4123        }
4124        return out;
4125    }
4126
4127    @Override
4128    public String[] canonicalToCurrentPackageNames(String[] names) {
4129        final int callingUid = Binder.getCallingUid();
4130        if (getInstantAppPackageName(callingUid) != null) {
4131            return names;
4132        }
4133        final String[] out = new String[names.length];
4134        // reader
4135        synchronized (mPackages) {
4136            final int callingUserId = UserHandle.getUserId(callingUid);
4137            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4138            for (int i=names.length-1; i>=0; i--) {
4139                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4140                boolean translateName = false;
4141                if (cur != null) {
4142                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4143                    final boolean targetIsInstantApp =
4144                            ps != null && ps.getInstantApp(callingUserId);
4145                    translateName = !targetIsInstantApp
4146                            || canViewInstantApps
4147                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4148                                    UserHandle.getAppId(callingUid), ps.appId);
4149                }
4150                out[i] = translateName ? cur : names[i];
4151            }
4152        }
4153        return out;
4154    }
4155
4156    @Override
4157    public int getPackageUid(String packageName, int flags, int userId) {
4158        if (!sUserManager.exists(userId)) return -1;
4159        final int callingUid = Binder.getCallingUid();
4160        flags = updateFlagsForPackage(flags, userId, packageName);
4161        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4162                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4163
4164        // reader
4165        synchronized (mPackages) {
4166            final PackageParser.Package p = mPackages.get(packageName);
4167            if (p != null && p.isMatch(flags)) {
4168                PackageSetting ps = (PackageSetting) p.mExtras;
4169                if (filterAppAccessLPr(ps, callingUid, userId)) {
4170                    return -1;
4171                }
4172                return UserHandle.getUid(userId, p.applicationInfo.uid);
4173            }
4174            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4175                final PackageSetting ps = mSettings.mPackages.get(packageName);
4176                if (ps != null && ps.isMatch(flags)
4177                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4178                    return UserHandle.getUid(userId, ps.appId);
4179                }
4180            }
4181        }
4182
4183        return -1;
4184    }
4185
4186    @Override
4187    public int[] getPackageGids(String packageName, int flags, int userId) {
4188        if (!sUserManager.exists(userId)) return null;
4189        final int callingUid = Binder.getCallingUid();
4190        flags = updateFlagsForPackage(flags, userId, packageName);
4191        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4192                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4193
4194        // reader
4195        synchronized (mPackages) {
4196            final PackageParser.Package p = mPackages.get(packageName);
4197            if (p != null && p.isMatch(flags)) {
4198                PackageSetting ps = (PackageSetting) p.mExtras;
4199                if (filterAppAccessLPr(ps, callingUid, userId)) {
4200                    return null;
4201                }
4202                // TODO: Shouldn't this be checking for package installed state for userId and
4203                // return null?
4204                return ps.getPermissionsState().computeGids(userId);
4205            }
4206            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4207                final PackageSetting ps = mSettings.mPackages.get(packageName);
4208                if (ps != null && ps.isMatch(flags)
4209                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4210                    return ps.getPermissionsState().computeGids(userId);
4211                }
4212            }
4213        }
4214
4215        return null;
4216    }
4217
4218    @Override
4219    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4220        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4221    }
4222
4223    @Override
4224    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4225            int flags) {
4226        final List<PermissionInfo> permissionList =
4227                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4228        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4229    }
4230
4231    @Override
4232    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4233        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4234    }
4235
4236    @Override
4237    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4238        final List<PermissionGroupInfo> permissionList =
4239                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4240        return (permissionList == null)
4241                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4242    }
4243
4244    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4245            int filterCallingUid, int userId) {
4246        if (!sUserManager.exists(userId)) return null;
4247        PackageSetting ps = mSettings.mPackages.get(packageName);
4248        if (ps != null) {
4249            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4250                return null;
4251            }
4252            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4253                return null;
4254            }
4255            if (ps.pkg == null) {
4256                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4257                if (pInfo != null) {
4258                    return pInfo.applicationInfo;
4259                }
4260                return null;
4261            }
4262            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4263                    ps.readUserState(userId), userId);
4264            if (ai != null) {
4265                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4266            }
4267            return ai;
4268        }
4269        return null;
4270    }
4271
4272    @Override
4273    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4274        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4275    }
4276
4277    /**
4278     * Important: The provided filterCallingUid is used exclusively to filter out applications
4279     * that can be seen based on user state. It's typically the original caller uid prior
4280     * to clearing. Because it can only be provided by trusted code, it's value can be
4281     * trusted and will be used as-is; unlike userId which will be validated by this method.
4282     */
4283    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4284            int filterCallingUid, int userId) {
4285        if (!sUserManager.exists(userId)) return null;
4286        flags = updateFlagsForApplication(flags, userId, packageName);
4287        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4288                false /* requireFullPermission */, false /* checkShell */, "get application info");
4289
4290        // writer
4291        synchronized (mPackages) {
4292            // Normalize package name to handle renamed packages and static libs
4293            packageName = resolveInternalPackageNameLPr(packageName,
4294                    PackageManager.VERSION_CODE_HIGHEST);
4295
4296            PackageParser.Package p = mPackages.get(packageName);
4297            if (DEBUG_PACKAGE_INFO) Log.v(
4298                    TAG, "getApplicationInfo " + packageName
4299                    + ": " + p);
4300            if (p != null) {
4301                PackageSetting ps = mSettings.mPackages.get(packageName);
4302                if (ps == null) return null;
4303                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4304                    return null;
4305                }
4306                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4307                    return null;
4308                }
4309                // Note: isEnabledLP() does not apply here - always return info
4310                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4311                        p, flags, ps.readUserState(userId), userId);
4312                if (ai != null) {
4313                    ai.packageName = resolveExternalPackageNameLPr(p);
4314                }
4315                return ai;
4316            }
4317            if ("android".equals(packageName)||"system".equals(packageName)) {
4318                return mAndroidApplication;
4319            }
4320            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4321                // Already generates the external package name
4322                return generateApplicationInfoFromSettingsLPw(packageName,
4323                        flags, filterCallingUid, userId);
4324            }
4325        }
4326        return null;
4327    }
4328
4329    private String normalizePackageNameLPr(String packageName) {
4330        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4331        return normalizedPackageName != null ? normalizedPackageName : packageName;
4332    }
4333
4334    @Override
4335    public void deletePreloadsFileCache() {
4336        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4337            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4338        }
4339        File dir = Environment.getDataPreloadsFileCacheDirectory();
4340        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4341        FileUtils.deleteContents(dir);
4342    }
4343
4344    @Override
4345    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4346            final int storageFlags, final IPackageDataObserver observer) {
4347        mContext.enforceCallingOrSelfPermission(
4348                android.Manifest.permission.CLEAR_APP_CACHE, null);
4349        mHandler.post(() -> {
4350            boolean success = false;
4351            try {
4352                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4353                success = true;
4354            } catch (IOException e) {
4355                Slog.w(TAG, e);
4356            }
4357            if (observer != null) {
4358                try {
4359                    observer.onRemoveCompleted(null, success);
4360                } catch (RemoteException e) {
4361                    Slog.w(TAG, e);
4362                }
4363            }
4364        });
4365    }
4366
4367    @Override
4368    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4369            final int storageFlags, final IntentSender pi) {
4370        mContext.enforceCallingOrSelfPermission(
4371                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4372        mHandler.post(() -> {
4373            boolean success = false;
4374            try {
4375                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4376                success = true;
4377            } catch (IOException e) {
4378                Slog.w(TAG, e);
4379            }
4380            if (pi != null) {
4381                try {
4382                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4383                } catch (SendIntentException e) {
4384                    Slog.w(TAG, e);
4385                }
4386            }
4387        });
4388    }
4389
4390    /**
4391     * Blocking call to clear various types of cached data across the system
4392     * until the requested bytes are available.
4393     */
4394    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4395        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4396        final File file = storage.findPathForUuid(volumeUuid);
4397        if (file.getUsableSpace() >= bytes) return;
4398
4399        if (ENABLE_FREE_CACHE_V2) {
4400            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4401                    volumeUuid);
4402            final boolean aggressive = (storageFlags
4403                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4404            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4405
4406            // 1. Pre-flight to determine if we have any chance to succeed
4407            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4408            if (internalVolume && (aggressive || SystemProperties
4409                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4410                deletePreloadsFileCache();
4411                if (file.getUsableSpace() >= bytes) return;
4412            }
4413
4414            // 3. Consider parsed APK data (aggressive only)
4415            if (internalVolume && aggressive) {
4416                FileUtils.deleteContents(mCacheDir);
4417                if (file.getUsableSpace() >= bytes) return;
4418            }
4419
4420            // 4. Consider cached app data (above quotas)
4421            try {
4422                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4423                        Installer.FLAG_FREE_CACHE_V2);
4424            } catch (InstallerException ignored) {
4425            }
4426            if (file.getUsableSpace() >= bytes) return;
4427
4428            // 5. Consider shared libraries with refcount=0 and age>min cache period
4429            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4430                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4431                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4432                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4433                return;
4434            }
4435
4436            // 6. Consider dexopt output (aggressive only)
4437            // TODO: Implement
4438
4439            // 7. Consider installed instant apps unused longer than min cache period
4440            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4441                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4442                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4443                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4444                return;
4445            }
4446
4447            // 8. Consider cached app data (below quotas)
4448            try {
4449                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4450                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4451            } catch (InstallerException ignored) {
4452            }
4453            if (file.getUsableSpace() >= bytes) return;
4454
4455            // 9. Consider DropBox entries
4456            // TODO: Implement
4457
4458            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4459            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4460                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4461                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4462                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4463                return;
4464            }
4465        } else {
4466            try {
4467                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4468            } catch (InstallerException ignored) {
4469            }
4470            if (file.getUsableSpace() >= bytes) return;
4471        }
4472
4473        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4474    }
4475
4476    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4477            throws IOException {
4478        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4479        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4480
4481        List<VersionedPackage> packagesToDelete = null;
4482        final long now = System.currentTimeMillis();
4483
4484        synchronized (mPackages) {
4485            final int[] allUsers = sUserManager.getUserIds();
4486            final int libCount = mSharedLibraries.size();
4487            for (int i = 0; i < libCount; i++) {
4488                final LongSparseArray<SharedLibraryEntry> versionedLib
4489                        = mSharedLibraries.valueAt(i);
4490                if (versionedLib == null) {
4491                    continue;
4492                }
4493                final int versionCount = versionedLib.size();
4494                for (int j = 0; j < versionCount; j++) {
4495                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4496                    // Skip packages that are not static shared libs.
4497                    if (!libInfo.isStatic()) {
4498                        break;
4499                    }
4500                    // Important: We skip static shared libs used for some user since
4501                    // in such a case we need to keep the APK on the device. The check for
4502                    // a lib being used for any user is performed by the uninstall call.
4503                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4504                    // Resolve the package name - we use synthetic package names internally
4505                    final String internalPackageName = resolveInternalPackageNameLPr(
4506                            declaringPackage.getPackageName(),
4507                            declaringPackage.getLongVersionCode());
4508                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4509                    // Skip unused static shared libs cached less than the min period
4510                    // to prevent pruning a lib needed by a subsequently installed package.
4511                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4512                        continue;
4513                    }
4514                    if (packagesToDelete == null) {
4515                        packagesToDelete = new ArrayList<>();
4516                    }
4517                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4518                            declaringPackage.getLongVersionCode()));
4519                }
4520            }
4521        }
4522
4523        if (packagesToDelete != null) {
4524            final int packageCount = packagesToDelete.size();
4525            for (int i = 0; i < packageCount; i++) {
4526                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4527                // Delete the package synchronously (will fail of the lib used for any user).
4528                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4529                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4530                                == PackageManager.DELETE_SUCCEEDED) {
4531                    if (volume.getUsableSpace() >= neededSpace) {
4532                        return true;
4533                    }
4534                }
4535            }
4536        }
4537
4538        return false;
4539    }
4540
4541    /**
4542     * Update given flags based on encryption status of current user.
4543     */
4544    private int updateFlags(int flags, int userId) {
4545        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4546                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4547            // Caller expressed an explicit opinion about what encryption
4548            // aware/unaware components they want to see, so fall through and
4549            // give them what they want
4550        } else {
4551            // Caller expressed no opinion, so match based on user state
4552            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4553                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4554            } else {
4555                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4556            }
4557        }
4558        return flags;
4559    }
4560
4561    private UserManagerInternal getUserManagerInternal() {
4562        if (mUserManagerInternal == null) {
4563            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4564        }
4565        return mUserManagerInternal;
4566    }
4567
4568    private DeviceIdleController.LocalService getDeviceIdleController() {
4569        if (mDeviceIdleController == null) {
4570            mDeviceIdleController =
4571                    LocalServices.getService(DeviceIdleController.LocalService.class);
4572        }
4573        return mDeviceIdleController;
4574    }
4575
4576    /**
4577     * Update given flags when being used to request {@link PackageInfo}.
4578     */
4579    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4580        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4581        boolean triaged = true;
4582        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4583                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4584            // Caller is asking for component details, so they'd better be
4585            // asking for specific encryption matching behavior, or be triaged
4586            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4587                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4588                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4589                triaged = false;
4590            }
4591        }
4592        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4593                | PackageManager.MATCH_SYSTEM_ONLY
4594                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4595            triaged = false;
4596        }
4597        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4598            mPermissionManager.enforceCrossUserPermission(
4599                    Binder.getCallingUid(), userId, false, false,
4600                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4601                    + Debug.getCallers(5));
4602        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4603                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4604            // If the caller wants all packages and has a restricted profile associated with it,
4605            // then match all users. This is to make sure that launchers that need to access work
4606            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4607            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4608            flags |= PackageManager.MATCH_ANY_USER;
4609        }
4610        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4611            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4612                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4613        }
4614        return updateFlags(flags, userId);
4615    }
4616
4617    /**
4618     * Update given flags when being used to request {@link ApplicationInfo}.
4619     */
4620    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4621        return updateFlagsForPackage(flags, userId, cookie);
4622    }
4623
4624    /**
4625     * Update given flags when being used to request {@link ComponentInfo}.
4626     */
4627    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4628        if (cookie instanceof Intent) {
4629            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4630                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4631            }
4632        }
4633
4634        boolean triaged = true;
4635        // Caller is asking for component details, so they'd better be
4636        // asking for specific encryption matching behavior, or be triaged
4637        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4638                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4639                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4640            triaged = false;
4641        }
4642        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4643            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4644                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4645        }
4646
4647        return updateFlags(flags, userId);
4648    }
4649
4650    /**
4651     * Update given intent when being used to request {@link ResolveInfo}.
4652     */
4653    private Intent updateIntentForResolve(Intent intent) {
4654        if (intent.getSelector() != null) {
4655            intent = intent.getSelector();
4656        }
4657        if (DEBUG_PREFERRED) {
4658            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4659        }
4660        return intent;
4661    }
4662
4663    /**
4664     * Update given flags when being used to request {@link ResolveInfo}.
4665     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4666     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4667     * flag set. However, this flag is only honoured in three circumstances:
4668     * <ul>
4669     * <li>when called from a system process</li>
4670     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4671     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4672     * action and a {@code android.intent.category.BROWSABLE} category</li>
4673     * </ul>
4674     */
4675    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4676        return updateFlagsForResolve(flags, userId, intent, callingUid,
4677                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4678    }
4679    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4680            boolean wantInstantApps) {
4681        return updateFlagsForResolve(flags, userId, intent, callingUid,
4682                wantInstantApps, false /*onlyExposedExplicitly*/);
4683    }
4684    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4685            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4686        // Safe mode means we shouldn't match any third-party components
4687        if (mSafeMode) {
4688            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4689        }
4690        if (getInstantAppPackageName(callingUid) != null) {
4691            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4692            if (onlyExposedExplicitly) {
4693                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4694            }
4695            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4696            flags |= PackageManager.MATCH_INSTANT;
4697        } else {
4698            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4699            final boolean allowMatchInstant =
4700                    (wantInstantApps
4701                            && Intent.ACTION_VIEW.equals(intent.getAction())
4702                            && hasWebURI(intent))
4703                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4704            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4705                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4706            if (!allowMatchInstant) {
4707                flags &= ~PackageManager.MATCH_INSTANT;
4708            }
4709        }
4710        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4711    }
4712
4713    @Override
4714    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4715        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4716    }
4717
4718    /**
4719     * Important: The provided filterCallingUid is used exclusively to filter out activities
4720     * that can be seen based on user state. It's typically the original caller uid prior
4721     * to clearing. Because it can only be provided by trusted code, it's value can be
4722     * trusted and will be used as-is; unlike userId which will be validated by this method.
4723     */
4724    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4725            int filterCallingUid, int userId) {
4726        if (!sUserManager.exists(userId)) return null;
4727        flags = updateFlagsForComponent(flags, userId, component);
4728        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4729                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4730        synchronized (mPackages) {
4731            PackageParser.Activity a = mActivities.mActivities.get(component);
4732
4733            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4734            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4735                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4736                if (ps == null) return null;
4737                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4738                    return null;
4739                }
4740                return PackageParser.generateActivityInfo(
4741                        a, flags, ps.readUserState(userId), userId);
4742            }
4743            if (mResolveComponentName.equals(component)) {
4744                return PackageParser.generateActivityInfo(
4745                        mResolveActivity, flags, new PackageUserState(), userId);
4746            }
4747        }
4748        return null;
4749    }
4750
4751    @Override
4752    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4753            String resolvedType) {
4754        synchronized (mPackages) {
4755            if (component.equals(mResolveComponentName)) {
4756                // The resolver supports EVERYTHING!
4757                return true;
4758            }
4759            final int callingUid = Binder.getCallingUid();
4760            final int callingUserId = UserHandle.getUserId(callingUid);
4761            PackageParser.Activity a = mActivities.mActivities.get(component);
4762            if (a == null) {
4763                return false;
4764            }
4765            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4766            if (ps == null) {
4767                return false;
4768            }
4769            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4770                return false;
4771            }
4772            for (int i=0; i<a.intents.size(); i++) {
4773                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4774                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4775                    return true;
4776                }
4777            }
4778            return false;
4779        }
4780    }
4781
4782    @Override
4783    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4784        if (!sUserManager.exists(userId)) return null;
4785        final int callingUid = Binder.getCallingUid();
4786        flags = updateFlagsForComponent(flags, userId, component);
4787        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4788                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4789        synchronized (mPackages) {
4790            PackageParser.Activity a = mReceivers.mActivities.get(component);
4791            if (DEBUG_PACKAGE_INFO) Log.v(
4792                TAG, "getReceiverInfo " + component + ": " + a);
4793            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4794                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4795                if (ps == null) return null;
4796                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4797                    return null;
4798                }
4799                return PackageParser.generateActivityInfo(
4800                        a, flags, ps.readUserState(userId), userId);
4801            }
4802        }
4803        return null;
4804    }
4805
4806    @Override
4807    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4808            int flags, int userId) {
4809        if (!sUserManager.exists(userId)) return null;
4810        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4811        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4812            return null;
4813        }
4814
4815        flags = updateFlagsForPackage(flags, userId, null);
4816
4817        final boolean canSeeStaticLibraries =
4818                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4819                        == PERMISSION_GRANTED
4820                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4821                        == PERMISSION_GRANTED
4822                || canRequestPackageInstallsInternal(packageName,
4823                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4824                        false  /* throwIfPermNotDeclared*/)
4825                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4826                        == PERMISSION_GRANTED;
4827
4828        synchronized (mPackages) {
4829            List<SharedLibraryInfo> result = null;
4830
4831            final int libCount = mSharedLibraries.size();
4832            for (int i = 0; i < libCount; i++) {
4833                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4834                if (versionedLib == null) {
4835                    continue;
4836                }
4837
4838                final int versionCount = versionedLib.size();
4839                for (int j = 0; j < versionCount; j++) {
4840                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4841                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4842                        break;
4843                    }
4844                    final long identity = Binder.clearCallingIdentity();
4845                    try {
4846                        PackageInfo packageInfo = getPackageInfoVersioned(
4847                                libInfo.getDeclaringPackage(), flags
4848                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4849                        if (packageInfo == null) {
4850                            continue;
4851                        }
4852                    } finally {
4853                        Binder.restoreCallingIdentity(identity);
4854                    }
4855
4856                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4857                            libInfo.getLongVersion(), libInfo.getType(),
4858                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4859                            flags, userId));
4860
4861                    if (result == null) {
4862                        result = new ArrayList<>();
4863                    }
4864                    result.add(resLibInfo);
4865                }
4866            }
4867
4868            return result != null ? new ParceledListSlice<>(result) : null;
4869        }
4870    }
4871
4872    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4873            SharedLibraryInfo libInfo, int flags, int userId) {
4874        List<VersionedPackage> versionedPackages = null;
4875        final int packageCount = mSettings.mPackages.size();
4876        for (int i = 0; i < packageCount; i++) {
4877            PackageSetting ps = mSettings.mPackages.valueAt(i);
4878
4879            if (ps == null) {
4880                continue;
4881            }
4882
4883            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4884                continue;
4885            }
4886
4887            final String libName = libInfo.getName();
4888            if (libInfo.isStatic()) {
4889                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4890                if (libIdx < 0) {
4891                    continue;
4892                }
4893                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
4894                    continue;
4895                }
4896                if (versionedPackages == null) {
4897                    versionedPackages = new ArrayList<>();
4898                }
4899                // If the dependent is a static shared lib, use the public package name
4900                String dependentPackageName = ps.name;
4901                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4902                    dependentPackageName = ps.pkg.manifestPackageName;
4903                }
4904                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4905            } else if (ps.pkg != null) {
4906                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4907                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4908                    if (versionedPackages == null) {
4909                        versionedPackages = new ArrayList<>();
4910                    }
4911                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4912                }
4913            }
4914        }
4915
4916        return versionedPackages;
4917    }
4918
4919    @Override
4920    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4921        if (!sUserManager.exists(userId)) return null;
4922        final int callingUid = Binder.getCallingUid();
4923        flags = updateFlagsForComponent(flags, userId, component);
4924        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4925                false /* requireFullPermission */, false /* checkShell */, "get service info");
4926        synchronized (mPackages) {
4927            PackageParser.Service s = mServices.mServices.get(component);
4928            if (DEBUG_PACKAGE_INFO) Log.v(
4929                TAG, "getServiceInfo " + component + ": " + s);
4930            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4931                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4932                if (ps == null) return null;
4933                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4934                    return null;
4935                }
4936                return PackageParser.generateServiceInfo(
4937                        s, flags, ps.readUserState(userId), userId);
4938            }
4939        }
4940        return null;
4941    }
4942
4943    @Override
4944    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4945        if (!sUserManager.exists(userId)) return null;
4946        final int callingUid = Binder.getCallingUid();
4947        flags = updateFlagsForComponent(flags, userId, component);
4948        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4949                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4950        synchronized (mPackages) {
4951            PackageParser.Provider p = mProviders.mProviders.get(component);
4952            if (DEBUG_PACKAGE_INFO) Log.v(
4953                TAG, "getProviderInfo " + component + ": " + p);
4954            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4955                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4956                if (ps == null) return null;
4957                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4958                    return null;
4959                }
4960                return PackageParser.generateProviderInfo(
4961                        p, flags, ps.readUserState(userId), userId);
4962            }
4963        }
4964        return null;
4965    }
4966
4967    @Override
4968    public String[] getSystemSharedLibraryNames() {
4969        // allow instant applications
4970        synchronized (mPackages) {
4971            Set<String> libs = null;
4972            final int libCount = mSharedLibraries.size();
4973            for (int i = 0; i < libCount; i++) {
4974                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4975                if (versionedLib == null) {
4976                    continue;
4977                }
4978                final int versionCount = versionedLib.size();
4979                for (int j = 0; j < versionCount; j++) {
4980                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4981                    if (!libEntry.info.isStatic()) {
4982                        if (libs == null) {
4983                            libs = new ArraySet<>();
4984                        }
4985                        libs.add(libEntry.info.getName());
4986                        break;
4987                    }
4988                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4989                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4990                            UserHandle.getUserId(Binder.getCallingUid()),
4991                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4992                        if (libs == null) {
4993                            libs = new ArraySet<>();
4994                        }
4995                        libs.add(libEntry.info.getName());
4996                        break;
4997                    }
4998                }
4999            }
5000
5001            if (libs != null) {
5002                String[] libsArray = new String[libs.size()];
5003                libs.toArray(libsArray);
5004                return libsArray;
5005            }
5006
5007            return null;
5008        }
5009    }
5010
5011    @Override
5012    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5013        // allow instant applications
5014        synchronized (mPackages) {
5015            return mServicesSystemSharedLibraryPackageName;
5016        }
5017    }
5018
5019    @Override
5020    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5021        // allow instant applications
5022        synchronized (mPackages) {
5023            return mSharedSystemSharedLibraryPackageName;
5024        }
5025    }
5026
5027    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5028        for (int i = userList.length - 1; i >= 0; --i) {
5029            final int userId = userList[i];
5030            // don't add instant app to the list of updates
5031            if (pkgSetting.getInstantApp(userId)) {
5032                continue;
5033            }
5034            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5035            if (changedPackages == null) {
5036                changedPackages = new SparseArray<>();
5037                mChangedPackages.put(userId, changedPackages);
5038            }
5039            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5040            if (sequenceNumbers == null) {
5041                sequenceNumbers = new HashMap<>();
5042                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5043            }
5044            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5045            if (sequenceNumber != null) {
5046                changedPackages.remove(sequenceNumber);
5047            }
5048            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5049            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5050        }
5051        mChangedPackagesSequenceNumber++;
5052    }
5053
5054    @Override
5055    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5056        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5057            return null;
5058        }
5059        synchronized (mPackages) {
5060            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5061                return null;
5062            }
5063            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5064            if (changedPackages == null) {
5065                return null;
5066            }
5067            final List<String> packageNames =
5068                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5069            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5070                final String packageName = changedPackages.get(i);
5071                if (packageName != null) {
5072                    packageNames.add(packageName);
5073                }
5074            }
5075            return packageNames.isEmpty()
5076                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5077        }
5078    }
5079
5080    @Override
5081    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5082        // allow instant applications
5083        ArrayList<FeatureInfo> res;
5084        synchronized (mAvailableFeatures) {
5085            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5086            res.addAll(mAvailableFeatures.values());
5087        }
5088        final FeatureInfo fi = new FeatureInfo();
5089        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5090                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5091        res.add(fi);
5092
5093        return new ParceledListSlice<>(res);
5094    }
5095
5096    @Override
5097    public boolean hasSystemFeature(String name, int version) {
5098        // allow instant applications
5099        synchronized (mAvailableFeatures) {
5100            final FeatureInfo feat = mAvailableFeatures.get(name);
5101            if (feat == null) {
5102                return false;
5103            } else {
5104                return feat.version >= version;
5105            }
5106        }
5107    }
5108
5109    @Override
5110    public int checkPermission(String permName, String pkgName, int userId) {
5111        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5112    }
5113
5114    @Override
5115    public int checkUidPermission(String permName, int uid) {
5116        return mPermissionManager.checkUidPermission(permName, uid, getCallingUid());
5117    }
5118
5119    @Override
5120    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5121        if (UserHandle.getCallingUserId() != userId) {
5122            mContext.enforceCallingPermission(
5123                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5124                    "isPermissionRevokedByPolicy for user " + userId);
5125        }
5126
5127        if (checkPermission(permission, packageName, userId)
5128                == PackageManager.PERMISSION_GRANTED) {
5129            return false;
5130        }
5131
5132        final int callingUid = Binder.getCallingUid();
5133        if (getInstantAppPackageName(callingUid) != null) {
5134            if (!isCallerSameApp(packageName, callingUid)) {
5135                return false;
5136            }
5137        } else {
5138            if (isInstantApp(packageName, userId)) {
5139                return false;
5140            }
5141        }
5142
5143        final long identity = Binder.clearCallingIdentity();
5144        try {
5145            final int flags = getPermissionFlags(permission, packageName, userId);
5146            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5147        } finally {
5148            Binder.restoreCallingIdentity(identity);
5149        }
5150    }
5151
5152    @Override
5153    public String getPermissionControllerPackageName() {
5154        synchronized (mPackages) {
5155            return mRequiredInstallerPackage;
5156        }
5157    }
5158
5159    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5160        return mPermissionManager.addDynamicPermission(
5161                info, async, getCallingUid(), new PermissionCallback() {
5162                    @Override
5163                    public void onPermissionChanged() {
5164                        if (!async) {
5165                            mSettings.writeLPr();
5166                        } else {
5167                            scheduleWriteSettingsLocked();
5168                        }
5169                    }
5170                });
5171    }
5172
5173    @Override
5174    public boolean addPermission(PermissionInfo info) {
5175        synchronized (mPackages) {
5176            return addDynamicPermission(info, false);
5177        }
5178    }
5179
5180    @Override
5181    public boolean addPermissionAsync(PermissionInfo info) {
5182        synchronized (mPackages) {
5183            return addDynamicPermission(info, true);
5184        }
5185    }
5186
5187    @Override
5188    public void removePermission(String permName) {
5189        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5190    }
5191
5192    @Override
5193    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5194        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5195                getCallingUid(), userId, mPermissionCallback);
5196    }
5197
5198    @Override
5199    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5200        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5201                getCallingUid(), userId, mPermissionCallback);
5202    }
5203
5204    @Override
5205    public void resetRuntimePermissions() {
5206        mContext.enforceCallingOrSelfPermission(
5207                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5208                "revokeRuntimePermission");
5209
5210        int callingUid = Binder.getCallingUid();
5211        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5212            mContext.enforceCallingOrSelfPermission(
5213                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5214                    "resetRuntimePermissions");
5215        }
5216
5217        synchronized (mPackages) {
5218            mPermissionManager.updateAllPermissions(
5219                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5220                    mPermissionCallback);
5221            for (int userId : UserManagerService.getInstance().getUserIds()) {
5222                final int packageCount = mPackages.size();
5223                for (int i = 0; i < packageCount; i++) {
5224                    PackageParser.Package pkg = mPackages.valueAt(i);
5225                    if (!(pkg.mExtras instanceof PackageSetting)) {
5226                        continue;
5227                    }
5228                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5229                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5230                }
5231            }
5232        }
5233    }
5234
5235    @Override
5236    public int getPermissionFlags(String permName, String packageName, int userId) {
5237        return mPermissionManager.getPermissionFlags(
5238                permName, packageName, getCallingUid(), userId);
5239    }
5240
5241    @Override
5242    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5243            int flagValues, int userId) {
5244        mPermissionManager.updatePermissionFlags(
5245                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5246                mPermissionCallback);
5247    }
5248
5249    /**
5250     * Update the permission flags for all packages and runtime permissions of a user in order
5251     * to allow device or profile owner to remove POLICY_FIXED.
5252     */
5253    @Override
5254    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5255        synchronized (mPackages) {
5256            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5257                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5258                    mPermissionCallback);
5259            if (changed) {
5260                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5261            }
5262        }
5263    }
5264
5265    @Override
5266    public boolean shouldShowRequestPermissionRationale(String permissionName,
5267            String packageName, int userId) {
5268        if (UserHandle.getCallingUserId() != userId) {
5269            mContext.enforceCallingPermission(
5270                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5271                    "canShowRequestPermissionRationale for user " + userId);
5272        }
5273
5274        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5275        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5276            return false;
5277        }
5278
5279        if (checkPermission(permissionName, packageName, userId)
5280                == PackageManager.PERMISSION_GRANTED) {
5281            return false;
5282        }
5283
5284        final int flags;
5285
5286        final long identity = Binder.clearCallingIdentity();
5287        try {
5288            flags = getPermissionFlags(permissionName,
5289                    packageName, userId);
5290        } finally {
5291            Binder.restoreCallingIdentity(identity);
5292        }
5293
5294        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5295                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5296                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5297
5298        if ((flags & fixedFlags) != 0) {
5299            return false;
5300        }
5301
5302        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5303    }
5304
5305    @Override
5306    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5307        mContext.enforceCallingOrSelfPermission(
5308                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5309                "addOnPermissionsChangeListener");
5310
5311        synchronized (mPackages) {
5312            mOnPermissionChangeListeners.addListenerLocked(listener);
5313        }
5314    }
5315
5316    @Override
5317    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5318        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5319            throw new SecurityException("Instant applications don't have access to this method");
5320        }
5321        synchronized (mPackages) {
5322            mOnPermissionChangeListeners.removeListenerLocked(listener);
5323        }
5324    }
5325
5326    @Override
5327    public boolean isProtectedBroadcast(String actionName) {
5328        // allow instant applications
5329        synchronized (mProtectedBroadcasts) {
5330            if (mProtectedBroadcasts.contains(actionName)) {
5331                return true;
5332            } else if (actionName != null) {
5333                // TODO: remove these terrible hacks
5334                if (actionName.startsWith("android.net.netmon.lingerExpired")
5335                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5336                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5337                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5338                    return true;
5339                }
5340            }
5341        }
5342        return false;
5343    }
5344
5345    @Override
5346    public int checkSignatures(String pkg1, String pkg2) {
5347        synchronized (mPackages) {
5348            final PackageParser.Package p1 = mPackages.get(pkg1);
5349            final PackageParser.Package p2 = mPackages.get(pkg2);
5350            if (p1 == null || p1.mExtras == null
5351                    || p2 == null || p2.mExtras == null) {
5352                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5353            }
5354            final int callingUid = Binder.getCallingUid();
5355            final int callingUserId = UserHandle.getUserId(callingUid);
5356            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5357            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5358            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5359                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5360                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5361            }
5362            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5363        }
5364    }
5365
5366    @Override
5367    public int checkUidSignatures(int uid1, int uid2) {
5368        final int callingUid = Binder.getCallingUid();
5369        final int callingUserId = UserHandle.getUserId(callingUid);
5370        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5371        // Map to base uids.
5372        uid1 = UserHandle.getAppId(uid1);
5373        uid2 = UserHandle.getAppId(uid2);
5374        // reader
5375        synchronized (mPackages) {
5376            Signature[] s1;
5377            Signature[] s2;
5378            Object obj = mSettings.getUserIdLPr(uid1);
5379            if (obj != null) {
5380                if (obj instanceof SharedUserSetting) {
5381                    if (isCallerInstantApp) {
5382                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5383                    }
5384                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5385                } else if (obj instanceof PackageSetting) {
5386                    final PackageSetting ps = (PackageSetting) obj;
5387                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5388                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5389                    }
5390                    s1 = ps.signatures.mSignatures;
5391                } else {
5392                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5393                }
5394            } else {
5395                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5396            }
5397            obj = mSettings.getUserIdLPr(uid2);
5398            if (obj != null) {
5399                if (obj instanceof SharedUserSetting) {
5400                    if (isCallerInstantApp) {
5401                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5402                    }
5403                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5404                } else if (obj instanceof PackageSetting) {
5405                    final PackageSetting ps = (PackageSetting) obj;
5406                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5407                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5408                    }
5409                    s2 = ps.signatures.mSignatures;
5410                } else {
5411                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5412                }
5413            } else {
5414                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5415            }
5416            return compareSignatures(s1, s2);
5417        }
5418    }
5419
5420    /**
5421     * This method should typically only be used when granting or revoking
5422     * permissions, since the app may immediately restart after this call.
5423     * <p>
5424     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5425     * guard your work against the app being relaunched.
5426     */
5427    private void killUid(int appId, int userId, String reason) {
5428        final long identity = Binder.clearCallingIdentity();
5429        try {
5430            IActivityManager am = ActivityManager.getService();
5431            if (am != null) {
5432                try {
5433                    am.killUid(appId, userId, reason);
5434                } catch (RemoteException e) {
5435                    /* ignore - same process */
5436                }
5437            }
5438        } finally {
5439            Binder.restoreCallingIdentity(identity);
5440        }
5441    }
5442
5443    /**
5444     * If the database version for this type of package (internal storage or
5445     * external storage) is less than the version where package signatures
5446     * were updated, return true.
5447     */
5448    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5449        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5450        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5451    }
5452
5453    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5454        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5455        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5456    }
5457
5458    @Override
5459    public List<String> getAllPackages() {
5460        final int callingUid = Binder.getCallingUid();
5461        final int callingUserId = UserHandle.getUserId(callingUid);
5462        synchronized (mPackages) {
5463            if (canViewInstantApps(callingUid, callingUserId)) {
5464                return new ArrayList<String>(mPackages.keySet());
5465            }
5466            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5467            final List<String> result = new ArrayList<>();
5468            if (instantAppPkgName != null) {
5469                // caller is an instant application; filter unexposed applications
5470                for (PackageParser.Package pkg : mPackages.values()) {
5471                    if (!pkg.visibleToInstantApps) {
5472                        continue;
5473                    }
5474                    result.add(pkg.packageName);
5475                }
5476            } else {
5477                // caller is a normal application; filter instant applications
5478                for (PackageParser.Package pkg : mPackages.values()) {
5479                    final PackageSetting ps =
5480                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5481                    if (ps != null
5482                            && ps.getInstantApp(callingUserId)
5483                            && !mInstantAppRegistry.isInstantAccessGranted(
5484                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5485                        continue;
5486                    }
5487                    result.add(pkg.packageName);
5488                }
5489            }
5490            return result;
5491        }
5492    }
5493
5494    @Override
5495    public String[] getPackagesForUid(int uid) {
5496        final int callingUid = Binder.getCallingUid();
5497        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5498        final int userId = UserHandle.getUserId(uid);
5499        uid = UserHandle.getAppId(uid);
5500        // reader
5501        synchronized (mPackages) {
5502            Object obj = mSettings.getUserIdLPr(uid);
5503            if (obj instanceof SharedUserSetting) {
5504                if (isCallerInstantApp) {
5505                    return null;
5506                }
5507                final SharedUserSetting sus = (SharedUserSetting) obj;
5508                final int N = sus.packages.size();
5509                String[] res = new String[N];
5510                final Iterator<PackageSetting> it = sus.packages.iterator();
5511                int i = 0;
5512                while (it.hasNext()) {
5513                    PackageSetting ps = it.next();
5514                    if (ps.getInstalled(userId)) {
5515                        res[i++] = ps.name;
5516                    } else {
5517                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5518                    }
5519                }
5520                return res;
5521            } else if (obj instanceof PackageSetting) {
5522                final PackageSetting ps = (PackageSetting) obj;
5523                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5524                    return new String[]{ps.name};
5525                }
5526            }
5527        }
5528        return null;
5529    }
5530
5531    @Override
5532    public String getNameForUid(int uid) {
5533        final int callingUid = Binder.getCallingUid();
5534        if (getInstantAppPackageName(callingUid) != null) {
5535            return null;
5536        }
5537        synchronized (mPackages) {
5538            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5539            if (obj instanceof SharedUserSetting) {
5540                final SharedUserSetting sus = (SharedUserSetting) obj;
5541                return sus.name + ":" + sus.userId;
5542            } else if (obj instanceof PackageSetting) {
5543                final PackageSetting ps = (PackageSetting) obj;
5544                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5545                    return null;
5546                }
5547                return ps.name;
5548            }
5549            return null;
5550        }
5551    }
5552
5553    @Override
5554    public String[] getNamesForUids(int[] uids) {
5555        if (uids == null || uids.length == 0) {
5556            return null;
5557        }
5558        final int callingUid = Binder.getCallingUid();
5559        if (getInstantAppPackageName(callingUid) != null) {
5560            return null;
5561        }
5562        final String[] names = new String[uids.length];
5563        synchronized (mPackages) {
5564            for (int i = uids.length - 1; i >= 0; i--) {
5565                final int uid = uids[i];
5566                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5567                if (obj instanceof SharedUserSetting) {
5568                    final SharedUserSetting sus = (SharedUserSetting) obj;
5569                    names[i] = "shared:" + sus.name;
5570                } else if (obj instanceof PackageSetting) {
5571                    final PackageSetting ps = (PackageSetting) obj;
5572                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5573                        names[i] = null;
5574                    } else {
5575                        names[i] = ps.name;
5576                    }
5577                } else {
5578                    names[i] = null;
5579                }
5580            }
5581        }
5582        return names;
5583    }
5584
5585    @Override
5586    public int getUidForSharedUser(String sharedUserName) {
5587        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5588            return -1;
5589        }
5590        if (sharedUserName == null) {
5591            return -1;
5592        }
5593        // reader
5594        synchronized (mPackages) {
5595            SharedUserSetting suid;
5596            try {
5597                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5598                if (suid != null) {
5599                    return suid.userId;
5600                }
5601            } catch (PackageManagerException ignore) {
5602                // can't happen, but, still need to catch it
5603            }
5604            return -1;
5605        }
5606    }
5607
5608    @Override
5609    public int getFlagsForUid(int uid) {
5610        final int callingUid = Binder.getCallingUid();
5611        if (getInstantAppPackageName(callingUid) != null) {
5612            return 0;
5613        }
5614        synchronized (mPackages) {
5615            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5616            if (obj instanceof SharedUserSetting) {
5617                final SharedUserSetting sus = (SharedUserSetting) obj;
5618                return sus.pkgFlags;
5619            } else if (obj instanceof PackageSetting) {
5620                final PackageSetting ps = (PackageSetting) obj;
5621                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5622                    return 0;
5623                }
5624                return ps.pkgFlags;
5625            }
5626        }
5627        return 0;
5628    }
5629
5630    @Override
5631    public int getPrivateFlagsForUid(int uid) {
5632        final int callingUid = Binder.getCallingUid();
5633        if (getInstantAppPackageName(callingUid) != null) {
5634            return 0;
5635        }
5636        synchronized (mPackages) {
5637            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5638            if (obj instanceof SharedUserSetting) {
5639                final SharedUserSetting sus = (SharedUserSetting) obj;
5640                return sus.pkgPrivateFlags;
5641            } else if (obj instanceof PackageSetting) {
5642                final PackageSetting ps = (PackageSetting) obj;
5643                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5644                    return 0;
5645                }
5646                return ps.pkgPrivateFlags;
5647            }
5648        }
5649        return 0;
5650    }
5651
5652    @Override
5653    public boolean isUidPrivileged(int uid) {
5654        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5655            return false;
5656        }
5657        uid = UserHandle.getAppId(uid);
5658        // reader
5659        synchronized (mPackages) {
5660            Object obj = mSettings.getUserIdLPr(uid);
5661            if (obj instanceof SharedUserSetting) {
5662                final SharedUserSetting sus = (SharedUserSetting) obj;
5663                final Iterator<PackageSetting> it = sus.packages.iterator();
5664                while (it.hasNext()) {
5665                    if (it.next().isPrivileged()) {
5666                        return true;
5667                    }
5668                }
5669            } else if (obj instanceof PackageSetting) {
5670                final PackageSetting ps = (PackageSetting) obj;
5671                return ps.isPrivileged();
5672            }
5673        }
5674        return false;
5675    }
5676
5677    @Override
5678    public String[] getAppOpPermissionPackages(String permName) {
5679        return mPermissionManager.getAppOpPermissionPackages(permName);
5680    }
5681
5682    @Override
5683    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5684            int flags, int userId) {
5685        return resolveIntentInternal(
5686                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5687    }
5688
5689    /**
5690     * Normally instant apps can only be resolved when they're visible to the caller.
5691     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5692     * since we need to allow the system to start any installed application.
5693     */
5694    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5695            int flags, int userId, boolean resolveForStart) {
5696        try {
5697            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5698
5699            if (!sUserManager.exists(userId)) return null;
5700            final int callingUid = Binder.getCallingUid();
5701            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5702            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5703                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5704
5705            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5706            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5707                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5708            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5709
5710            final ResolveInfo bestChoice =
5711                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5712            return bestChoice;
5713        } finally {
5714            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5715        }
5716    }
5717
5718    @Override
5719    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5720        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5721            throw new SecurityException(
5722                    "findPersistentPreferredActivity can only be run by the system");
5723        }
5724        if (!sUserManager.exists(userId)) {
5725            return null;
5726        }
5727        final int callingUid = Binder.getCallingUid();
5728        intent = updateIntentForResolve(intent);
5729        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5730        final int flags = updateFlagsForResolve(
5731                0, userId, intent, callingUid, false /*includeInstantApps*/);
5732        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5733                userId);
5734        synchronized (mPackages) {
5735            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5736                    userId);
5737        }
5738    }
5739
5740    @Override
5741    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5742            IntentFilter filter, int match, ComponentName activity) {
5743        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5744            return;
5745        }
5746        final int userId = UserHandle.getCallingUserId();
5747        if (DEBUG_PREFERRED) {
5748            Log.v(TAG, "setLastChosenActivity intent=" + intent
5749                + " resolvedType=" + resolvedType
5750                + " flags=" + flags
5751                + " filter=" + filter
5752                + " match=" + match
5753                + " activity=" + activity);
5754            filter.dump(new PrintStreamPrinter(System.out), "    ");
5755        }
5756        intent.setComponent(null);
5757        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5758                userId);
5759        // Find any earlier preferred or last chosen entries and nuke them
5760        findPreferredActivity(intent, resolvedType,
5761                flags, query, 0, false, true, false, userId);
5762        // Add the new activity as the last chosen for this filter
5763        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5764                "Setting last chosen");
5765    }
5766
5767    @Override
5768    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5769        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5770            return null;
5771        }
5772        final int userId = UserHandle.getCallingUserId();
5773        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5774        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5775                userId);
5776        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5777                false, false, false, userId);
5778    }
5779
5780    /**
5781     * Returns whether or not instant apps have been disabled remotely.
5782     */
5783    private boolean isEphemeralDisabled() {
5784        return mEphemeralAppsDisabled;
5785    }
5786
5787    private boolean isInstantAppAllowed(
5788            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5789            boolean skipPackageCheck) {
5790        if (mInstantAppResolverConnection == null) {
5791            return false;
5792        }
5793        if (mInstantAppInstallerActivity == null) {
5794            return false;
5795        }
5796        if (intent.getComponent() != null) {
5797            return false;
5798        }
5799        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5800            return false;
5801        }
5802        if (!skipPackageCheck && intent.getPackage() != null) {
5803            return false;
5804        }
5805        final boolean isWebUri = hasWebURI(intent);
5806        if (!isWebUri || intent.getData().getHost() == null) {
5807            return false;
5808        }
5809        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5810        // Or if there's already an ephemeral app installed that handles the action
5811        synchronized (mPackages) {
5812            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5813            for (int n = 0; n < count; n++) {
5814                final ResolveInfo info = resolvedActivities.get(n);
5815                final String packageName = info.activityInfo.packageName;
5816                final PackageSetting ps = mSettings.mPackages.get(packageName);
5817                if (ps != null) {
5818                    // only check domain verification status if the app is not a browser
5819                    if (!info.handleAllWebDataURI) {
5820                        // Try to get the status from User settings first
5821                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5822                        final int status = (int) (packedStatus >> 32);
5823                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5824                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5825                            if (DEBUG_EPHEMERAL) {
5826                                Slog.v(TAG, "DENY instant app;"
5827                                    + " pkg: " + packageName + ", status: " + status);
5828                            }
5829                            return false;
5830                        }
5831                    }
5832                    if (ps.getInstantApp(userId)) {
5833                        if (DEBUG_EPHEMERAL) {
5834                            Slog.v(TAG, "DENY instant app installed;"
5835                                    + " pkg: " + packageName);
5836                        }
5837                        return false;
5838                    }
5839                }
5840            }
5841        }
5842        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5843        return true;
5844    }
5845
5846    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5847            Intent origIntent, String resolvedType, String callingPackage,
5848            Bundle verificationBundle, int userId) {
5849        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5850                new InstantAppRequest(responseObj, origIntent, resolvedType,
5851                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
5852        mHandler.sendMessage(msg);
5853    }
5854
5855    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5856            int flags, List<ResolveInfo> query, int userId) {
5857        if (query != null) {
5858            final int N = query.size();
5859            if (N == 1) {
5860                return query.get(0);
5861            } else if (N > 1) {
5862                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5863                // If there is more than one activity with the same priority,
5864                // then let the user decide between them.
5865                ResolveInfo r0 = query.get(0);
5866                ResolveInfo r1 = query.get(1);
5867                if (DEBUG_INTENT_MATCHING || debug) {
5868                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5869                            + r1.activityInfo.name + "=" + r1.priority);
5870                }
5871                // If the first activity has a higher priority, or a different
5872                // default, then it is always desirable to pick it.
5873                if (r0.priority != r1.priority
5874                        || r0.preferredOrder != r1.preferredOrder
5875                        || r0.isDefault != r1.isDefault) {
5876                    return query.get(0);
5877                }
5878                // If we have saved a preference for a preferred activity for
5879                // this Intent, use that.
5880                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5881                        flags, query, r0.priority, true, false, debug, userId);
5882                if (ri != null) {
5883                    return ri;
5884                }
5885                // If we have an ephemeral app, use it
5886                for (int i = 0; i < N; i++) {
5887                    ri = query.get(i);
5888                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5889                        final String packageName = ri.activityInfo.packageName;
5890                        final PackageSetting ps = mSettings.mPackages.get(packageName);
5891                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5892                        final int status = (int)(packedStatus >> 32);
5893                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5894                            return ri;
5895                        }
5896                    }
5897                }
5898                ri = new ResolveInfo(mResolveInfo);
5899                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5900                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5901                // If all of the options come from the same package, show the application's
5902                // label and icon instead of the generic resolver's.
5903                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5904                // and then throw away the ResolveInfo itself, meaning that the caller loses
5905                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5906                // a fallback for this case; we only set the target package's resources on
5907                // the ResolveInfo, not the ActivityInfo.
5908                final String intentPackage = intent.getPackage();
5909                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5910                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5911                    ri.resolvePackageName = intentPackage;
5912                    if (userNeedsBadging(userId)) {
5913                        ri.noResourceId = true;
5914                    } else {
5915                        ri.icon = appi.icon;
5916                    }
5917                    ri.iconResourceId = appi.icon;
5918                    ri.labelRes = appi.labelRes;
5919                }
5920                ri.activityInfo.applicationInfo = new ApplicationInfo(
5921                        ri.activityInfo.applicationInfo);
5922                if (userId != 0) {
5923                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5924                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5925                }
5926                // Make sure that the resolver is displayable in car mode
5927                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5928                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5929                return ri;
5930            }
5931        }
5932        return null;
5933    }
5934
5935    /**
5936     * Return true if the given list is not empty and all of its contents have
5937     * an activityInfo with the given package name.
5938     */
5939    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5940        if (ArrayUtils.isEmpty(list)) {
5941            return false;
5942        }
5943        for (int i = 0, N = list.size(); i < N; i++) {
5944            final ResolveInfo ri = list.get(i);
5945            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5946            if (ai == null || !packageName.equals(ai.packageName)) {
5947                return false;
5948            }
5949        }
5950        return true;
5951    }
5952
5953    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5954            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5955        final int N = query.size();
5956        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5957                .get(userId);
5958        // Get the list of persistent preferred activities that handle the intent
5959        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5960        List<PersistentPreferredActivity> pprefs = ppir != null
5961                ? ppir.queryIntent(intent, resolvedType,
5962                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5963                        userId)
5964                : null;
5965        if (pprefs != null && pprefs.size() > 0) {
5966            final int M = pprefs.size();
5967            for (int i=0; i<M; i++) {
5968                final PersistentPreferredActivity ppa = pprefs.get(i);
5969                if (DEBUG_PREFERRED || debug) {
5970                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5971                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5972                            + "\n  component=" + ppa.mComponent);
5973                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5974                }
5975                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5976                        flags | MATCH_DISABLED_COMPONENTS, userId);
5977                if (DEBUG_PREFERRED || debug) {
5978                    Slog.v(TAG, "Found persistent preferred activity:");
5979                    if (ai != null) {
5980                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5981                    } else {
5982                        Slog.v(TAG, "  null");
5983                    }
5984                }
5985                if (ai == null) {
5986                    // This previously registered persistent preferred activity
5987                    // component is no longer known. Ignore it and do NOT remove it.
5988                    continue;
5989                }
5990                for (int j=0; j<N; j++) {
5991                    final ResolveInfo ri = query.get(j);
5992                    if (!ri.activityInfo.applicationInfo.packageName
5993                            .equals(ai.applicationInfo.packageName)) {
5994                        continue;
5995                    }
5996                    if (!ri.activityInfo.name.equals(ai.name)) {
5997                        continue;
5998                    }
5999                    //  Found a persistent preference that can handle the intent.
6000                    if (DEBUG_PREFERRED || debug) {
6001                        Slog.v(TAG, "Returning persistent preferred activity: " +
6002                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6003                    }
6004                    return ri;
6005                }
6006            }
6007        }
6008        return null;
6009    }
6010
6011    // TODO: handle preferred activities missing while user has amnesia
6012    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6013            List<ResolveInfo> query, int priority, boolean always,
6014            boolean removeMatches, boolean debug, int userId) {
6015        if (!sUserManager.exists(userId)) return null;
6016        final int callingUid = Binder.getCallingUid();
6017        flags = updateFlagsForResolve(
6018                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6019        intent = updateIntentForResolve(intent);
6020        // writer
6021        synchronized (mPackages) {
6022            // Try to find a matching persistent preferred activity.
6023            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6024                    debug, userId);
6025
6026            // If a persistent preferred activity matched, use it.
6027            if (pri != null) {
6028                return pri;
6029            }
6030
6031            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6032            // Get the list of preferred activities that handle the intent
6033            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6034            List<PreferredActivity> prefs = pir != null
6035                    ? pir.queryIntent(intent, resolvedType,
6036                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6037                            userId)
6038                    : null;
6039            if (prefs != null && prefs.size() > 0) {
6040                boolean changed = false;
6041                try {
6042                    // First figure out how good the original match set is.
6043                    // We will only allow preferred activities that came
6044                    // from the same match quality.
6045                    int match = 0;
6046
6047                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6048
6049                    final int N = query.size();
6050                    for (int j=0; j<N; j++) {
6051                        final ResolveInfo ri = query.get(j);
6052                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6053                                + ": 0x" + Integer.toHexString(match));
6054                        if (ri.match > match) {
6055                            match = ri.match;
6056                        }
6057                    }
6058
6059                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6060                            + Integer.toHexString(match));
6061
6062                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6063                    final int M = prefs.size();
6064                    for (int i=0; i<M; i++) {
6065                        final PreferredActivity pa = prefs.get(i);
6066                        if (DEBUG_PREFERRED || debug) {
6067                            Slog.v(TAG, "Checking PreferredActivity ds="
6068                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6069                                    + "\n  component=" + pa.mPref.mComponent);
6070                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6071                        }
6072                        if (pa.mPref.mMatch != match) {
6073                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6074                                    + Integer.toHexString(pa.mPref.mMatch));
6075                            continue;
6076                        }
6077                        // If it's not an "always" type preferred activity and that's what we're
6078                        // looking for, skip it.
6079                        if (always && !pa.mPref.mAlways) {
6080                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6081                            continue;
6082                        }
6083                        final ActivityInfo ai = getActivityInfo(
6084                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6085                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6086                                userId);
6087                        if (DEBUG_PREFERRED || debug) {
6088                            Slog.v(TAG, "Found preferred activity:");
6089                            if (ai != null) {
6090                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6091                            } else {
6092                                Slog.v(TAG, "  null");
6093                            }
6094                        }
6095                        if (ai == null) {
6096                            // This previously registered preferred activity
6097                            // component is no longer known.  Most likely an update
6098                            // to the app was installed and in the new version this
6099                            // component no longer exists.  Clean it up by removing
6100                            // it from the preferred activities list, and skip it.
6101                            Slog.w(TAG, "Removing dangling preferred activity: "
6102                                    + pa.mPref.mComponent);
6103                            pir.removeFilter(pa);
6104                            changed = true;
6105                            continue;
6106                        }
6107                        for (int j=0; j<N; j++) {
6108                            final ResolveInfo ri = query.get(j);
6109                            if (!ri.activityInfo.applicationInfo.packageName
6110                                    .equals(ai.applicationInfo.packageName)) {
6111                                continue;
6112                            }
6113                            if (!ri.activityInfo.name.equals(ai.name)) {
6114                                continue;
6115                            }
6116
6117                            if (removeMatches) {
6118                                pir.removeFilter(pa);
6119                                changed = true;
6120                                if (DEBUG_PREFERRED) {
6121                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6122                                }
6123                                break;
6124                            }
6125
6126                            // Okay we found a previously set preferred or last chosen app.
6127                            // If the result set is different from when this
6128                            // was created, and is not a subset of the preferred set, we need to
6129                            // clear it and re-ask the user their preference, if we're looking for
6130                            // an "always" type entry.
6131                            if (always && !pa.mPref.sameSet(query)) {
6132                                if (pa.mPref.isSuperset(query)) {
6133                                    // some components of the set are no longer present in
6134                                    // the query, but the preferred activity can still be reused
6135                                    if (DEBUG_PREFERRED) {
6136                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6137                                                + " still valid as only non-preferred components"
6138                                                + " were removed for " + intent + " type "
6139                                                + resolvedType);
6140                                    }
6141                                    // remove obsolete components and re-add the up-to-date filter
6142                                    PreferredActivity freshPa = new PreferredActivity(pa,
6143                                            pa.mPref.mMatch,
6144                                            pa.mPref.discardObsoleteComponents(query),
6145                                            pa.mPref.mComponent,
6146                                            pa.mPref.mAlways);
6147                                    pir.removeFilter(pa);
6148                                    pir.addFilter(freshPa);
6149                                    changed = true;
6150                                } else {
6151                                    Slog.i(TAG,
6152                                            "Result set changed, dropping preferred activity for "
6153                                                    + intent + " type " + resolvedType);
6154                                    if (DEBUG_PREFERRED) {
6155                                        Slog.v(TAG, "Removing preferred activity since set changed "
6156                                                + pa.mPref.mComponent);
6157                                    }
6158                                    pir.removeFilter(pa);
6159                                    // Re-add the filter as a "last chosen" entry (!always)
6160                                    PreferredActivity lastChosen = new PreferredActivity(
6161                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6162                                    pir.addFilter(lastChosen);
6163                                    changed = true;
6164                                    return null;
6165                                }
6166                            }
6167
6168                            // Yay! Either the set matched or we're looking for the last chosen
6169                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6170                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6171                            return ri;
6172                        }
6173                    }
6174                } finally {
6175                    if (changed) {
6176                        if (DEBUG_PREFERRED) {
6177                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6178                        }
6179                        scheduleWritePackageRestrictionsLocked(userId);
6180                    }
6181                }
6182            }
6183        }
6184        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6185        return null;
6186    }
6187
6188    /*
6189     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6190     */
6191    @Override
6192    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6193            int targetUserId) {
6194        mContext.enforceCallingOrSelfPermission(
6195                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6196        List<CrossProfileIntentFilter> matches =
6197                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6198        if (matches != null) {
6199            int size = matches.size();
6200            for (int i = 0; i < size; i++) {
6201                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6202            }
6203        }
6204        if (hasWebURI(intent)) {
6205            // cross-profile app linking works only towards the parent.
6206            final int callingUid = Binder.getCallingUid();
6207            final UserInfo parent = getProfileParent(sourceUserId);
6208            synchronized(mPackages) {
6209                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6210                        false /*includeInstantApps*/);
6211                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6212                        intent, resolvedType, flags, sourceUserId, parent.id);
6213                return xpDomainInfo != null;
6214            }
6215        }
6216        return false;
6217    }
6218
6219    private UserInfo getProfileParent(int userId) {
6220        final long identity = Binder.clearCallingIdentity();
6221        try {
6222            return sUserManager.getProfileParent(userId);
6223        } finally {
6224            Binder.restoreCallingIdentity(identity);
6225        }
6226    }
6227
6228    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6229            String resolvedType, int userId) {
6230        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6231        if (resolver != null) {
6232            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6233        }
6234        return null;
6235    }
6236
6237    @Override
6238    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6239            String resolvedType, int flags, int userId) {
6240        try {
6241            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6242
6243            return new ParceledListSlice<>(
6244                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6245        } finally {
6246            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6247        }
6248    }
6249
6250    /**
6251     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6252     * instant, returns {@code null}.
6253     */
6254    private String getInstantAppPackageName(int callingUid) {
6255        synchronized (mPackages) {
6256            // If the caller is an isolated app use the owner's uid for the lookup.
6257            if (Process.isIsolated(callingUid)) {
6258                callingUid = mIsolatedOwners.get(callingUid);
6259            }
6260            final int appId = UserHandle.getAppId(callingUid);
6261            final Object obj = mSettings.getUserIdLPr(appId);
6262            if (obj instanceof PackageSetting) {
6263                final PackageSetting ps = (PackageSetting) obj;
6264                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6265                return isInstantApp ? ps.pkg.packageName : null;
6266            }
6267        }
6268        return null;
6269    }
6270
6271    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6272            String resolvedType, int flags, int userId) {
6273        return queryIntentActivitiesInternal(
6274                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6275                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6276    }
6277
6278    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6279            String resolvedType, int flags, int filterCallingUid, int userId,
6280            boolean resolveForStart, boolean allowDynamicSplits) {
6281        if (!sUserManager.exists(userId)) return Collections.emptyList();
6282        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6283        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6284                false /* requireFullPermission */, false /* checkShell */,
6285                "query intent activities");
6286        final String pkgName = intent.getPackage();
6287        ComponentName comp = intent.getComponent();
6288        if (comp == null) {
6289            if (intent.getSelector() != null) {
6290                intent = intent.getSelector();
6291                comp = intent.getComponent();
6292            }
6293        }
6294
6295        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6296                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6297        if (comp != null) {
6298            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6299            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6300            if (ai != null) {
6301                // When specifying an explicit component, we prevent the activity from being
6302                // used when either 1) the calling package is normal and the activity is within
6303                // an ephemeral application or 2) the calling package is ephemeral and the
6304                // activity is not visible to ephemeral applications.
6305                final boolean matchInstantApp =
6306                        (flags & PackageManager.MATCH_INSTANT) != 0;
6307                final boolean matchVisibleToInstantAppOnly =
6308                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6309                final boolean matchExplicitlyVisibleOnly =
6310                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6311                final boolean isCallerInstantApp =
6312                        instantAppPkgName != null;
6313                final boolean isTargetSameInstantApp =
6314                        comp.getPackageName().equals(instantAppPkgName);
6315                final boolean isTargetInstantApp =
6316                        (ai.applicationInfo.privateFlags
6317                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6318                final boolean isTargetVisibleToInstantApp =
6319                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6320                final boolean isTargetExplicitlyVisibleToInstantApp =
6321                        isTargetVisibleToInstantApp
6322                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6323                final boolean isTargetHiddenFromInstantApp =
6324                        !isTargetVisibleToInstantApp
6325                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6326                final boolean blockResolution =
6327                        !isTargetSameInstantApp
6328                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6329                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6330                                        && isTargetHiddenFromInstantApp));
6331                if (!blockResolution) {
6332                    final ResolveInfo ri = new ResolveInfo();
6333                    ri.activityInfo = ai;
6334                    list.add(ri);
6335                }
6336            }
6337            return applyPostResolutionFilter(
6338                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6339        }
6340
6341        // reader
6342        boolean sortResult = false;
6343        boolean addEphemeral = false;
6344        List<ResolveInfo> result;
6345        final boolean ephemeralDisabled = isEphemeralDisabled();
6346        synchronized (mPackages) {
6347            if (pkgName == null) {
6348                List<CrossProfileIntentFilter> matchingFilters =
6349                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6350                // Check for results that need to skip the current profile.
6351                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6352                        resolvedType, flags, userId);
6353                if (xpResolveInfo != null) {
6354                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6355                    xpResult.add(xpResolveInfo);
6356                    return applyPostResolutionFilter(
6357                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6358                            allowDynamicSplits, filterCallingUid, userId);
6359                }
6360
6361                // Check for results in the current profile.
6362                result = filterIfNotSystemUser(mActivities.queryIntent(
6363                        intent, resolvedType, flags, userId), userId);
6364                addEphemeral = !ephemeralDisabled
6365                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6366                // Check for cross profile results.
6367                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6368                xpResolveInfo = queryCrossProfileIntents(
6369                        matchingFilters, intent, resolvedType, flags, userId,
6370                        hasNonNegativePriorityResult);
6371                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6372                    boolean isVisibleToUser = filterIfNotSystemUser(
6373                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6374                    if (isVisibleToUser) {
6375                        result.add(xpResolveInfo);
6376                        sortResult = true;
6377                    }
6378                }
6379                if (hasWebURI(intent)) {
6380                    CrossProfileDomainInfo xpDomainInfo = null;
6381                    final UserInfo parent = getProfileParent(userId);
6382                    if (parent != null) {
6383                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6384                                flags, userId, parent.id);
6385                    }
6386                    if (xpDomainInfo != null) {
6387                        if (xpResolveInfo != null) {
6388                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6389                            // in the result.
6390                            result.remove(xpResolveInfo);
6391                        }
6392                        if (result.size() == 0 && !addEphemeral) {
6393                            // No result in current profile, but found candidate in parent user.
6394                            // And we are not going to add emphemeral app, so we can return the
6395                            // result straight away.
6396                            result.add(xpDomainInfo.resolveInfo);
6397                            return applyPostResolutionFilter(result, instantAppPkgName,
6398                                    allowDynamicSplits, filterCallingUid, userId);
6399                        }
6400                    } else if (result.size() <= 1 && !addEphemeral) {
6401                        // No result in parent user and <= 1 result in current profile, and we
6402                        // are not going to add emphemeral app, so we can return the result without
6403                        // further processing.
6404                        return applyPostResolutionFilter(result, instantAppPkgName,
6405                                allowDynamicSplits, filterCallingUid, userId);
6406                    }
6407                    // We have more than one candidate (combining results from current and parent
6408                    // profile), so we need filtering and sorting.
6409                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6410                            intent, flags, result, xpDomainInfo, userId);
6411                    sortResult = true;
6412                }
6413            } else {
6414                final PackageParser.Package pkg = mPackages.get(pkgName);
6415                result = null;
6416                if (pkg != null) {
6417                    result = filterIfNotSystemUser(
6418                            mActivities.queryIntentForPackage(
6419                                    intent, resolvedType, flags, pkg.activities, userId),
6420                            userId);
6421                }
6422                if (result == null || result.size() == 0) {
6423                    // the caller wants to resolve for a particular package; however, there
6424                    // were no installed results, so, try to find an ephemeral result
6425                    addEphemeral = !ephemeralDisabled
6426                            && isInstantAppAllowed(
6427                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6428                    if (result == null) {
6429                        result = new ArrayList<>();
6430                    }
6431                }
6432            }
6433        }
6434        if (addEphemeral) {
6435            result = maybeAddInstantAppInstaller(
6436                    result, intent, resolvedType, flags, userId, resolveForStart);
6437        }
6438        if (sortResult) {
6439            Collections.sort(result, mResolvePrioritySorter);
6440        }
6441        return applyPostResolutionFilter(
6442                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6443    }
6444
6445    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6446            String resolvedType, int flags, int userId, boolean resolveForStart) {
6447        // first, check to see if we've got an instant app already installed
6448        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6449        ResolveInfo localInstantApp = null;
6450        boolean blockResolution = false;
6451        if (!alreadyResolvedLocally) {
6452            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6453                    flags
6454                        | PackageManager.GET_RESOLVED_FILTER
6455                        | PackageManager.MATCH_INSTANT
6456                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6457                    userId);
6458            for (int i = instantApps.size() - 1; i >= 0; --i) {
6459                final ResolveInfo info = instantApps.get(i);
6460                final String packageName = info.activityInfo.packageName;
6461                final PackageSetting ps = mSettings.mPackages.get(packageName);
6462                if (ps.getInstantApp(userId)) {
6463                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6464                    final int status = (int)(packedStatus >> 32);
6465                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6466                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6467                        // there's a local instant application installed, but, the user has
6468                        // chosen to never use it; skip resolution and don't acknowledge
6469                        // an instant application is even available
6470                        if (DEBUG_EPHEMERAL) {
6471                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6472                        }
6473                        blockResolution = true;
6474                        break;
6475                    } else {
6476                        // we have a locally installed instant application; skip resolution
6477                        // but acknowledge there's an instant application available
6478                        if (DEBUG_EPHEMERAL) {
6479                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6480                        }
6481                        localInstantApp = info;
6482                        break;
6483                    }
6484                }
6485            }
6486        }
6487        // no app installed, let's see if one's available
6488        AuxiliaryResolveInfo auxiliaryResponse = null;
6489        if (!blockResolution) {
6490            if (localInstantApp == null) {
6491                // we don't have an instant app locally, resolve externally
6492                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6493                final InstantAppRequest requestObject = new InstantAppRequest(
6494                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6495                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6496                        resolveForStart);
6497                auxiliaryResponse =
6498                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6499                                mContext, mInstantAppResolverConnection, requestObject);
6500                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6501            } else {
6502                // we have an instant application locally, but, we can't admit that since
6503                // callers shouldn't be able to determine prior browsing. create a dummy
6504                // auxiliary response so the downstream code behaves as if there's an
6505                // instant application available externally. when it comes time to start
6506                // the instant application, we'll do the right thing.
6507                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6508                auxiliaryResponse = new AuxiliaryResolveInfo(
6509                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
6510                        ai.versionCode, null /*failureIntent*/);
6511            }
6512        }
6513        if (auxiliaryResponse != null) {
6514            if (DEBUG_EPHEMERAL) {
6515                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6516            }
6517            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6518            final PackageSetting ps =
6519                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6520            if (ps != null) {
6521                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6522                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6523                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6524                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6525                // make sure this resolver is the default
6526                ephemeralInstaller.isDefault = true;
6527                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6528                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6529                // add a non-generic filter
6530                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6531                ephemeralInstaller.filter.addDataPath(
6532                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6533                ephemeralInstaller.isInstantAppAvailable = true;
6534                result.add(ephemeralInstaller);
6535            }
6536        }
6537        return result;
6538    }
6539
6540    private static class CrossProfileDomainInfo {
6541        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6542        ResolveInfo resolveInfo;
6543        /* Best domain verification status of the activities found in the other profile */
6544        int bestDomainVerificationStatus;
6545    }
6546
6547    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6548            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6549        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6550                sourceUserId)) {
6551            return null;
6552        }
6553        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6554                resolvedType, flags, parentUserId);
6555
6556        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6557            return null;
6558        }
6559        CrossProfileDomainInfo result = null;
6560        int size = resultTargetUser.size();
6561        for (int i = 0; i < size; i++) {
6562            ResolveInfo riTargetUser = resultTargetUser.get(i);
6563            // Intent filter verification is only for filters that specify a host. So don't return
6564            // those that handle all web uris.
6565            if (riTargetUser.handleAllWebDataURI) {
6566                continue;
6567            }
6568            String packageName = riTargetUser.activityInfo.packageName;
6569            PackageSetting ps = mSettings.mPackages.get(packageName);
6570            if (ps == null) {
6571                continue;
6572            }
6573            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6574            int status = (int)(verificationState >> 32);
6575            if (result == null) {
6576                result = new CrossProfileDomainInfo();
6577                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6578                        sourceUserId, parentUserId);
6579                result.bestDomainVerificationStatus = status;
6580            } else {
6581                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6582                        result.bestDomainVerificationStatus);
6583            }
6584        }
6585        // Don't consider matches with status NEVER across profiles.
6586        if (result != null && result.bestDomainVerificationStatus
6587                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6588            return null;
6589        }
6590        return result;
6591    }
6592
6593    /**
6594     * Verification statuses are ordered from the worse to the best, except for
6595     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6596     */
6597    private int bestDomainVerificationStatus(int status1, int status2) {
6598        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6599            return status2;
6600        }
6601        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6602            return status1;
6603        }
6604        return (int) MathUtils.max(status1, status2);
6605    }
6606
6607    private boolean isUserEnabled(int userId) {
6608        long callingId = Binder.clearCallingIdentity();
6609        try {
6610            UserInfo userInfo = sUserManager.getUserInfo(userId);
6611            return userInfo != null && userInfo.isEnabled();
6612        } finally {
6613            Binder.restoreCallingIdentity(callingId);
6614        }
6615    }
6616
6617    /**
6618     * Filter out activities with systemUserOnly flag set, when current user is not System.
6619     *
6620     * @return filtered list
6621     */
6622    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6623        if (userId == UserHandle.USER_SYSTEM) {
6624            return resolveInfos;
6625        }
6626        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6627            ResolveInfo info = resolveInfos.get(i);
6628            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6629                resolveInfos.remove(i);
6630            }
6631        }
6632        return resolveInfos;
6633    }
6634
6635    /**
6636     * Filters out ephemeral activities.
6637     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6638     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6639     *
6640     * @param resolveInfos The pre-filtered list of resolved activities
6641     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6642     *          is performed.
6643     * @return A filtered list of resolved activities.
6644     */
6645    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6646            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
6647        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6648            final ResolveInfo info = resolveInfos.get(i);
6649            // allow activities that are defined in the provided package
6650            if (allowDynamicSplits
6651                    && info.activityInfo.splitName != null
6652                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6653                            info.activityInfo.splitName)) {
6654                if (mInstantAppInstallerInfo == null) {
6655                    if (DEBUG_INSTALL) {
6656                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6657                    }
6658                    resolveInfos.remove(i);
6659                    continue;
6660                }
6661                // requested activity is defined in a split that hasn't been installed yet.
6662                // add the installer to the resolve list
6663                if (DEBUG_INSTALL) {
6664                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6665                }
6666                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6667                final ComponentName installFailureActivity = findInstallFailureActivity(
6668                        info.activityInfo.packageName,  filterCallingUid, userId);
6669                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6670                        info.activityInfo.packageName, info.activityInfo.splitName,
6671                        installFailureActivity,
6672                        info.activityInfo.applicationInfo.versionCode,
6673                        null /*failureIntent*/);
6674                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6675                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6676                // add a non-generic filter
6677                installerInfo.filter = new IntentFilter();
6678
6679                // This resolve info may appear in the chooser UI, so let us make it
6680                // look as the one it replaces as far as the user is concerned which
6681                // requires loading the correct label and icon for the resolve info.
6682                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6683                installerInfo.labelRes = info.resolveLabelResId();
6684                installerInfo.icon = info.resolveIconResId();
6685
6686                // propagate priority/preferred order/default
6687                installerInfo.priority = info.priority;
6688                installerInfo.preferredOrder = info.preferredOrder;
6689                installerInfo.isDefault = info.isDefault;
6690                resolveInfos.set(i, installerInfo);
6691                continue;
6692            }
6693            // caller is a full app, don't need to apply any other filtering
6694            if (ephemeralPkgName == null) {
6695                continue;
6696            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6697                // caller is same app; don't need to apply any other filtering
6698                continue;
6699            }
6700            // allow activities that have been explicitly exposed to ephemeral apps
6701            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6702            if (!isEphemeralApp
6703                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6704                continue;
6705            }
6706            resolveInfos.remove(i);
6707        }
6708        return resolveInfos;
6709    }
6710
6711    /**
6712     * Returns the activity component that can handle install failures.
6713     * <p>By default, the instant application installer handles failures. However, an
6714     * application may want to handle failures on its own. Applications do this by
6715     * creating an activity with an intent filter that handles the action
6716     * {@link Intent#ACTION_INSTALL_FAILURE}.
6717     */
6718    private @Nullable ComponentName findInstallFailureActivity(
6719            String packageName, int filterCallingUid, int userId) {
6720        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6721        failureActivityIntent.setPackage(packageName);
6722        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6723        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6724                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6725                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6726        final int NR = result.size();
6727        if (NR > 0) {
6728            for (int i = 0; i < NR; i++) {
6729                final ResolveInfo info = result.get(i);
6730                if (info.activityInfo.splitName != null) {
6731                    continue;
6732                }
6733                return new ComponentName(packageName, info.activityInfo.name);
6734            }
6735        }
6736        return null;
6737    }
6738
6739    /**
6740     * @param resolveInfos list of resolve infos in descending priority order
6741     * @return if the list contains a resolve info with non-negative priority
6742     */
6743    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6744        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6745    }
6746
6747    private static boolean hasWebURI(Intent intent) {
6748        if (intent.getData() == null) {
6749            return false;
6750        }
6751        final String scheme = intent.getScheme();
6752        if (TextUtils.isEmpty(scheme)) {
6753            return false;
6754        }
6755        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6756    }
6757
6758    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6759            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6760            int userId) {
6761        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6762
6763        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6764            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6765                    candidates.size());
6766        }
6767
6768        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6769        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6770        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6771        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6772        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6773        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6774
6775        synchronized (mPackages) {
6776            final int count = candidates.size();
6777            // First, try to use linked apps. Partition the candidates into four lists:
6778            // one for the final results, one for the "do not use ever", one for "undefined status"
6779            // and finally one for "browser app type".
6780            for (int n=0; n<count; n++) {
6781                ResolveInfo info = candidates.get(n);
6782                String packageName = info.activityInfo.packageName;
6783                PackageSetting ps = mSettings.mPackages.get(packageName);
6784                if (ps != null) {
6785                    // Add to the special match all list (Browser use case)
6786                    if (info.handleAllWebDataURI) {
6787                        matchAllList.add(info);
6788                        continue;
6789                    }
6790                    // Try to get the status from User settings first
6791                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6792                    int status = (int)(packedStatus >> 32);
6793                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6794                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6795                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6796                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6797                                    + " : linkgen=" + linkGeneration);
6798                        }
6799                        // Use link-enabled generation as preferredOrder, i.e.
6800                        // prefer newly-enabled over earlier-enabled.
6801                        info.preferredOrder = linkGeneration;
6802                        alwaysList.add(info);
6803                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6804                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6805                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6806                        }
6807                        neverList.add(info);
6808                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6809                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6810                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6811                        }
6812                        alwaysAskList.add(info);
6813                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6814                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6815                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6816                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6817                        }
6818                        undefinedList.add(info);
6819                    }
6820                }
6821            }
6822
6823            // We'll want to include browser possibilities in a few cases
6824            boolean includeBrowser = false;
6825
6826            // First try to add the "always" resolution(s) for the current user, if any
6827            if (alwaysList.size() > 0) {
6828                result.addAll(alwaysList);
6829            } else {
6830                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6831                result.addAll(undefinedList);
6832                // Maybe add one for the other profile.
6833                if (xpDomainInfo != null && (
6834                        xpDomainInfo.bestDomainVerificationStatus
6835                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6836                    result.add(xpDomainInfo.resolveInfo);
6837                }
6838                includeBrowser = true;
6839            }
6840
6841            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6842            // If there were 'always' entries their preferred order has been set, so we also
6843            // back that off to make the alternatives equivalent
6844            if (alwaysAskList.size() > 0) {
6845                for (ResolveInfo i : result) {
6846                    i.preferredOrder = 0;
6847                }
6848                result.addAll(alwaysAskList);
6849                includeBrowser = true;
6850            }
6851
6852            if (includeBrowser) {
6853                // Also add browsers (all of them or only the default one)
6854                if (DEBUG_DOMAIN_VERIFICATION) {
6855                    Slog.v(TAG, "   ...including browsers in candidate set");
6856                }
6857                if ((matchFlags & MATCH_ALL) != 0) {
6858                    result.addAll(matchAllList);
6859                } else {
6860                    // Browser/generic handling case.  If there's a default browser, go straight
6861                    // to that (but only if there is no other higher-priority match).
6862                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6863                    int maxMatchPrio = 0;
6864                    ResolveInfo defaultBrowserMatch = null;
6865                    final int numCandidates = matchAllList.size();
6866                    for (int n = 0; n < numCandidates; n++) {
6867                        ResolveInfo info = matchAllList.get(n);
6868                        // track the highest overall match priority...
6869                        if (info.priority > maxMatchPrio) {
6870                            maxMatchPrio = info.priority;
6871                        }
6872                        // ...and the highest-priority default browser match
6873                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6874                            if (defaultBrowserMatch == null
6875                                    || (defaultBrowserMatch.priority < info.priority)) {
6876                                if (debug) {
6877                                    Slog.v(TAG, "Considering default browser match " + info);
6878                                }
6879                                defaultBrowserMatch = info;
6880                            }
6881                        }
6882                    }
6883                    if (defaultBrowserMatch != null
6884                            && defaultBrowserMatch.priority >= maxMatchPrio
6885                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6886                    {
6887                        if (debug) {
6888                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6889                        }
6890                        result.add(defaultBrowserMatch);
6891                    } else {
6892                        result.addAll(matchAllList);
6893                    }
6894                }
6895
6896                // If there is nothing selected, add all candidates and remove the ones that the user
6897                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6898                if (result.size() == 0) {
6899                    result.addAll(candidates);
6900                    result.removeAll(neverList);
6901                }
6902            }
6903        }
6904        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6905            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6906                    result.size());
6907            for (ResolveInfo info : result) {
6908                Slog.v(TAG, "  + " + info.activityInfo);
6909            }
6910        }
6911        return result;
6912    }
6913
6914    // Returns a packed value as a long:
6915    //
6916    // high 'int'-sized word: link status: undefined/ask/never/always.
6917    // low 'int'-sized word: relative priority among 'always' results.
6918    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6919        long result = ps.getDomainVerificationStatusForUser(userId);
6920        // if none available, get the master status
6921        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6922            if (ps.getIntentFilterVerificationInfo() != null) {
6923                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6924            }
6925        }
6926        return result;
6927    }
6928
6929    private ResolveInfo querySkipCurrentProfileIntents(
6930            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6931            int flags, int sourceUserId) {
6932        if (matchingFilters != null) {
6933            int size = matchingFilters.size();
6934            for (int i = 0; i < size; i ++) {
6935                CrossProfileIntentFilter filter = matchingFilters.get(i);
6936                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6937                    // Checking if there are activities in the target user that can handle the
6938                    // intent.
6939                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6940                            resolvedType, flags, sourceUserId);
6941                    if (resolveInfo != null) {
6942                        return resolveInfo;
6943                    }
6944                }
6945            }
6946        }
6947        return null;
6948    }
6949
6950    // Return matching ResolveInfo in target user if any.
6951    private ResolveInfo queryCrossProfileIntents(
6952            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6953            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6954        if (matchingFilters != null) {
6955            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6956            // match the same intent. For performance reasons, it is better not to
6957            // run queryIntent twice for the same userId
6958            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6959            int size = matchingFilters.size();
6960            for (int i = 0; i < size; i++) {
6961                CrossProfileIntentFilter filter = matchingFilters.get(i);
6962                int targetUserId = filter.getTargetUserId();
6963                boolean skipCurrentProfile =
6964                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6965                boolean skipCurrentProfileIfNoMatchFound =
6966                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6967                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6968                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6969                    // Checking if there are activities in the target user that can handle the
6970                    // intent.
6971                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6972                            resolvedType, flags, sourceUserId);
6973                    if (resolveInfo != null) return resolveInfo;
6974                    alreadyTriedUserIds.put(targetUserId, true);
6975                }
6976            }
6977        }
6978        return null;
6979    }
6980
6981    /**
6982     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6983     * will forward the intent to the filter's target user.
6984     * Otherwise, returns null.
6985     */
6986    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6987            String resolvedType, int flags, int sourceUserId) {
6988        int targetUserId = filter.getTargetUserId();
6989        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6990                resolvedType, flags, targetUserId);
6991        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6992            // If all the matches in the target profile are suspended, return null.
6993            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6994                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6995                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6996                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6997                            targetUserId);
6998                }
6999            }
7000        }
7001        return null;
7002    }
7003
7004    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7005            int sourceUserId, int targetUserId) {
7006        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7007        long ident = Binder.clearCallingIdentity();
7008        boolean targetIsProfile;
7009        try {
7010            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7011        } finally {
7012            Binder.restoreCallingIdentity(ident);
7013        }
7014        String className;
7015        if (targetIsProfile) {
7016            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7017        } else {
7018            className = FORWARD_INTENT_TO_PARENT;
7019        }
7020        ComponentName forwardingActivityComponentName = new ComponentName(
7021                mAndroidApplication.packageName, className);
7022        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7023                sourceUserId);
7024        if (!targetIsProfile) {
7025            forwardingActivityInfo.showUserIcon = targetUserId;
7026            forwardingResolveInfo.noResourceId = true;
7027        }
7028        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7029        forwardingResolveInfo.priority = 0;
7030        forwardingResolveInfo.preferredOrder = 0;
7031        forwardingResolveInfo.match = 0;
7032        forwardingResolveInfo.isDefault = true;
7033        forwardingResolveInfo.filter = filter;
7034        forwardingResolveInfo.targetUserId = targetUserId;
7035        return forwardingResolveInfo;
7036    }
7037
7038    @Override
7039    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7040            Intent[] specifics, String[] specificTypes, Intent intent,
7041            String resolvedType, int flags, int userId) {
7042        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7043                specificTypes, intent, resolvedType, flags, userId));
7044    }
7045
7046    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7047            Intent[] specifics, String[] specificTypes, Intent intent,
7048            String resolvedType, int flags, int userId) {
7049        if (!sUserManager.exists(userId)) return Collections.emptyList();
7050        final int callingUid = Binder.getCallingUid();
7051        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7052                false /*includeInstantApps*/);
7053        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7054                false /*requireFullPermission*/, false /*checkShell*/,
7055                "query intent activity options");
7056        final String resultsAction = intent.getAction();
7057
7058        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7059                | PackageManager.GET_RESOLVED_FILTER, userId);
7060
7061        if (DEBUG_INTENT_MATCHING) {
7062            Log.v(TAG, "Query " + intent + ": " + results);
7063        }
7064
7065        int specificsPos = 0;
7066        int N;
7067
7068        // todo: note that the algorithm used here is O(N^2).  This
7069        // isn't a problem in our current environment, but if we start running
7070        // into situations where we have more than 5 or 10 matches then this
7071        // should probably be changed to something smarter...
7072
7073        // First we go through and resolve each of the specific items
7074        // that were supplied, taking care of removing any corresponding
7075        // duplicate items in the generic resolve list.
7076        if (specifics != null) {
7077            for (int i=0; i<specifics.length; i++) {
7078                final Intent sintent = specifics[i];
7079                if (sintent == null) {
7080                    continue;
7081                }
7082
7083                if (DEBUG_INTENT_MATCHING) {
7084                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7085                }
7086
7087                String action = sintent.getAction();
7088                if (resultsAction != null && resultsAction.equals(action)) {
7089                    // If this action was explicitly requested, then don't
7090                    // remove things that have it.
7091                    action = null;
7092                }
7093
7094                ResolveInfo ri = null;
7095                ActivityInfo ai = null;
7096
7097                ComponentName comp = sintent.getComponent();
7098                if (comp == null) {
7099                    ri = resolveIntent(
7100                        sintent,
7101                        specificTypes != null ? specificTypes[i] : null,
7102                            flags, userId);
7103                    if (ri == null) {
7104                        continue;
7105                    }
7106                    if (ri == mResolveInfo) {
7107                        // ACK!  Must do something better with this.
7108                    }
7109                    ai = ri.activityInfo;
7110                    comp = new ComponentName(ai.applicationInfo.packageName,
7111                            ai.name);
7112                } else {
7113                    ai = getActivityInfo(comp, flags, userId);
7114                    if (ai == null) {
7115                        continue;
7116                    }
7117                }
7118
7119                // Look for any generic query activities that are duplicates
7120                // of this specific one, and remove them from the results.
7121                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7122                N = results.size();
7123                int j;
7124                for (j=specificsPos; j<N; j++) {
7125                    ResolveInfo sri = results.get(j);
7126                    if ((sri.activityInfo.name.equals(comp.getClassName())
7127                            && sri.activityInfo.applicationInfo.packageName.equals(
7128                                    comp.getPackageName()))
7129                        || (action != null && sri.filter.matchAction(action))) {
7130                        results.remove(j);
7131                        if (DEBUG_INTENT_MATCHING) Log.v(
7132                            TAG, "Removing duplicate item from " + j
7133                            + " due to specific " + specificsPos);
7134                        if (ri == null) {
7135                            ri = sri;
7136                        }
7137                        j--;
7138                        N--;
7139                    }
7140                }
7141
7142                // Add this specific item to its proper place.
7143                if (ri == null) {
7144                    ri = new ResolveInfo();
7145                    ri.activityInfo = ai;
7146                }
7147                results.add(specificsPos, ri);
7148                ri.specificIndex = i;
7149                specificsPos++;
7150            }
7151        }
7152
7153        // Now we go through the remaining generic results and remove any
7154        // duplicate actions that are found here.
7155        N = results.size();
7156        for (int i=specificsPos; i<N-1; i++) {
7157            final ResolveInfo rii = results.get(i);
7158            if (rii.filter == null) {
7159                continue;
7160            }
7161
7162            // Iterate over all of the actions of this result's intent
7163            // filter...  typically this should be just one.
7164            final Iterator<String> it = rii.filter.actionsIterator();
7165            if (it == null) {
7166                continue;
7167            }
7168            while (it.hasNext()) {
7169                final String action = it.next();
7170                if (resultsAction != null && resultsAction.equals(action)) {
7171                    // If this action was explicitly requested, then don't
7172                    // remove things that have it.
7173                    continue;
7174                }
7175                for (int j=i+1; j<N; j++) {
7176                    final ResolveInfo rij = results.get(j);
7177                    if (rij.filter != null && rij.filter.hasAction(action)) {
7178                        results.remove(j);
7179                        if (DEBUG_INTENT_MATCHING) Log.v(
7180                            TAG, "Removing duplicate item from " + j
7181                            + " due to action " + action + " at " + i);
7182                        j--;
7183                        N--;
7184                    }
7185                }
7186            }
7187
7188            // If the caller didn't request filter information, drop it now
7189            // so we don't have to marshall/unmarshall it.
7190            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7191                rii.filter = null;
7192            }
7193        }
7194
7195        // Filter out the caller activity if so requested.
7196        if (caller != null) {
7197            N = results.size();
7198            for (int i=0; i<N; i++) {
7199                ActivityInfo ainfo = results.get(i).activityInfo;
7200                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7201                        && caller.getClassName().equals(ainfo.name)) {
7202                    results.remove(i);
7203                    break;
7204                }
7205            }
7206        }
7207
7208        // If the caller didn't request filter information,
7209        // drop them now so we don't have to
7210        // marshall/unmarshall it.
7211        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7212            N = results.size();
7213            for (int i=0; i<N; i++) {
7214                results.get(i).filter = null;
7215            }
7216        }
7217
7218        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7219        return results;
7220    }
7221
7222    @Override
7223    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7224            String resolvedType, int flags, int userId) {
7225        return new ParceledListSlice<>(
7226                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7227                        false /*allowDynamicSplits*/));
7228    }
7229
7230    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7231            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7232        if (!sUserManager.exists(userId)) return Collections.emptyList();
7233        final int callingUid = Binder.getCallingUid();
7234        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7235                false /*requireFullPermission*/, false /*checkShell*/,
7236                "query intent receivers");
7237        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7238        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7239                false /*includeInstantApps*/);
7240        ComponentName comp = intent.getComponent();
7241        if (comp == null) {
7242            if (intent.getSelector() != null) {
7243                intent = intent.getSelector();
7244                comp = intent.getComponent();
7245            }
7246        }
7247        if (comp != null) {
7248            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7249            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7250            if (ai != null) {
7251                // When specifying an explicit component, we prevent the activity from being
7252                // used when either 1) the calling package is normal and the activity is within
7253                // an instant application or 2) the calling package is ephemeral and the
7254                // activity is not visible to instant applications.
7255                final boolean matchInstantApp =
7256                        (flags & PackageManager.MATCH_INSTANT) != 0;
7257                final boolean matchVisibleToInstantAppOnly =
7258                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7259                final boolean matchExplicitlyVisibleOnly =
7260                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7261                final boolean isCallerInstantApp =
7262                        instantAppPkgName != null;
7263                final boolean isTargetSameInstantApp =
7264                        comp.getPackageName().equals(instantAppPkgName);
7265                final boolean isTargetInstantApp =
7266                        (ai.applicationInfo.privateFlags
7267                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7268                final boolean isTargetVisibleToInstantApp =
7269                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7270                final boolean isTargetExplicitlyVisibleToInstantApp =
7271                        isTargetVisibleToInstantApp
7272                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7273                final boolean isTargetHiddenFromInstantApp =
7274                        !isTargetVisibleToInstantApp
7275                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7276                final boolean blockResolution =
7277                        !isTargetSameInstantApp
7278                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7279                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7280                                        && isTargetHiddenFromInstantApp));
7281                if (!blockResolution) {
7282                    ResolveInfo ri = new ResolveInfo();
7283                    ri.activityInfo = ai;
7284                    list.add(ri);
7285                }
7286            }
7287            return applyPostResolutionFilter(
7288                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7289        }
7290
7291        // reader
7292        synchronized (mPackages) {
7293            String pkgName = intent.getPackage();
7294            if (pkgName == null) {
7295                final List<ResolveInfo> result =
7296                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7297                return applyPostResolutionFilter(
7298                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7299            }
7300            final PackageParser.Package pkg = mPackages.get(pkgName);
7301            if (pkg != null) {
7302                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7303                        intent, resolvedType, flags, pkg.receivers, userId);
7304                return applyPostResolutionFilter(
7305                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7306            }
7307            return Collections.emptyList();
7308        }
7309    }
7310
7311    @Override
7312    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7313        final int callingUid = Binder.getCallingUid();
7314        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7315    }
7316
7317    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7318            int userId, int callingUid) {
7319        if (!sUserManager.exists(userId)) return null;
7320        flags = updateFlagsForResolve(
7321                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7322        List<ResolveInfo> query = queryIntentServicesInternal(
7323                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7324        if (query != null) {
7325            if (query.size() >= 1) {
7326                // If there is more than one service with the same priority,
7327                // just arbitrarily pick the first one.
7328                return query.get(0);
7329            }
7330        }
7331        return null;
7332    }
7333
7334    @Override
7335    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7336            String resolvedType, int flags, int userId) {
7337        final int callingUid = Binder.getCallingUid();
7338        return new ParceledListSlice<>(queryIntentServicesInternal(
7339                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7340    }
7341
7342    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7343            String resolvedType, int flags, int userId, int callingUid,
7344            boolean includeInstantApps) {
7345        if (!sUserManager.exists(userId)) return Collections.emptyList();
7346        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7347                false /*requireFullPermission*/, false /*checkShell*/,
7348                "query intent receivers");
7349        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7350        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7351        ComponentName comp = intent.getComponent();
7352        if (comp == null) {
7353            if (intent.getSelector() != null) {
7354                intent = intent.getSelector();
7355                comp = intent.getComponent();
7356            }
7357        }
7358        if (comp != null) {
7359            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7360            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7361            if (si != null) {
7362                // When specifying an explicit component, we prevent the service from being
7363                // used when either 1) the service is in an instant application and the
7364                // caller is not the same instant application or 2) the calling package is
7365                // ephemeral and the activity is not visible to ephemeral applications.
7366                final boolean matchInstantApp =
7367                        (flags & PackageManager.MATCH_INSTANT) != 0;
7368                final boolean matchVisibleToInstantAppOnly =
7369                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7370                final boolean isCallerInstantApp =
7371                        instantAppPkgName != null;
7372                final boolean isTargetSameInstantApp =
7373                        comp.getPackageName().equals(instantAppPkgName);
7374                final boolean isTargetInstantApp =
7375                        (si.applicationInfo.privateFlags
7376                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7377                final boolean isTargetHiddenFromInstantApp =
7378                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7379                final boolean blockResolution =
7380                        !isTargetSameInstantApp
7381                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7382                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7383                                        && isTargetHiddenFromInstantApp));
7384                if (!blockResolution) {
7385                    final ResolveInfo ri = new ResolveInfo();
7386                    ri.serviceInfo = si;
7387                    list.add(ri);
7388                }
7389            }
7390            return list;
7391        }
7392
7393        // reader
7394        synchronized (mPackages) {
7395            String pkgName = intent.getPackage();
7396            if (pkgName == null) {
7397                return applyPostServiceResolutionFilter(
7398                        mServices.queryIntent(intent, resolvedType, flags, userId),
7399                        instantAppPkgName);
7400            }
7401            final PackageParser.Package pkg = mPackages.get(pkgName);
7402            if (pkg != null) {
7403                return applyPostServiceResolutionFilter(
7404                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7405                                userId),
7406                        instantAppPkgName);
7407            }
7408            return Collections.emptyList();
7409        }
7410    }
7411
7412    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7413            String instantAppPkgName) {
7414        if (instantAppPkgName == null) {
7415            return resolveInfos;
7416        }
7417        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7418            final ResolveInfo info = resolveInfos.get(i);
7419            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7420            // allow services that are defined in the provided package
7421            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7422                if (info.serviceInfo.splitName != null
7423                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7424                                info.serviceInfo.splitName)) {
7425                    // requested service is defined in a split that hasn't been installed yet.
7426                    // add the installer to the resolve list
7427                    if (DEBUG_EPHEMERAL) {
7428                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7429                    }
7430                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7431                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7432                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7433                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
7434                            null /*failureIntent*/);
7435                    // make sure this resolver is the default
7436                    installerInfo.isDefault = true;
7437                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7438                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7439                    // add a non-generic filter
7440                    installerInfo.filter = new IntentFilter();
7441                    // load resources from the correct package
7442                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7443                    resolveInfos.set(i, installerInfo);
7444                }
7445                continue;
7446            }
7447            // allow services that have been explicitly exposed to ephemeral apps
7448            if (!isEphemeralApp
7449                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7450                continue;
7451            }
7452            resolveInfos.remove(i);
7453        }
7454        return resolveInfos;
7455    }
7456
7457    @Override
7458    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7459            String resolvedType, int flags, int userId) {
7460        return new ParceledListSlice<>(
7461                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7462    }
7463
7464    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7465            Intent intent, String resolvedType, int flags, int userId) {
7466        if (!sUserManager.exists(userId)) return Collections.emptyList();
7467        final int callingUid = Binder.getCallingUid();
7468        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7469        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7470                false /*includeInstantApps*/);
7471        ComponentName comp = intent.getComponent();
7472        if (comp == null) {
7473            if (intent.getSelector() != null) {
7474                intent = intent.getSelector();
7475                comp = intent.getComponent();
7476            }
7477        }
7478        if (comp != null) {
7479            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7480            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7481            if (pi != null) {
7482                // When specifying an explicit component, we prevent the provider from being
7483                // used when either 1) the provider is in an instant application and the
7484                // caller is not the same instant application or 2) the calling package is an
7485                // instant application and the provider is not visible to instant applications.
7486                final boolean matchInstantApp =
7487                        (flags & PackageManager.MATCH_INSTANT) != 0;
7488                final boolean matchVisibleToInstantAppOnly =
7489                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7490                final boolean isCallerInstantApp =
7491                        instantAppPkgName != null;
7492                final boolean isTargetSameInstantApp =
7493                        comp.getPackageName().equals(instantAppPkgName);
7494                final boolean isTargetInstantApp =
7495                        (pi.applicationInfo.privateFlags
7496                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7497                final boolean isTargetHiddenFromInstantApp =
7498                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7499                final boolean blockResolution =
7500                        !isTargetSameInstantApp
7501                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7502                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7503                                        && isTargetHiddenFromInstantApp));
7504                if (!blockResolution) {
7505                    final ResolveInfo ri = new ResolveInfo();
7506                    ri.providerInfo = pi;
7507                    list.add(ri);
7508                }
7509            }
7510            return list;
7511        }
7512
7513        // reader
7514        synchronized (mPackages) {
7515            String pkgName = intent.getPackage();
7516            if (pkgName == null) {
7517                return applyPostContentProviderResolutionFilter(
7518                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7519                        instantAppPkgName);
7520            }
7521            final PackageParser.Package pkg = mPackages.get(pkgName);
7522            if (pkg != null) {
7523                return applyPostContentProviderResolutionFilter(
7524                        mProviders.queryIntentForPackage(
7525                        intent, resolvedType, flags, pkg.providers, userId),
7526                        instantAppPkgName);
7527            }
7528            return Collections.emptyList();
7529        }
7530    }
7531
7532    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7533            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7534        if (instantAppPkgName == null) {
7535            return resolveInfos;
7536        }
7537        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7538            final ResolveInfo info = resolveInfos.get(i);
7539            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7540            // allow providers that are defined in the provided package
7541            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7542                if (info.providerInfo.splitName != null
7543                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7544                                info.providerInfo.splitName)) {
7545                    // requested provider is defined in a split that hasn't been installed yet.
7546                    // add the installer to the resolve list
7547                    if (DEBUG_EPHEMERAL) {
7548                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7549                    }
7550                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7551                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7552                            info.providerInfo.packageName, info.providerInfo.splitName,
7553                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
7554                            null /*failureIntent*/);
7555                    // make sure this resolver is the default
7556                    installerInfo.isDefault = true;
7557                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7558                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7559                    // add a non-generic filter
7560                    installerInfo.filter = new IntentFilter();
7561                    // load resources from the correct package
7562                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7563                    resolveInfos.set(i, installerInfo);
7564                }
7565                continue;
7566            }
7567            // allow providers that have been explicitly exposed to instant applications
7568            if (!isEphemeralApp
7569                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7570                continue;
7571            }
7572            resolveInfos.remove(i);
7573        }
7574        return resolveInfos;
7575    }
7576
7577    @Override
7578    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7579        final int callingUid = Binder.getCallingUid();
7580        if (getInstantAppPackageName(callingUid) != null) {
7581            return ParceledListSlice.emptyList();
7582        }
7583        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7584        flags = updateFlagsForPackage(flags, userId, null);
7585        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7586        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7587                true /* requireFullPermission */, false /* checkShell */,
7588                "get installed packages");
7589
7590        // writer
7591        synchronized (mPackages) {
7592            ArrayList<PackageInfo> list;
7593            if (listUninstalled) {
7594                list = new ArrayList<>(mSettings.mPackages.size());
7595                for (PackageSetting ps : mSettings.mPackages.values()) {
7596                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7597                        continue;
7598                    }
7599                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7600                        continue;
7601                    }
7602                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7603                    if (pi != null) {
7604                        list.add(pi);
7605                    }
7606                }
7607            } else {
7608                list = new ArrayList<>(mPackages.size());
7609                for (PackageParser.Package p : mPackages.values()) {
7610                    final PackageSetting ps = (PackageSetting) p.mExtras;
7611                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7612                        continue;
7613                    }
7614                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7615                        continue;
7616                    }
7617                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7618                            p.mExtras, flags, userId);
7619                    if (pi != null) {
7620                        list.add(pi);
7621                    }
7622                }
7623            }
7624
7625            return new ParceledListSlice<>(list);
7626        }
7627    }
7628
7629    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7630            String[] permissions, boolean[] tmp, int flags, int userId) {
7631        int numMatch = 0;
7632        final PermissionsState permissionsState = ps.getPermissionsState();
7633        for (int i=0; i<permissions.length; i++) {
7634            final String permission = permissions[i];
7635            if (permissionsState.hasPermission(permission, userId)) {
7636                tmp[i] = true;
7637                numMatch++;
7638            } else {
7639                tmp[i] = false;
7640            }
7641        }
7642        if (numMatch == 0) {
7643            return;
7644        }
7645        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7646
7647        // The above might return null in cases of uninstalled apps or install-state
7648        // skew across users/profiles.
7649        if (pi != null) {
7650            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7651                if (numMatch == permissions.length) {
7652                    pi.requestedPermissions = permissions;
7653                } else {
7654                    pi.requestedPermissions = new String[numMatch];
7655                    numMatch = 0;
7656                    for (int i=0; i<permissions.length; i++) {
7657                        if (tmp[i]) {
7658                            pi.requestedPermissions[numMatch] = permissions[i];
7659                            numMatch++;
7660                        }
7661                    }
7662                }
7663            }
7664            list.add(pi);
7665        }
7666    }
7667
7668    @Override
7669    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7670            String[] permissions, int flags, int userId) {
7671        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7672        flags = updateFlagsForPackage(flags, userId, permissions);
7673        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7674                true /* requireFullPermission */, false /* checkShell */,
7675                "get packages holding permissions");
7676        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7677
7678        // writer
7679        synchronized (mPackages) {
7680            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7681            boolean[] tmpBools = new boolean[permissions.length];
7682            if (listUninstalled) {
7683                for (PackageSetting ps : mSettings.mPackages.values()) {
7684                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7685                            userId);
7686                }
7687            } else {
7688                for (PackageParser.Package pkg : mPackages.values()) {
7689                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7690                    if (ps != null) {
7691                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7692                                userId);
7693                    }
7694                }
7695            }
7696
7697            return new ParceledListSlice<PackageInfo>(list);
7698        }
7699    }
7700
7701    @Override
7702    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7703        final int callingUid = Binder.getCallingUid();
7704        if (getInstantAppPackageName(callingUid) != null) {
7705            return ParceledListSlice.emptyList();
7706        }
7707        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7708        flags = updateFlagsForApplication(flags, userId, null);
7709        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7710
7711        // writer
7712        synchronized (mPackages) {
7713            ArrayList<ApplicationInfo> list;
7714            if (listUninstalled) {
7715                list = new ArrayList<>(mSettings.mPackages.size());
7716                for (PackageSetting ps : mSettings.mPackages.values()) {
7717                    ApplicationInfo ai;
7718                    int effectiveFlags = flags;
7719                    if (ps.isSystem()) {
7720                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7721                    }
7722                    if (ps.pkg != null) {
7723                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7724                            continue;
7725                        }
7726                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7727                            continue;
7728                        }
7729                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7730                                ps.readUserState(userId), userId);
7731                        if (ai != null) {
7732                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7733                        }
7734                    } else {
7735                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7736                        // and already converts to externally visible package name
7737                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7738                                callingUid, effectiveFlags, userId);
7739                    }
7740                    if (ai != null) {
7741                        list.add(ai);
7742                    }
7743                }
7744            } else {
7745                list = new ArrayList<>(mPackages.size());
7746                for (PackageParser.Package p : mPackages.values()) {
7747                    if (p.mExtras != null) {
7748                        PackageSetting ps = (PackageSetting) p.mExtras;
7749                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7750                            continue;
7751                        }
7752                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7753                            continue;
7754                        }
7755                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7756                                ps.readUserState(userId), userId);
7757                        if (ai != null) {
7758                            ai.packageName = resolveExternalPackageNameLPr(p);
7759                            list.add(ai);
7760                        }
7761                    }
7762                }
7763            }
7764
7765            return new ParceledListSlice<>(list);
7766        }
7767    }
7768
7769    @Override
7770    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7771        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7772            return null;
7773        }
7774        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7775            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7776                    "getEphemeralApplications");
7777        }
7778        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7779                true /* requireFullPermission */, false /* checkShell */,
7780                "getEphemeralApplications");
7781        synchronized (mPackages) {
7782            List<InstantAppInfo> instantApps = mInstantAppRegistry
7783                    .getInstantAppsLPr(userId);
7784            if (instantApps != null) {
7785                return new ParceledListSlice<>(instantApps);
7786            }
7787        }
7788        return null;
7789    }
7790
7791    @Override
7792    public boolean isInstantApp(String packageName, int userId) {
7793        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7794                true /* requireFullPermission */, false /* checkShell */,
7795                "isInstantApp");
7796        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7797            return false;
7798        }
7799
7800        synchronized (mPackages) {
7801            int callingUid = Binder.getCallingUid();
7802            if (Process.isIsolated(callingUid)) {
7803                callingUid = mIsolatedOwners.get(callingUid);
7804            }
7805            final PackageSetting ps = mSettings.mPackages.get(packageName);
7806            PackageParser.Package pkg = mPackages.get(packageName);
7807            final boolean returnAllowed =
7808                    ps != null
7809                    && (isCallerSameApp(packageName, callingUid)
7810                            || canViewInstantApps(callingUid, userId)
7811                            || mInstantAppRegistry.isInstantAccessGranted(
7812                                    userId, UserHandle.getAppId(callingUid), ps.appId));
7813            if (returnAllowed) {
7814                return ps.getInstantApp(userId);
7815            }
7816        }
7817        return false;
7818    }
7819
7820    @Override
7821    public byte[] getInstantAppCookie(String packageName, int userId) {
7822        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7823            return null;
7824        }
7825
7826        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7827                true /* requireFullPermission */, false /* checkShell */,
7828                "getInstantAppCookie");
7829        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7830            return null;
7831        }
7832        synchronized (mPackages) {
7833            return mInstantAppRegistry.getInstantAppCookieLPw(
7834                    packageName, userId);
7835        }
7836    }
7837
7838    @Override
7839    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7840        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7841            return true;
7842        }
7843
7844        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7845                true /* requireFullPermission */, true /* checkShell */,
7846                "setInstantAppCookie");
7847        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7848            return false;
7849        }
7850        synchronized (mPackages) {
7851            return mInstantAppRegistry.setInstantAppCookieLPw(
7852                    packageName, cookie, userId);
7853        }
7854    }
7855
7856    @Override
7857    public Bitmap getInstantAppIcon(String packageName, int userId) {
7858        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7859            return null;
7860        }
7861
7862        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7863            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7864                    "getInstantAppIcon");
7865        }
7866        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7867                true /* requireFullPermission */, false /* checkShell */,
7868                "getInstantAppIcon");
7869
7870        synchronized (mPackages) {
7871            return mInstantAppRegistry.getInstantAppIconLPw(
7872                    packageName, userId);
7873        }
7874    }
7875
7876    private boolean isCallerSameApp(String packageName, int uid) {
7877        PackageParser.Package pkg = mPackages.get(packageName);
7878        return pkg != null
7879                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7880    }
7881
7882    @Override
7883    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7884        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7885            return ParceledListSlice.emptyList();
7886        }
7887        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7888    }
7889
7890    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7891        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7892
7893        // reader
7894        synchronized (mPackages) {
7895            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7896            final int userId = UserHandle.getCallingUserId();
7897            while (i.hasNext()) {
7898                final PackageParser.Package p = i.next();
7899                if (p.applicationInfo == null) continue;
7900
7901                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7902                        && !p.applicationInfo.isDirectBootAware();
7903                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7904                        && p.applicationInfo.isDirectBootAware();
7905
7906                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7907                        && (!mSafeMode || isSystemApp(p))
7908                        && (matchesUnaware || matchesAware)) {
7909                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7910                    if (ps != null) {
7911                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7912                                ps.readUserState(userId), userId);
7913                        if (ai != null) {
7914                            finalList.add(ai);
7915                        }
7916                    }
7917                }
7918            }
7919        }
7920
7921        return finalList;
7922    }
7923
7924    @Override
7925    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7926        return resolveContentProviderInternal(name, flags, userId);
7927    }
7928
7929    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
7930        if (!sUserManager.exists(userId)) return null;
7931        flags = updateFlagsForComponent(flags, userId, name);
7932        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7933        // reader
7934        synchronized (mPackages) {
7935            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7936            PackageSetting ps = provider != null
7937                    ? mSettings.mPackages.get(provider.owner.packageName)
7938                    : null;
7939            if (ps != null) {
7940                final boolean isInstantApp = ps.getInstantApp(userId);
7941                // normal application; filter out instant application provider
7942                if (instantAppPkgName == null && isInstantApp) {
7943                    return null;
7944                }
7945                // instant application; filter out other instant applications
7946                if (instantAppPkgName != null
7947                        && isInstantApp
7948                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7949                    return null;
7950                }
7951                // instant application; filter out non-exposed provider
7952                if (instantAppPkgName != null
7953                        && !isInstantApp
7954                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
7955                    return null;
7956                }
7957                // provider not enabled
7958                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7959                    return null;
7960                }
7961                return PackageParser.generateProviderInfo(
7962                        provider, flags, ps.readUserState(userId), userId);
7963            }
7964            return null;
7965        }
7966    }
7967
7968    /**
7969     * @deprecated
7970     */
7971    @Deprecated
7972    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7973        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7974            return;
7975        }
7976        // reader
7977        synchronized (mPackages) {
7978            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7979                    .entrySet().iterator();
7980            final int userId = UserHandle.getCallingUserId();
7981            while (i.hasNext()) {
7982                Map.Entry<String, PackageParser.Provider> entry = i.next();
7983                PackageParser.Provider p = entry.getValue();
7984                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7985
7986                if (ps != null && p.syncable
7987                        && (!mSafeMode || (p.info.applicationInfo.flags
7988                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7989                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7990                            ps.readUserState(userId), userId);
7991                    if (info != null) {
7992                        outNames.add(entry.getKey());
7993                        outInfo.add(info);
7994                    }
7995                }
7996            }
7997        }
7998    }
7999
8000    @Override
8001    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8002            int uid, int flags, String metaDataKey) {
8003        final int callingUid = Binder.getCallingUid();
8004        final int userId = processName != null ? UserHandle.getUserId(uid)
8005                : UserHandle.getCallingUserId();
8006        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8007        flags = updateFlagsForComponent(flags, userId, processName);
8008        ArrayList<ProviderInfo> finalList = null;
8009        // reader
8010        synchronized (mPackages) {
8011            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8012            while (i.hasNext()) {
8013                final PackageParser.Provider p = i.next();
8014                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8015                if (ps != null && p.info.authority != null
8016                        && (processName == null
8017                                || (p.info.processName.equals(processName)
8018                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8019                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8020
8021                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8022                    // parameter.
8023                    if (metaDataKey != null
8024                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8025                        continue;
8026                    }
8027                    final ComponentName component =
8028                            new ComponentName(p.info.packageName, p.info.name);
8029                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8030                        continue;
8031                    }
8032                    if (finalList == null) {
8033                        finalList = new ArrayList<ProviderInfo>(3);
8034                    }
8035                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8036                            ps.readUserState(userId), userId);
8037                    if (info != null) {
8038                        finalList.add(info);
8039                    }
8040                }
8041            }
8042        }
8043
8044        if (finalList != null) {
8045            Collections.sort(finalList, mProviderInitOrderSorter);
8046            return new ParceledListSlice<ProviderInfo>(finalList);
8047        }
8048
8049        return ParceledListSlice.emptyList();
8050    }
8051
8052    @Override
8053    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8054        // reader
8055        synchronized (mPackages) {
8056            final int callingUid = Binder.getCallingUid();
8057            final int callingUserId = UserHandle.getUserId(callingUid);
8058            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8059            if (ps == null) return null;
8060            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8061                return null;
8062            }
8063            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8064            return PackageParser.generateInstrumentationInfo(i, flags);
8065        }
8066    }
8067
8068    @Override
8069    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8070            String targetPackage, int flags) {
8071        final int callingUid = Binder.getCallingUid();
8072        final int callingUserId = UserHandle.getUserId(callingUid);
8073        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8074        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8075            return ParceledListSlice.emptyList();
8076        }
8077        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8078    }
8079
8080    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8081            int flags) {
8082        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8083
8084        // reader
8085        synchronized (mPackages) {
8086            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8087            while (i.hasNext()) {
8088                final PackageParser.Instrumentation p = i.next();
8089                if (targetPackage == null
8090                        || targetPackage.equals(p.info.targetPackage)) {
8091                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8092                            flags);
8093                    if (ii != null) {
8094                        finalList.add(ii);
8095                    }
8096                }
8097            }
8098        }
8099
8100        return finalList;
8101    }
8102
8103    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8104        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8105        try {
8106            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8107        } finally {
8108            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8109        }
8110    }
8111
8112    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8113        final File[] files = scanDir.listFiles();
8114        if (ArrayUtils.isEmpty(files)) {
8115            Log.d(TAG, "No files in app dir " + scanDir);
8116            return;
8117        }
8118
8119        if (DEBUG_PACKAGE_SCANNING) {
8120            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8121                    + " flags=0x" + Integer.toHexString(parseFlags));
8122        }
8123        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8124                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8125                mParallelPackageParserCallback)) {
8126            // Submit files for parsing in parallel
8127            int fileCount = 0;
8128            for (File file : files) {
8129                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8130                        && !PackageInstallerService.isStageName(file.getName());
8131                if (!isPackage) {
8132                    // Ignore entries which are not packages
8133                    continue;
8134                }
8135                parallelPackageParser.submit(file, parseFlags);
8136                fileCount++;
8137            }
8138
8139            // Process results one by one
8140            for (; fileCount > 0; fileCount--) {
8141                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8142                Throwable throwable = parseResult.throwable;
8143                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8144
8145                if (throwable == null) {
8146                    // TODO(toddke): move lower in the scan chain
8147                    // Static shared libraries have synthetic package names
8148                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8149                        renameStaticSharedLibraryPackage(parseResult.pkg);
8150                    }
8151                    try {
8152                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8153                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8154                                    currentTime, null);
8155                        }
8156                    } catch (PackageManagerException e) {
8157                        errorCode = e.error;
8158                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8159                    }
8160                } else if (throwable instanceof PackageParser.PackageParserException) {
8161                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8162                            throwable;
8163                    errorCode = e.error;
8164                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8165                } else {
8166                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8167                            + parseResult.scanFile, throwable);
8168                }
8169
8170                // Delete invalid userdata apps
8171                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8172                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8173                    logCriticalInfo(Log.WARN,
8174                            "Deleting invalid package at " + parseResult.scanFile);
8175                    removeCodePathLI(parseResult.scanFile);
8176                }
8177            }
8178        }
8179    }
8180
8181    public static void reportSettingsProblem(int priority, String msg) {
8182        logCriticalInfo(priority, msg);
8183    }
8184
8185    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8186            final @ParseFlags int parseFlags) throws PackageManagerException {
8187        // When upgrading from pre-N MR1, verify the package time stamp using the package
8188        // directory and not the APK file.
8189        final long lastModifiedTime = mIsPreNMR1Upgrade
8190                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8191        if (ps != null
8192                && ps.codePathString.equals(pkg.codePath)
8193                && ps.timeStamp == lastModifiedTime
8194                && !isCompatSignatureUpdateNeeded(pkg)
8195                && !isRecoverSignatureUpdateNeeded(pkg)) {
8196            if (ps.signatures.mSignatures != null
8197                    && ps.signatures.mSignatures.length != 0
8198                    && ps.signatures.mSignatureSchemeVersion != SignatureSchemeVersion.UNKNOWN) {
8199                // Optimization: reuse the existing cached signing data
8200                // if the package appears to be unchanged.
8201                try {
8202                    pkg.mSigningDetails = new PackageParser.SigningDetails(ps.signatures.mSignatures,
8203                            ps.signatures.mSignatureSchemeVersion);
8204                    return;
8205                } catch (CertificateException e) {
8206                    Slog.e(TAG, "Attempt to read public keys from persisted signatures failed for "
8207                                    + ps.name, e);
8208                }
8209            }
8210
8211            Slog.w(TAG, "PackageSetting for " + ps.name
8212                    + " is missing signatures.  Collecting certs again to recover them.");
8213        } else {
8214            Slog.i(TAG, toString() + " changed; collecting certs");
8215        }
8216
8217        try {
8218            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8219            PackageParser.collectCertificates(pkg, parseFlags);
8220        } catch (PackageParserException e) {
8221            throw PackageManagerException.from(e);
8222        } finally {
8223            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8224        }
8225    }
8226
8227    /**
8228     *  Traces a package scan.
8229     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8230     */
8231    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8232            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8233        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8234        try {
8235            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8236        } finally {
8237            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8238        }
8239    }
8240
8241    /**
8242     *  Scans a package and returns the newly parsed package.
8243     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8244     */
8245    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8246            long currentTime, UserHandle user) throws PackageManagerException {
8247        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8248        PackageParser pp = new PackageParser();
8249        pp.setSeparateProcesses(mSeparateProcesses);
8250        pp.setOnlyCoreApps(mOnlyCore);
8251        pp.setDisplayMetrics(mMetrics);
8252        pp.setCallback(mPackageParserCallback);
8253
8254        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8255        final PackageParser.Package pkg;
8256        try {
8257            pkg = pp.parsePackage(scanFile, parseFlags);
8258        } catch (PackageParserException e) {
8259            throw PackageManagerException.from(e);
8260        } finally {
8261            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8262        }
8263
8264        // Static shared libraries have synthetic package names
8265        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8266            renameStaticSharedLibraryPackage(pkg);
8267        }
8268
8269        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8270    }
8271
8272    /**
8273     *  Scans a package and returns the newly parsed package.
8274     *  @throws PackageManagerException on a parse error.
8275     */
8276    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8277            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8278            @Nullable UserHandle user)
8279                    throws PackageManagerException {
8280        // If the package has children and this is the first dive in the function
8281        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8282        // packages (parent and children) would be successfully scanned before the
8283        // actual scan since scanning mutates internal state and we want to atomically
8284        // install the package and its children.
8285        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8286            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8287                scanFlags |= SCAN_CHECK_ONLY;
8288            }
8289        } else {
8290            scanFlags &= ~SCAN_CHECK_ONLY;
8291        }
8292
8293        // Scan the parent
8294        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8295                scanFlags, currentTime, user);
8296
8297        // Scan the children
8298        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8299        for (int i = 0; i < childCount; i++) {
8300            PackageParser.Package childPackage = pkg.childPackages.get(i);
8301            addForInitLI(childPackage, parseFlags, scanFlags,
8302                    currentTime, user);
8303        }
8304
8305
8306        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8307            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8308        }
8309
8310        return scannedPkg;
8311    }
8312
8313    /**
8314     * Adds a new package to the internal data structures during platform initialization.
8315     * <p>After adding, the package is known to the system and available for querying.
8316     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8317     * etc...], additional checks are performed. Basic verification [such as ensuring
8318     * matching signatures, checking version codes, etc...] occurs if the package is
8319     * identical to a previously known package. If the package fails a signature check,
8320     * the version installed on /data will be removed. If the version of the new package
8321     * is less than or equal than the version on /data, it will be ignored.
8322     * <p>Regardless of the package location, the results are applied to the internal
8323     * structures and the package is made available to the rest of the system.
8324     * <p>NOTE: The return value should be removed. It's the passed in package object.
8325     */
8326    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8327            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8328            @Nullable UserHandle user)
8329                    throws PackageManagerException {
8330        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8331        final String renamedPkgName;
8332        final PackageSetting disabledPkgSetting;
8333        final boolean isSystemPkgUpdated;
8334        final boolean pkgAlreadyExists;
8335        PackageSetting pkgSetting;
8336
8337        // NOTE: installPackageLI() has the same code to setup the package's
8338        // application info. This probably should be done lower in the call
8339        // stack [such as scanPackageOnly()]. However, we verify the application
8340        // info prior to that [in scanPackageNew()] and thus have to setup
8341        // the application info early.
8342        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8343        pkg.setApplicationInfoCodePath(pkg.codePath);
8344        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8345        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8346        pkg.setApplicationInfoResourcePath(pkg.codePath);
8347        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8348        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8349
8350        synchronized (mPackages) {
8351            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8352            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8353            if (realPkgName != null) {
8354                ensurePackageRenamed(pkg, renamedPkgName);
8355            }
8356            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8357            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8358            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8359            pkgAlreadyExists = pkgSetting != null;
8360            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8361            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8362            isSystemPkgUpdated = disabledPkgSetting != null;
8363
8364            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8365                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8366            }
8367
8368            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8369                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8370                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8371                    : null;
8372            if (DEBUG_PACKAGE_SCANNING
8373                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8374                    && sharedUserSetting != null) {
8375                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8376                        + " (uid=" + sharedUserSetting.userId + "):"
8377                        + " packages=" + sharedUserSetting.packages);
8378            }
8379
8380            if (scanSystemPartition) {
8381                // Potentially prune child packages. If the application on the /system
8382                // partition has been updated via OTA, but, is still disabled by a
8383                // version on /data, cycle through all of its children packages and
8384                // remove children that are no longer defined.
8385                if (isSystemPkgUpdated) {
8386                    final int scannedChildCount = (pkg.childPackages != null)
8387                            ? pkg.childPackages.size() : 0;
8388                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8389                            ? disabledPkgSetting.childPackageNames.size() : 0;
8390                    for (int i = 0; i < disabledChildCount; i++) {
8391                        String disabledChildPackageName =
8392                                disabledPkgSetting.childPackageNames.get(i);
8393                        boolean disabledPackageAvailable = false;
8394                        for (int j = 0; j < scannedChildCount; j++) {
8395                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8396                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8397                                disabledPackageAvailable = true;
8398                                break;
8399                            }
8400                        }
8401                        if (!disabledPackageAvailable) {
8402                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8403                        }
8404                    }
8405                    // we're updating the disabled package, so, scan it as the package setting
8406                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
8407                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8408                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8409                            (pkg == mPlatformPackage), user);
8410                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8411                }
8412            }
8413        }
8414
8415        final boolean newPkgChangedPaths =
8416                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8417        final boolean newPkgVersionGreater =
8418                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8419        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8420                && newPkgChangedPaths && newPkgVersionGreater;
8421        if (isSystemPkgBetter) {
8422            // The version of the application on /system is greater than the version on
8423            // /data. Switch back to the application on /system.
8424            // It's safe to assume the application on /system will correctly scan. If not,
8425            // there won't be a working copy of the application.
8426            synchronized (mPackages) {
8427                // just remove the loaded entries from package lists
8428                mPackages.remove(pkgSetting.name);
8429            }
8430
8431            logCriticalInfo(Log.WARN,
8432                    "System package updated;"
8433                    + " name: " + pkgSetting.name
8434                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8435                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8436
8437            final InstallArgs args = createInstallArgsForExisting(
8438                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8439                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8440            args.cleanUpResourcesLI();
8441            synchronized (mPackages) {
8442                mSettings.enableSystemPackageLPw(pkgSetting.name);
8443            }
8444        }
8445
8446        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8447            // The version of the application on the /system partition is less than or
8448            // equal to the version on the /data partition. Throw an exception and use
8449            // the application already installed on the /data partition.
8450            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8451                    + pkg.codePath + " ignored: updated version " + disabledPkgSetting.versionCode
8452                    + " better than this " + pkg.getLongVersionCode());
8453        }
8454
8455        // verify certificates against what was last scanned
8456        collectCertificatesLI(pkgSetting, pkg, parseFlags);
8457
8458        boolean shouldHideSystemApp = false;
8459        // A new application appeared on /system, but, we already have a copy of
8460        // the application installed on /data.
8461        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8462                && !pkgSetting.isSystem()) {
8463            // if the signatures don't match, wipe the installed application and its data
8464            if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSigningDetails.signatures)
8465                    != PackageManager.SIGNATURE_MATCH) {
8466                logCriticalInfo(Log.WARN,
8467                        "System package signature mismatch;"
8468                        + " name: " + pkgSetting.name);
8469                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8470                        "scanPackageInternalLI")) {
8471                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8472                }
8473                pkgSetting = null;
8474            } else if (newPkgVersionGreater) {
8475                // The application on /system is newer than the application on /data.
8476                // Simply remove the application on /data [keeping application data]
8477                // and replace it with the version on /system.
8478                logCriticalInfo(Log.WARN,
8479                        "System package enabled;"
8480                        + " name: " + pkgSetting.name
8481                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8482                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8483                InstallArgs args = createInstallArgsForExisting(
8484                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8485                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8486                synchronized (mInstallLock) {
8487                    args.cleanUpResourcesLI();
8488                }
8489            } else {
8490                // The application on /system is older than the application on /data. Hide
8491                // the application on /system and the version on /data will be scanned later
8492                // and re-added like an update.
8493                shouldHideSystemApp = true;
8494                logCriticalInfo(Log.INFO,
8495                        "System package disabled;"
8496                        + " name: " + pkgSetting.name
8497                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8498                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8499            }
8500        }
8501
8502        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8503                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8504
8505        if (shouldHideSystemApp) {
8506            synchronized (mPackages) {
8507                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8508            }
8509        }
8510        return scannedPkg;
8511    }
8512
8513    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8514        // Derive the new package synthetic package name
8515        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8516                + pkg.staticSharedLibVersion);
8517    }
8518
8519    private static String fixProcessName(String defProcessName,
8520            String processName) {
8521        if (processName == null) {
8522            return defProcessName;
8523        }
8524        return processName;
8525    }
8526
8527    /**
8528     * Enforces that only the system UID or root's UID can call a method exposed
8529     * via Binder.
8530     *
8531     * @param message used as message if SecurityException is thrown
8532     * @throws SecurityException if the caller is not system or root
8533     */
8534    private static final void enforceSystemOrRoot(String message) {
8535        final int uid = Binder.getCallingUid();
8536        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8537            throw new SecurityException(message);
8538        }
8539    }
8540
8541    @Override
8542    public void performFstrimIfNeeded() {
8543        enforceSystemOrRoot("Only the system can request fstrim");
8544
8545        // Before everything else, see whether we need to fstrim.
8546        try {
8547            IStorageManager sm = PackageHelper.getStorageManager();
8548            if (sm != null) {
8549                boolean doTrim = false;
8550                final long interval = android.provider.Settings.Global.getLong(
8551                        mContext.getContentResolver(),
8552                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8553                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8554                if (interval > 0) {
8555                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8556                    if (timeSinceLast > interval) {
8557                        doTrim = true;
8558                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8559                                + "; running immediately");
8560                    }
8561                }
8562                if (doTrim) {
8563                    final boolean dexOptDialogShown;
8564                    synchronized (mPackages) {
8565                        dexOptDialogShown = mDexOptDialogShown;
8566                    }
8567                    if (!isFirstBoot() && dexOptDialogShown) {
8568                        try {
8569                            ActivityManager.getService().showBootMessage(
8570                                    mContext.getResources().getString(
8571                                            R.string.android_upgrading_fstrim), true);
8572                        } catch (RemoteException e) {
8573                        }
8574                    }
8575                    sm.runMaintenance();
8576                }
8577            } else {
8578                Slog.e(TAG, "storageManager service unavailable!");
8579            }
8580        } catch (RemoteException e) {
8581            // Can't happen; StorageManagerService is local
8582        }
8583    }
8584
8585    @Override
8586    public void updatePackagesIfNeeded() {
8587        enforceSystemOrRoot("Only the system can request package update");
8588
8589        // We need to re-extract after an OTA.
8590        boolean causeUpgrade = isUpgrade();
8591
8592        // First boot or factory reset.
8593        // Note: we also handle devices that are upgrading to N right now as if it is their
8594        //       first boot, as they do not have profile data.
8595        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8596
8597        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8598        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8599
8600        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8601            return;
8602        }
8603
8604        List<PackageParser.Package> pkgs;
8605        synchronized (mPackages) {
8606            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8607        }
8608
8609        final long startTime = System.nanoTime();
8610        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8611                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
8612                    false /* bootComplete */);
8613
8614        final int elapsedTimeSeconds =
8615                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8616
8617        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8618        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8619        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8620        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8621        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8622    }
8623
8624    /*
8625     * Return the prebuilt profile path given a package base code path.
8626     */
8627    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8628        return pkg.baseCodePath + ".prof";
8629    }
8630
8631    /**
8632     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8633     * containing statistics about the invocation. The array consists of three elements,
8634     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8635     * and {@code numberOfPackagesFailed}.
8636     */
8637    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8638            final String compilerFilter, boolean bootComplete) {
8639
8640        int numberOfPackagesVisited = 0;
8641        int numberOfPackagesOptimized = 0;
8642        int numberOfPackagesSkipped = 0;
8643        int numberOfPackagesFailed = 0;
8644        final int numberOfPackagesToDexopt = pkgs.size();
8645
8646        for (PackageParser.Package pkg : pkgs) {
8647            numberOfPackagesVisited++;
8648
8649            boolean useProfileForDexopt = false;
8650
8651            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8652                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8653                // that are already compiled.
8654                File profileFile = new File(getPrebuildProfilePath(pkg));
8655                // Copy profile if it exists.
8656                if (profileFile.exists()) {
8657                    try {
8658                        // We could also do this lazily before calling dexopt in
8659                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8660                        // is that we don't have a good way to say "do this only once".
8661                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8662                                pkg.applicationInfo.uid, pkg.packageName)) {
8663                            Log.e(TAG, "Installer failed to copy system profile!");
8664                        } else {
8665                            // Disabled as this causes speed-profile compilation during first boot
8666                            // even if things are already compiled.
8667                            // useProfileForDexopt = true;
8668                        }
8669                    } catch (Exception e) {
8670                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8671                                e);
8672                    }
8673                } else {
8674                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8675                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8676                    // minimize the number off apps being speed-profile compiled during first boot.
8677                    // The other paths will not change the filter.
8678                    if (disabledPs != null && disabledPs.pkg.isStub) {
8679                        // The package is the stub one, remove the stub suffix to get the normal
8680                        // package and APK names.
8681                        String systemProfilePath =
8682                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8683                        profileFile = new File(systemProfilePath);
8684                        // If we have a profile for a compressed APK, copy it to the reference
8685                        // location.
8686                        // Note that copying the profile here will cause it to override the
8687                        // reference profile every OTA even though the existing reference profile
8688                        // may have more data. We can't copy during decompression since the
8689                        // directories are not set up at that point.
8690                        if (profileFile.exists()) {
8691                            try {
8692                                // We could also do this lazily before calling dexopt in
8693                                // PackageDexOptimizer to prevent this happening on first boot. The
8694                                // issue is that we don't have a good way to say "do this only
8695                                // once".
8696                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8697                                        pkg.applicationInfo.uid, pkg.packageName)) {
8698                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8699                                } else {
8700                                    useProfileForDexopt = true;
8701                                }
8702                            } catch (Exception e) {
8703                                Log.e(TAG, "Failed to copy profile " +
8704                                        profileFile.getAbsolutePath() + " ", e);
8705                            }
8706                        }
8707                    }
8708                }
8709            }
8710
8711            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8712                if (DEBUG_DEXOPT) {
8713                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8714                }
8715                numberOfPackagesSkipped++;
8716                continue;
8717            }
8718
8719            if (DEBUG_DEXOPT) {
8720                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8721                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8722            }
8723
8724            if (showDialog) {
8725                try {
8726                    ActivityManager.getService().showBootMessage(
8727                            mContext.getResources().getString(R.string.android_upgrading_apk,
8728                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8729                } catch (RemoteException e) {
8730                }
8731                synchronized (mPackages) {
8732                    mDexOptDialogShown = true;
8733                }
8734            }
8735
8736            String pkgCompilerFilter = compilerFilter;
8737            if (useProfileForDexopt) {
8738                // Use background dexopt mode to try and use the profile. Note that this does not
8739                // guarantee usage of the profile.
8740                pkgCompilerFilter =
8741                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
8742                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
8743            }
8744
8745            // checkProfiles is false to avoid merging profiles during boot which
8746            // might interfere with background compilation (b/28612421).
8747            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8748            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8749            // trade-off worth doing to save boot time work.
8750            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
8751            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
8752                    pkg.packageName,
8753                    pkgCompilerFilter,
8754                    dexoptFlags));
8755
8756            switch (primaryDexOptStaus) {
8757                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8758                    numberOfPackagesOptimized++;
8759                    break;
8760                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8761                    numberOfPackagesSkipped++;
8762                    break;
8763                case PackageDexOptimizer.DEX_OPT_FAILED:
8764                    numberOfPackagesFailed++;
8765                    break;
8766                default:
8767                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
8768                    break;
8769            }
8770        }
8771
8772        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8773                numberOfPackagesFailed };
8774    }
8775
8776    @Override
8777    public void notifyPackageUse(String packageName, int reason) {
8778        synchronized (mPackages) {
8779            final int callingUid = Binder.getCallingUid();
8780            final int callingUserId = UserHandle.getUserId(callingUid);
8781            if (getInstantAppPackageName(callingUid) != null) {
8782                if (!isCallerSameApp(packageName, callingUid)) {
8783                    return;
8784                }
8785            } else {
8786                if (isInstantApp(packageName, callingUserId)) {
8787                    return;
8788                }
8789            }
8790            notifyPackageUseLocked(packageName, reason);
8791        }
8792    }
8793
8794    private void notifyPackageUseLocked(String packageName, int reason) {
8795        final PackageParser.Package p = mPackages.get(packageName);
8796        if (p == null) {
8797            return;
8798        }
8799        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8800    }
8801
8802    @Override
8803    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
8804            List<String> classPaths, String loaderIsa) {
8805        int userId = UserHandle.getCallingUserId();
8806        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8807        if (ai == null) {
8808            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8809                + loadingPackageName + ", user=" + userId);
8810            return;
8811        }
8812        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
8813    }
8814
8815    @Override
8816    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
8817            IDexModuleRegisterCallback callback) {
8818        int userId = UserHandle.getCallingUserId();
8819        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
8820        DexManager.RegisterDexModuleResult result;
8821        if (ai == null) {
8822            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
8823                     " calling user. package=" + packageName + ", user=" + userId);
8824            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
8825        } else {
8826            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
8827        }
8828
8829        if (callback != null) {
8830            mHandler.post(() -> {
8831                try {
8832                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
8833                } catch (RemoteException e) {
8834                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
8835                }
8836            });
8837        }
8838    }
8839
8840    /**
8841     * Ask the package manager to perform a dex-opt with the given compiler filter.
8842     *
8843     * Note: exposed only for the shell command to allow moving packages explicitly to a
8844     *       definite state.
8845     */
8846    @Override
8847    public boolean performDexOptMode(String packageName,
8848            boolean checkProfiles, String targetCompilerFilter, boolean force,
8849            boolean bootComplete, String splitName) {
8850        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
8851                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
8852                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
8853        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
8854                splitName, flags));
8855    }
8856
8857    /**
8858     * Ask the package manager to perform a dex-opt with the given compiler filter on the
8859     * secondary dex files belonging to the given package.
8860     *
8861     * Note: exposed only for the shell command to allow moving packages explicitly to a
8862     *       definite state.
8863     */
8864    @Override
8865    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8866            boolean force) {
8867        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
8868                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
8869                DexoptOptions.DEXOPT_BOOT_COMPLETE |
8870                (force ? DexoptOptions.DEXOPT_FORCE : 0);
8871        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
8872    }
8873
8874    /*package*/ boolean performDexOpt(DexoptOptions options) {
8875        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8876            return false;
8877        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
8878            return false;
8879        }
8880
8881        if (options.isDexoptOnlySecondaryDex()) {
8882            return mDexManager.dexoptSecondaryDex(options);
8883        } else {
8884            int dexoptStatus = performDexOptWithStatus(options);
8885            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8886        }
8887    }
8888
8889    /**
8890     * Perform dexopt on the given package and return one of following result:
8891     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
8892     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
8893     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
8894     */
8895    /* package */ int performDexOptWithStatus(DexoptOptions options) {
8896        return performDexOptTraced(options);
8897    }
8898
8899    private int performDexOptTraced(DexoptOptions options) {
8900        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8901        try {
8902            return performDexOptInternal(options);
8903        } finally {
8904            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8905        }
8906    }
8907
8908    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8909    // if the package can now be considered up to date for the given filter.
8910    private int performDexOptInternal(DexoptOptions options) {
8911        PackageParser.Package p;
8912        synchronized (mPackages) {
8913            p = mPackages.get(options.getPackageName());
8914            if (p == null) {
8915                // Package could not be found. Report failure.
8916                return PackageDexOptimizer.DEX_OPT_FAILED;
8917            }
8918            mPackageUsage.maybeWriteAsync(mPackages);
8919            mCompilerStats.maybeWriteAsync();
8920        }
8921        long callingId = Binder.clearCallingIdentity();
8922        try {
8923            synchronized (mInstallLock) {
8924                return performDexOptInternalWithDependenciesLI(p, options);
8925            }
8926        } finally {
8927            Binder.restoreCallingIdentity(callingId);
8928        }
8929    }
8930
8931    public ArraySet<String> getOptimizablePackages() {
8932        ArraySet<String> pkgs = new ArraySet<String>();
8933        synchronized (mPackages) {
8934            for (PackageParser.Package p : mPackages.values()) {
8935                if (PackageDexOptimizer.canOptimizePackage(p)) {
8936                    pkgs.add(p.packageName);
8937                }
8938            }
8939        }
8940        return pkgs;
8941    }
8942
8943    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8944            DexoptOptions options) {
8945        // Select the dex optimizer based on the force parameter.
8946        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8947        //       allocate an object here.
8948        PackageDexOptimizer pdo = options.isForce()
8949                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8950                : mPackageDexOptimizer;
8951
8952        // Dexopt all dependencies first. Note: we ignore the return value and march on
8953        // on errors.
8954        // Note that we are going to call performDexOpt on those libraries as many times as
8955        // they are referenced in packages. When we do a batch of performDexOpt (for example
8956        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8957        // and the first package that uses the library will dexopt it. The
8958        // others will see that the compiled code for the library is up to date.
8959        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8960        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8961        if (!deps.isEmpty()) {
8962            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
8963                    options.getCompilerFilter(), options.getSplitName(),
8964                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
8965            for (PackageParser.Package depPackage : deps) {
8966                // TODO: Analyze and investigate if we (should) profile libraries.
8967                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8968                        getOrCreateCompilerPackageStats(depPackage),
8969                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
8970            }
8971        }
8972        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
8973                getOrCreateCompilerPackageStats(p),
8974                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
8975    }
8976
8977    /**
8978     * Reconcile the information we have about the secondary dex files belonging to
8979     * {@code packagName} and the actual dex files. For all dex files that were
8980     * deleted, update the internal records and delete the generated oat files.
8981     */
8982    @Override
8983    public void reconcileSecondaryDexFiles(String packageName) {
8984        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8985            return;
8986        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
8987            return;
8988        }
8989        mDexManager.reconcileSecondaryDexFiles(packageName);
8990    }
8991
8992    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8993    // a reference there.
8994    /*package*/ DexManager getDexManager() {
8995        return mDexManager;
8996    }
8997
8998    /**
8999     * Execute the background dexopt job immediately.
9000     */
9001    @Override
9002    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9003        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9004            return false;
9005        }
9006        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9007    }
9008
9009    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9010        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9011                || p.usesStaticLibraries != null) {
9012            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9013            Set<String> collectedNames = new HashSet<>();
9014            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9015
9016            retValue.remove(p);
9017
9018            return retValue;
9019        } else {
9020            return Collections.emptyList();
9021        }
9022    }
9023
9024    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9025            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9026        if (!collectedNames.contains(p.packageName)) {
9027            collectedNames.add(p.packageName);
9028            collected.add(p);
9029
9030            if (p.usesLibraries != null) {
9031                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9032                        null, collected, collectedNames);
9033            }
9034            if (p.usesOptionalLibraries != null) {
9035                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9036                        null, collected, collectedNames);
9037            }
9038            if (p.usesStaticLibraries != null) {
9039                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9040                        p.usesStaticLibrariesVersions, collected, collectedNames);
9041            }
9042        }
9043    }
9044
9045    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9046            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9047        final int libNameCount = libs.size();
9048        for (int i = 0; i < libNameCount; i++) {
9049            String libName = libs.get(i);
9050            long version = (versions != null && versions.length == libNameCount)
9051                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9052            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9053            if (libPkg != null) {
9054                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9055            }
9056        }
9057    }
9058
9059    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9060        synchronized (mPackages) {
9061            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9062            if (libEntry != null) {
9063                return mPackages.get(libEntry.apk);
9064            }
9065            return null;
9066        }
9067    }
9068
9069    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9070        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9071        if (versionedLib == null) {
9072            return null;
9073        }
9074        return versionedLib.get(version);
9075    }
9076
9077    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9078        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9079                pkg.staticSharedLibName);
9080        if (versionedLib == null) {
9081            return null;
9082        }
9083        long previousLibVersion = -1;
9084        final int versionCount = versionedLib.size();
9085        for (int i = 0; i < versionCount; i++) {
9086            final long libVersion = versionedLib.keyAt(i);
9087            if (libVersion < pkg.staticSharedLibVersion) {
9088                previousLibVersion = Math.max(previousLibVersion, libVersion);
9089            }
9090        }
9091        if (previousLibVersion >= 0) {
9092            return versionedLib.get(previousLibVersion);
9093        }
9094        return null;
9095    }
9096
9097    public void shutdown() {
9098        mPackageUsage.writeNow(mPackages);
9099        mCompilerStats.writeNow();
9100        mDexManager.writePackageDexUsageNow();
9101    }
9102
9103    @Override
9104    public void dumpProfiles(String packageName) {
9105        PackageParser.Package pkg;
9106        synchronized (mPackages) {
9107            pkg = mPackages.get(packageName);
9108            if (pkg == null) {
9109                throw new IllegalArgumentException("Unknown package: " + packageName);
9110            }
9111        }
9112        /* Only the shell, root, or the app user should be able to dump profiles. */
9113        int callingUid = Binder.getCallingUid();
9114        if (callingUid != Process.SHELL_UID &&
9115            callingUid != Process.ROOT_UID &&
9116            callingUid != pkg.applicationInfo.uid) {
9117            throw new SecurityException("dumpProfiles");
9118        }
9119
9120        synchronized (mInstallLock) {
9121            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9122            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9123            try {
9124                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9125                String codePaths = TextUtils.join(";", allCodePaths);
9126                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9127            } catch (InstallerException e) {
9128                Slog.w(TAG, "Failed to dump profiles", e);
9129            }
9130            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9131        }
9132    }
9133
9134    @Override
9135    public void forceDexOpt(String packageName) {
9136        enforceSystemOrRoot("forceDexOpt");
9137
9138        PackageParser.Package pkg;
9139        synchronized (mPackages) {
9140            pkg = mPackages.get(packageName);
9141            if (pkg == null) {
9142                throw new IllegalArgumentException("Unknown package: " + packageName);
9143            }
9144        }
9145
9146        synchronized (mInstallLock) {
9147            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9148
9149            // Whoever is calling forceDexOpt wants a compiled package.
9150            // Don't use profiles since that may cause compilation to be skipped.
9151            final int res = performDexOptInternalWithDependenciesLI(
9152                    pkg,
9153                    new DexoptOptions(packageName,
9154                            getDefaultCompilerFilter(),
9155                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9156
9157            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9158            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9159                throw new IllegalStateException("Failed to dexopt: " + res);
9160            }
9161        }
9162    }
9163
9164    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9165        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9166            Slog.w(TAG, "Unable to update from " + oldPkg.name
9167                    + " to " + newPkg.packageName
9168                    + ": old package not in system partition");
9169            return false;
9170        } else if (mPackages.get(oldPkg.name) != null) {
9171            Slog.w(TAG, "Unable to update from " + oldPkg.name
9172                    + " to " + newPkg.packageName
9173                    + ": old package still exists");
9174            return false;
9175        }
9176        return true;
9177    }
9178
9179    void removeCodePathLI(File codePath) {
9180        if (codePath.isDirectory()) {
9181            try {
9182                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9183            } catch (InstallerException e) {
9184                Slog.w(TAG, "Failed to remove code path", e);
9185            }
9186        } else {
9187            codePath.delete();
9188        }
9189    }
9190
9191    private int[] resolveUserIds(int userId) {
9192        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9193    }
9194
9195    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9196        if (pkg == null) {
9197            Slog.wtf(TAG, "Package was null!", new Throwable());
9198            return;
9199        }
9200        clearAppDataLeafLIF(pkg, userId, flags);
9201        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9202        for (int i = 0; i < childCount; i++) {
9203            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9204        }
9205    }
9206
9207    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9208        final PackageSetting ps;
9209        synchronized (mPackages) {
9210            ps = mSettings.mPackages.get(pkg.packageName);
9211        }
9212        for (int realUserId : resolveUserIds(userId)) {
9213            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9214            try {
9215                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9216                        ceDataInode);
9217            } catch (InstallerException e) {
9218                Slog.w(TAG, String.valueOf(e));
9219            }
9220        }
9221    }
9222
9223    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9224        if (pkg == null) {
9225            Slog.wtf(TAG, "Package was null!", new Throwable());
9226            return;
9227        }
9228        destroyAppDataLeafLIF(pkg, userId, flags);
9229        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9230        for (int i = 0; i < childCount; i++) {
9231            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9232        }
9233    }
9234
9235    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9236        final PackageSetting ps;
9237        synchronized (mPackages) {
9238            ps = mSettings.mPackages.get(pkg.packageName);
9239        }
9240        for (int realUserId : resolveUserIds(userId)) {
9241            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9242            try {
9243                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9244                        ceDataInode);
9245            } catch (InstallerException e) {
9246                Slog.w(TAG, String.valueOf(e));
9247            }
9248            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9249        }
9250    }
9251
9252    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9253        if (pkg == null) {
9254            Slog.wtf(TAG, "Package was null!", new Throwable());
9255            return;
9256        }
9257        destroyAppProfilesLeafLIF(pkg);
9258        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9259        for (int i = 0; i < childCount; i++) {
9260            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9261        }
9262    }
9263
9264    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9265        try {
9266            mInstaller.destroyAppProfiles(pkg.packageName);
9267        } catch (InstallerException e) {
9268            Slog.w(TAG, String.valueOf(e));
9269        }
9270    }
9271
9272    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9273        if (pkg == null) {
9274            Slog.wtf(TAG, "Package was null!", new Throwable());
9275            return;
9276        }
9277        clearAppProfilesLeafLIF(pkg);
9278        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9279        for (int i = 0; i < childCount; i++) {
9280            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9281        }
9282    }
9283
9284    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9285        try {
9286            mInstaller.clearAppProfiles(pkg.packageName);
9287        } catch (InstallerException e) {
9288            Slog.w(TAG, String.valueOf(e));
9289        }
9290    }
9291
9292    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9293            long lastUpdateTime) {
9294        // Set parent install/update time
9295        PackageSetting ps = (PackageSetting) pkg.mExtras;
9296        if (ps != null) {
9297            ps.firstInstallTime = firstInstallTime;
9298            ps.lastUpdateTime = lastUpdateTime;
9299        }
9300        // Set children install/update time
9301        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9302        for (int i = 0; i < childCount; i++) {
9303            PackageParser.Package childPkg = pkg.childPackages.get(i);
9304            ps = (PackageSetting) childPkg.mExtras;
9305            if (ps != null) {
9306                ps.firstInstallTime = firstInstallTime;
9307                ps.lastUpdateTime = lastUpdateTime;
9308            }
9309        }
9310    }
9311
9312    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9313            SharedLibraryEntry file,
9314            PackageParser.Package changingLib) {
9315        if (file.path != null) {
9316            usesLibraryFiles.add(file.path);
9317            return;
9318        }
9319        PackageParser.Package p = mPackages.get(file.apk);
9320        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9321            // If we are doing this while in the middle of updating a library apk,
9322            // then we need to make sure to use that new apk for determining the
9323            // dependencies here.  (We haven't yet finished committing the new apk
9324            // to the package manager state.)
9325            if (p == null || p.packageName.equals(changingLib.packageName)) {
9326                p = changingLib;
9327            }
9328        }
9329        if (p != null) {
9330            usesLibraryFiles.addAll(p.getAllCodePaths());
9331            if (p.usesLibraryFiles != null) {
9332                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9333            }
9334        }
9335    }
9336
9337    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9338            PackageParser.Package changingLib) throws PackageManagerException {
9339        if (pkg == null) {
9340            return;
9341        }
9342        // The collection used here must maintain the order of addition (so
9343        // that libraries are searched in the correct order) and must have no
9344        // duplicates.
9345        Set<String> usesLibraryFiles = null;
9346        if (pkg.usesLibraries != null) {
9347            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9348                    null, null, pkg.packageName, changingLib, true,
9349                    pkg.applicationInfo.targetSdkVersion, null);
9350        }
9351        if (pkg.usesStaticLibraries != null) {
9352            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9353                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9354                    pkg.packageName, changingLib, true,
9355                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9356        }
9357        if (pkg.usesOptionalLibraries != null) {
9358            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9359                    null, null, pkg.packageName, changingLib, false,
9360                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9361        }
9362        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9363            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9364        } else {
9365            pkg.usesLibraryFiles = null;
9366        }
9367    }
9368
9369    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9370            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9371            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9372            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9373            throws PackageManagerException {
9374        final int libCount = requestedLibraries.size();
9375        for (int i = 0; i < libCount; i++) {
9376            final String libName = requestedLibraries.get(i);
9377            final long libVersion = requiredVersions != null ? requiredVersions[i]
9378                    : SharedLibraryInfo.VERSION_UNDEFINED;
9379            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9380            if (libEntry == null) {
9381                if (required) {
9382                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9383                            "Package " + packageName + " requires unavailable shared library "
9384                                    + libName + "; failing!");
9385                } else if (DEBUG_SHARED_LIBRARIES) {
9386                    Slog.i(TAG, "Package " + packageName
9387                            + " desires unavailable shared library "
9388                            + libName + "; ignoring!");
9389                }
9390            } else {
9391                if (requiredVersions != null && requiredCertDigests != null) {
9392                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9393                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9394                            "Package " + packageName + " requires unavailable static shared"
9395                                    + " library " + libName + " version "
9396                                    + libEntry.info.getLongVersion() + "; failing!");
9397                    }
9398
9399                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9400                    if (libPkg == null) {
9401                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9402                                "Package " + packageName + " requires unavailable static shared"
9403                                        + " library; failing!");
9404                    }
9405
9406                    final String[] expectedCertDigests = requiredCertDigests[i];
9407                    // For apps targeting O MR1 we require explicit enumeration of all certs.
9408                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9409                            ? PackageUtils.computeSignaturesSha256Digests(
9410                            libPkg.mSigningDetails.signatures)
9411                            : PackageUtils.computeSignaturesSha256Digests(
9412                                    new Signature[]{libPkg.mSigningDetails.signatures[0]});
9413
9414                    // Take a shortcut if sizes don't match. Note that if an app doesn't
9415                    // target O we don't parse the "additional-certificate" tags similarly
9416                    // how we only consider all certs only for apps targeting O (see above).
9417                    // Therefore, the size check is safe to make.
9418                    if (expectedCertDigests.length != libCertDigests.length) {
9419                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9420                                "Package " + packageName + " requires differently signed" +
9421                                        " static shared library; failing!");
9422                    }
9423
9424                    // Use a predictable order as signature order may vary
9425                    Arrays.sort(libCertDigests);
9426                    Arrays.sort(expectedCertDigests);
9427
9428                    final int certCount = libCertDigests.length;
9429                    for (int j = 0; j < certCount; j++) {
9430                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9431                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9432                                    "Package " + packageName + " requires differently signed" +
9433                                            " static shared library; failing!");
9434                        }
9435                    }
9436                }
9437
9438                if (outUsedLibraries == null) {
9439                    // Use LinkedHashSet to preserve the order of files added to
9440                    // usesLibraryFiles while eliminating duplicates.
9441                    outUsedLibraries = new LinkedHashSet<>();
9442                }
9443                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9444            }
9445        }
9446        return outUsedLibraries;
9447    }
9448
9449    private static boolean hasString(List<String> list, List<String> which) {
9450        if (list == null) {
9451            return false;
9452        }
9453        for (int i=list.size()-1; i>=0; i--) {
9454            for (int j=which.size()-1; j>=0; j--) {
9455                if (which.get(j).equals(list.get(i))) {
9456                    return true;
9457                }
9458            }
9459        }
9460        return false;
9461    }
9462
9463    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9464            PackageParser.Package changingPkg) {
9465        ArrayList<PackageParser.Package> res = null;
9466        for (PackageParser.Package pkg : mPackages.values()) {
9467            if (changingPkg != null
9468                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9469                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9470                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9471                            changingPkg.staticSharedLibName)) {
9472                return null;
9473            }
9474            if (res == null) {
9475                res = new ArrayList<>();
9476            }
9477            res.add(pkg);
9478            try {
9479                updateSharedLibrariesLPr(pkg, changingPkg);
9480            } catch (PackageManagerException e) {
9481                // If a system app update or an app and a required lib missing we
9482                // delete the package and for updated system apps keep the data as
9483                // it is better for the user to reinstall than to be in an limbo
9484                // state. Also libs disappearing under an app should never happen
9485                // - just in case.
9486                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9487                    final int flags = pkg.isUpdatedSystemApp()
9488                            ? PackageManager.DELETE_KEEP_DATA : 0;
9489                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9490                            flags , null, true, null);
9491                }
9492                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9493            }
9494        }
9495        return res;
9496    }
9497
9498    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9499            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9500            @Nullable UserHandle user) throws PackageManagerException {
9501        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9502        // If the package has children and this is the first dive in the function
9503        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9504        // whether all packages (parent and children) would be successfully scanned
9505        // before the actual scan since scanning mutates internal state and we want
9506        // to atomically install the package and its children.
9507        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9508            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9509                scanFlags |= SCAN_CHECK_ONLY;
9510            }
9511        } else {
9512            scanFlags &= ~SCAN_CHECK_ONLY;
9513        }
9514
9515        final PackageParser.Package scannedPkg;
9516        try {
9517            // Scan the parent
9518            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9519            // Scan the children
9520            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9521            for (int i = 0; i < childCount; i++) {
9522                PackageParser.Package childPkg = pkg.childPackages.get(i);
9523                scanPackageNewLI(childPkg, parseFlags,
9524                        scanFlags, currentTime, user);
9525            }
9526        } finally {
9527            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9528        }
9529
9530        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9531            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9532        }
9533
9534        return scannedPkg;
9535    }
9536
9537    /** The result of a package scan. */
9538    private static class ScanResult {
9539        /** Whether or not the package scan was successful */
9540        public final boolean success;
9541        /**
9542         * The final package settings. This may be the same object passed in
9543         * the {@link ScanRequest}, but, with modified values.
9544         */
9545        @Nullable public final PackageSetting pkgSetting;
9546        /** ABI code paths that have changed in the package scan */
9547        @Nullable public final List<String> changedAbiCodePath;
9548        public ScanResult(
9549                boolean success,
9550                @Nullable PackageSetting pkgSetting,
9551                @Nullable List<String> changedAbiCodePath) {
9552            this.success = success;
9553            this.pkgSetting = pkgSetting;
9554            this.changedAbiCodePath = changedAbiCodePath;
9555        }
9556    }
9557
9558    /** A package to be scanned */
9559    private static class ScanRequest {
9560        /** The parsed package */
9561        @NonNull public final PackageParser.Package pkg;
9562        /** Shared user settings, if the package has a shared user */
9563        @Nullable public final SharedUserSetting sharedUserSetting;
9564        /**
9565         * Package settings of the currently installed version.
9566         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9567         * during scan.
9568         */
9569        @Nullable public final PackageSetting pkgSetting;
9570        /** A copy of the settings for the currently installed version */
9571        @Nullable public final PackageSetting oldPkgSetting;
9572        /** Package settings for the disabled version on the /system partition */
9573        @Nullable public final PackageSetting disabledPkgSetting;
9574        /** Package settings for the installed version under its original package name */
9575        @Nullable public final PackageSetting originalPkgSetting;
9576        /** The real package name of a renamed application */
9577        @Nullable public final String realPkgName;
9578        public final @ParseFlags int parseFlags;
9579        public final @ScanFlags int scanFlags;
9580        /** The user for which the package is being scanned */
9581        @Nullable public final UserHandle user;
9582        /** Whether or not the platform package is being scanned */
9583        public final boolean isPlatformPackage;
9584        public ScanRequest(
9585                @NonNull PackageParser.Package pkg,
9586                @Nullable SharedUserSetting sharedUserSetting,
9587                @Nullable PackageSetting pkgSetting,
9588                @Nullable PackageSetting disabledPkgSetting,
9589                @Nullable PackageSetting originalPkgSetting,
9590                @Nullable String realPkgName,
9591                @ParseFlags int parseFlags,
9592                @ScanFlags int scanFlags,
9593                boolean isPlatformPackage,
9594                @Nullable UserHandle user) {
9595            this.pkg = pkg;
9596            this.pkgSetting = pkgSetting;
9597            this.sharedUserSetting = sharedUserSetting;
9598            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9599            this.disabledPkgSetting = disabledPkgSetting;
9600            this.originalPkgSetting = originalPkgSetting;
9601            this.realPkgName = realPkgName;
9602            this.parseFlags = parseFlags;
9603            this.scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user);
9604            this.isPlatformPackage = isPlatformPackage;
9605            this.user = user;
9606        }
9607
9608        /**
9609         * Returns the actual scan flags depending upon the state of the other settings.
9610         * <p>Updated system applications will not have the following flags set
9611         * by default and need to be adjusted after the fact:
9612         * <ul>
9613         * <li>{@link #SCAN_AS_SYSTEM}</li>
9614         * <li>{@link #SCAN_AS_PRIVILEGED}</li>
9615         * <li>{@link #SCAN_AS_OEM}</li>
9616         * <li>{@link #SCAN_AS_VENDOR}</li>
9617         * <li>{@link #SCAN_AS_INSTANT_APP}</li>
9618         * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
9619         * </ul>
9620         */
9621        private static @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
9622                PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user) {
9623            if (disabledPkgSetting != null) {
9624                // updated system application, must at least have SCAN_AS_SYSTEM
9625                scanFlags |= SCAN_AS_SYSTEM;
9626                if ((disabledPkgSetting.pkgPrivateFlags
9627                        & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9628                    scanFlags |= SCAN_AS_PRIVILEGED;
9629                }
9630                if ((disabledPkgSetting.pkgPrivateFlags
9631                        & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9632                    scanFlags |= SCAN_AS_OEM;
9633                }
9634                if ((disabledPkgSetting.pkgPrivateFlags
9635                        & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
9636                    scanFlags |= SCAN_AS_VENDOR;
9637                }
9638            }
9639            if (pkgSetting != null) {
9640                final int userId = ((user == null) ? 0 : user.getIdentifier());
9641                if (pkgSetting.getInstantApp(userId)) {
9642                    scanFlags |= SCAN_AS_INSTANT_APP;
9643                }
9644                if (pkgSetting.getVirtulalPreload(userId)) {
9645                    scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9646                }
9647            }
9648            return scanFlags;
9649        }
9650    }
9651
9652    @GuardedBy("mInstallLock")
9653    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9654            final @ParseFlags int parseFlags, final @ScanFlags int scanFlags, long currentTime,
9655            @Nullable UserHandle user) throws PackageManagerException {
9656
9657        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9658        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9659        if (realPkgName != null) {
9660            ensurePackageRenamed(pkg, renamedPkgName);
9661        }
9662        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9663        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9664        final PackageSetting disabledPkgSetting =
9665                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9666
9667        if (mTransferedPackages.contains(pkg.packageName)) {
9668            Slog.w(TAG, "Package " + pkg.packageName
9669                    + " was transferred to another, but its .apk remains");
9670        }
9671
9672        synchronized (mPackages) {
9673            applyPolicy(pkg, parseFlags, scanFlags);
9674            assertPackageIsValid(pkg, parseFlags, scanFlags);
9675
9676            SharedUserSetting sharedUserSetting = null;
9677            if (pkg.mSharedUserId != null) {
9678                // SIDE EFFECTS; may potentially allocate a new shared user
9679                sharedUserSetting = mSettings.getSharedUserLPw(
9680                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9681                if (DEBUG_PACKAGE_SCANNING) {
9682                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9683                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9684                                + " (uid=" + sharedUserSetting.userId + "):"
9685                                + " packages=" + sharedUserSetting.packages);
9686                }
9687            }
9688
9689            boolean scanSucceeded = false;
9690            try {
9691                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
9692                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
9693                        (pkg == mPlatformPackage), user);
9694                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
9695                if (result.success) {
9696                    commitScanResultsLocked(request, result);
9697                }
9698                scanSucceeded = true;
9699            } finally {
9700                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9701                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
9702                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9703                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9704                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9705                  }
9706            }
9707        }
9708        return pkg;
9709    }
9710
9711    /**
9712     * Commits the package scan and modifies system state.
9713     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
9714     * of committing the package, leaving the system in an inconsistent state.
9715     * This needs to be fixed so, once we get to this point, no errors are
9716     * possible and the system is not left in an inconsistent state.
9717     */
9718    @GuardedBy("mPackages")
9719    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
9720            throws PackageManagerException {
9721        final PackageParser.Package pkg = request.pkg;
9722        final @ParseFlags int parseFlags = request.parseFlags;
9723        final @ScanFlags int scanFlags = request.scanFlags;
9724        final PackageSetting oldPkgSetting = request.oldPkgSetting;
9725        final PackageSetting originalPkgSetting = request.originalPkgSetting;
9726        final UserHandle user = request.user;
9727        final String realPkgName = request.realPkgName;
9728        final PackageSetting pkgSetting = result.pkgSetting;
9729        final List<String> changedAbiCodePath = result.changedAbiCodePath;
9730        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
9731
9732        if (newPkgSettingCreated) {
9733            if (originalPkgSetting != null) {
9734                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
9735            }
9736            // THROWS: when we can't allocate a user id. add call to check if there's
9737            // enough space to ensure we won't throw; otherwise, don't modify state
9738            mSettings.addUserToSettingLPw(pkgSetting);
9739
9740            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
9741                mTransferedPackages.add(originalPkgSetting.name);
9742            }
9743        }
9744        // TODO(toddke): Consider a method specifically for modifying the Package object
9745        // post scan; or, moving this stuff out of the Package object since it has nothing
9746        // to do with the package on disk.
9747        // We need to have this here because addUserToSettingLPw() is sometimes responsible
9748        // for creating the application ID. If we did this earlier, we would be saving the
9749        // correct ID.
9750        pkg.applicationInfo.uid = pkgSetting.appId;
9751
9752        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9753
9754        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
9755            mTransferedPackages.add(pkg.packageName);
9756        }
9757
9758        // THROWS: when requested libraries that can't be found. it only changes
9759        // the state of the passed in pkg object, so, move to the top of the method
9760        // and allow it to abort
9761        if ((scanFlags & SCAN_BOOTING) == 0
9762                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9763            // Check all shared libraries and map to their actual file path.
9764            // We only do this here for apps not on a system dir, because those
9765            // are the only ones that can fail an install due to this.  We
9766            // will take care of the system apps by updating all of their
9767            // library paths after the scan is done. Also during the initial
9768            // scan don't update any libs as we do this wholesale after all
9769            // apps are scanned to avoid dependency based scanning.
9770            updateSharedLibrariesLPr(pkg, null);
9771        }
9772
9773        // All versions of a static shared library are referenced with the same
9774        // package name. Internally, we use a synthetic package name to allow
9775        // multiple versions of the same shared library to be installed. So,
9776        // we need to generate the synthetic package name of the latest shared
9777        // library in order to compare signatures.
9778        PackageSetting signatureCheckPs = pkgSetting;
9779        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9780            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9781            if (libraryEntry != null) {
9782                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9783            }
9784        }
9785
9786        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
9787        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
9788            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
9789                // We just determined the app is signed correctly, so bring
9790                // over the latest parsed certs.
9791                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9792            } else {
9793                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9794                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9795                            "Package " + pkg.packageName + " upgrade keys do not match the "
9796                                    + "previously installed version");
9797                } else {
9798                    pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9799                    String msg = "System package " + pkg.packageName
9800                            + " signature changed; retaining data.";
9801                    reportSettingsProblem(Log.WARN, msg);
9802                }
9803            }
9804        } else {
9805            try {
9806                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
9807                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
9808                final boolean compatMatch = verifySignatures(signatureCheckPs,
9809                        pkg.mSigningDetails, compareCompat, compareRecover);
9810                // The new KeySets will be re-added later in the scanning process.
9811                if (compatMatch) {
9812                    synchronized (mPackages) {
9813                        ksms.removeAppKeySetDataLPw(pkg.packageName);
9814                    }
9815                }
9816                // We just determined the app is signed correctly, so bring
9817                // over the latest parsed certs.
9818                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9819            } catch (PackageManagerException e) {
9820                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9821                    throw e;
9822                }
9823                // The signature has changed, but this package is in the system
9824                // image...  let's recover!
9825                pkgSetting.signatures.mSignatures = pkg.mSigningDetails.signatures;
9826                // However...  if this package is part of a shared user, but it
9827                // doesn't match the signature of the shared user, let's fail.
9828                // What this means is that you can't change the signatures
9829                // associated with an overall shared user, which doesn't seem all
9830                // that unreasonable.
9831                if (signatureCheckPs.sharedUser != null) {
9832                    if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9833                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
9834                        throw new PackageManagerException(
9835                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9836                                "Signature mismatch for shared user: "
9837                                        + pkgSetting.sharedUser);
9838                    }
9839                }
9840                // File a report about this.
9841                String msg = "System package " + pkg.packageName
9842                        + " signature changed; retaining data.";
9843                reportSettingsProblem(Log.WARN, msg);
9844            }
9845        }
9846
9847        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9848            // This package wants to adopt ownership of permissions from
9849            // another package.
9850            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9851                final String origName = pkg.mAdoptPermissions.get(i);
9852                final PackageSetting orig = mSettings.getPackageLPr(origName);
9853                if (orig != null) {
9854                    if (verifyPackageUpdateLPr(orig, pkg)) {
9855                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
9856                                + pkg.packageName);
9857                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
9858                    }
9859                }
9860            }
9861        }
9862
9863        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
9864            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
9865                final String codePathString = changedAbiCodePath.get(i);
9866                try {
9867                    mInstaller.rmdex(codePathString,
9868                            getDexCodeInstructionSet(getPreferredInstructionSet()));
9869                } catch (InstallerException ignored) {
9870                }
9871            }
9872        }
9873
9874        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9875            if (oldPkgSetting != null) {
9876                synchronized (mPackages) {
9877                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
9878                }
9879            }
9880        } else {
9881            final int userId = user == null ? 0 : user.getIdentifier();
9882            // Modify state for the given package setting
9883            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9884                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9885            if (pkgSetting.getInstantApp(userId)) {
9886                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9887            }
9888        }
9889    }
9890
9891    /**
9892     * Returns the "real" name of the package.
9893     * <p>This may differ from the package's actual name if the application has already
9894     * been installed under one of this package's original names.
9895     */
9896    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
9897            @Nullable String renamedPkgName) {
9898        if (isPackageRenamed(pkg, renamedPkgName)) {
9899            return pkg.mRealPackage;
9900        }
9901        return null;
9902    }
9903
9904    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
9905    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
9906            @Nullable String renamedPkgName) {
9907        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
9908    }
9909
9910    /**
9911     * Returns the original package setting.
9912     * <p>A package can migrate its name during an update. In this scenario, a package
9913     * designates a set of names that it considers as one of its original names.
9914     * <p>An original package must be signed identically and it must have the same
9915     * shared user [if any].
9916     */
9917    @GuardedBy("mPackages")
9918    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
9919            @Nullable String renamedPkgName) {
9920        if (!isPackageRenamed(pkg, renamedPkgName)) {
9921            return null;
9922        }
9923        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
9924            final PackageSetting originalPs =
9925                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
9926            if (originalPs != null) {
9927                // the package is already installed under its original name...
9928                // but, should we use it?
9929                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
9930                    // the new package is incompatible with the original
9931                    continue;
9932                } else if (originalPs.sharedUser != null) {
9933                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
9934                        // the shared user id is incompatible with the original
9935                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
9936                                + " to " + pkg.packageName + ": old uid "
9937                                + originalPs.sharedUser.name
9938                                + " differs from " + pkg.mSharedUserId);
9939                        continue;
9940                    }
9941                    // TODO: Add case when shared user id is added [b/28144775]
9942                } else {
9943                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9944                            + pkg.packageName + " to old name " + originalPs.name);
9945                }
9946                return originalPs;
9947            }
9948        }
9949        return null;
9950    }
9951
9952    /**
9953     * Renames the package if it was installed under a different name.
9954     * <p>When we've already installed the package under an original name, update
9955     * the new package so we can continue to have the old name.
9956     */
9957    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
9958            @NonNull String renamedPackageName) {
9959        if (pkg.mOriginalPackages == null
9960                || !pkg.mOriginalPackages.contains(renamedPackageName)
9961                || pkg.packageName.equals(renamedPackageName)) {
9962            return;
9963        }
9964        pkg.setPackageName(renamedPackageName);
9965    }
9966
9967    /**
9968     * Just scans the package without any side effects.
9969     * <p>Not entirely true at the moment. There is still one side effect -- this
9970     * method potentially modifies a live {@link PackageSetting} object representing
9971     * the package being scanned. This will be resolved in the future.
9972     *
9973     * @param request Information about the package to be scanned
9974     * @param isUnderFactoryTest Whether or not the device is under factory test
9975     * @param currentTime The current time, in millis
9976     * @return The results of the scan
9977     */
9978    @GuardedBy("mInstallLock")
9979    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
9980            boolean isUnderFactoryTest, long currentTime)
9981                    throws PackageManagerException {
9982        final PackageParser.Package pkg = request.pkg;
9983        PackageSetting pkgSetting = request.pkgSetting;
9984        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
9985        final PackageSetting originalPkgSetting = request.originalPkgSetting;
9986        final @ParseFlags int parseFlags = request.parseFlags;
9987        final @ScanFlags int scanFlags = request.scanFlags;
9988        final String realPkgName = request.realPkgName;
9989        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
9990        final UserHandle user = request.user;
9991        final boolean isPlatformPackage = request.isPlatformPackage;
9992
9993        List<String> changedAbiCodePath = null;
9994
9995        if (DEBUG_PACKAGE_SCANNING) {
9996            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9997                Log.d(TAG, "Scanning package " + pkg.packageName);
9998        }
9999
10000        if (Build.IS_DEBUGGABLE &&
10001                pkg.isPrivileged() &&
10002                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10003            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10004        }
10005
10006        // Initialize package source and resource directories
10007        final File scanFile = new File(pkg.codePath);
10008        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10009        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10010
10011        // We keep references to the derived CPU Abis from settings in oder to reuse
10012        // them in the case where we're not upgrading or booting for the first time.
10013        String primaryCpuAbiFromSettings = null;
10014        String secondaryCpuAbiFromSettings = null;
10015        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10016
10017        if (!needToDeriveAbi) {
10018            if (pkgSetting != null) {
10019                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10020                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10021            } else {
10022                // Re-scanning a system package after uninstalling updates; need to derive ABI
10023                needToDeriveAbi = true;
10024            }
10025        }
10026
10027        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10028            PackageManagerService.reportSettingsProblem(Log.WARN,
10029                    "Package " + pkg.packageName + " shared user changed from "
10030                            + (pkgSetting.sharedUser != null
10031                            ? pkgSetting.sharedUser.name : "<nothing>")
10032                            + " to "
10033                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10034                            + "; replacing with new");
10035            pkgSetting = null;
10036        }
10037
10038        String[] usesStaticLibraries = null;
10039        if (pkg.usesStaticLibraries != null) {
10040            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10041            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10042        }
10043        final boolean createNewPackage = (pkgSetting == null);
10044        if (createNewPackage) {
10045            final String parentPackageName = (pkg.parentPackage != null)
10046                    ? pkg.parentPackage.packageName : null;
10047            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10048            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10049            // REMOVE SharedUserSetting from method; update in a separate call
10050            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10051                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10052                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10053                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10054                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10055                    user, true /*allowInstall*/, instantApp, virtualPreload,
10056                    parentPackageName, pkg.getChildPackageNames(),
10057                    UserManagerService.getInstance(), usesStaticLibraries,
10058                    pkg.usesStaticLibrariesVersions);
10059        } else {
10060            // REMOVE SharedUserSetting from method; update in a separate call.
10061            //
10062            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10063            // secondaryCpuAbi are not known at this point so we always update them
10064            // to null here, only to reset them at a later point.
10065            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10066                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10067                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10068                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10069                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10070                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10071        }
10072        if (createNewPackage && originalPkgSetting != null) {
10073            // This is the initial transition from the original package, so,
10074            // fix up the new package's name now. We must do this after looking
10075            // up the package under its new name, so getPackageLP takes care of
10076            // fiddling things correctly.
10077            pkg.setPackageName(originalPkgSetting.name);
10078
10079            // File a report about this.
10080            String msg = "New package " + pkgSetting.realName
10081                    + " renamed to replace old package " + pkgSetting.name;
10082            reportSettingsProblem(Log.WARN, msg);
10083        }
10084
10085        if (disabledPkgSetting != null) {
10086            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10087        }
10088
10089        SELinuxMMAC.assignSeInfoValue(pkg);
10090
10091        pkg.mExtras = pkgSetting;
10092        pkg.applicationInfo.processName = fixProcessName(
10093                pkg.applicationInfo.packageName,
10094                pkg.applicationInfo.processName);
10095
10096        if (!isPlatformPackage) {
10097            // Get all of our default paths setup
10098            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10099        }
10100
10101        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10102
10103        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10104            if (needToDeriveAbi) {
10105                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10106                final boolean extractNativeLibs = !pkg.isLibrary();
10107                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10108                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10109
10110                // Some system apps still use directory structure for native libraries
10111                // in which case we might end up not detecting abi solely based on apk
10112                // structure. Try to detect abi based on directory structure.
10113                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10114                        pkg.applicationInfo.primaryCpuAbi == null) {
10115                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10116                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10117                }
10118            } else {
10119                // This is not a first boot or an upgrade, don't bother deriving the
10120                // ABI during the scan. Instead, trust the value that was stored in the
10121                // package setting.
10122                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10123                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10124
10125                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10126
10127                if (DEBUG_ABI_SELECTION) {
10128                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10129                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10130                            pkg.applicationInfo.secondaryCpuAbi);
10131                }
10132            }
10133        } else {
10134            if ((scanFlags & SCAN_MOVE) != 0) {
10135                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10136                // but we already have this packages package info in the PackageSetting. We just
10137                // use that and derive the native library path based on the new codepath.
10138                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10139                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10140            }
10141
10142            // Set native library paths again. For moves, the path will be updated based on the
10143            // ABIs we've determined above. For non-moves, the path will be updated based on the
10144            // ABIs we determined during compilation, but the path will depend on the final
10145            // package path (after the rename away from the stage path).
10146            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10147        }
10148
10149        // This is a special case for the "system" package, where the ABI is
10150        // dictated by the zygote configuration (and init.rc). We should keep track
10151        // of this ABI so that we can deal with "normal" applications that run under
10152        // the same UID correctly.
10153        if (isPlatformPackage) {
10154            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10155                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10156        }
10157
10158        // If there's a mismatch between the abi-override in the package setting
10159        // and the abiOverride specified for the install. Warn about this because we
10160        // would've already compiled the app without taking the package setting into
10161        // account.
10162        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10163            if (cpuAbiOverride == null && pkg.packageName != null) {
10164                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10165                        " for package " + pkg.packageName);
10166            }
10167        }
10168
10169        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10170        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10171        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10172
10173        // Copy the derived override back to the parsed package, so that we can
10174        // update the package settings accordingly.
10175        pkg.cpuAbiOverride = cpuAbiOverride;
10176
10177        if (DEBUG_ABI_SELECTION) {
10178            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10179                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10180                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10181        }
10182
10183        // Push the derived path down into PackageSettings so we know what to
10184        // clean up at uninstall time.
10185        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10186
10187        if (DEBUG_ABI_SELECTION) {
10188            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10189                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10190                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10191        }
10192
10193        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10194            // We don't do this here during boot because we can do it all
10195            // at once after scanning all existing packages.
10196            //
10197            // We also do this *before* we perform dexopt on this package, so that
10198            // we can avoid redundant dexopts, and also to make sure we've got the
10199            // code and package path correct.
10200            changedAbiCodePath =
10201                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10202        }
10203
10204        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10205                android.Manifest.permission.FACTORY_TEST)) {
10206            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10207        }
10208
10209        if (isSystemApp(pkg)) {
10210            pkgSetting.isOrphaned = true;
10211        }
10212
10213        // Take care of first install / last update times.
10214        final long scanFileTime = getLastModifiedTime(pkg);
10215        if (currentTime != 0) {
10216            if (pkgSetting.firstInstallTime == 0) {
10217                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10218            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10219                pkgSetting.lastUpdateTime = currentTime;
10220            }
10221        } else if (pkgSetting.firstInstallTime == 0) {
10222            // We need *something*.  Take time time stamp of the file.
10223            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10224        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10225            if (scanFileTime != pkgSetting.timeStamp) {
10226                // A package on the system image has changed; consider this
10227                // to be an update.
10228                pkgSetting.lastUpdateTime = scanFileTime;
10229            }
10230        }
10231        pkgSetting.setTimeStamp(scanFileTime);
10232
10233        pkgSetting.pkg = pkg;
10234        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10235        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10236            pkgSetting.versionCode = pkg.getLongVersionCode();
10237        }
10238        // Update volume if needed
10239        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10240        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10241            Slog.i(PackageManagerService.TAG,
10242                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10243                    + " package " + pkg.packageName
10244                    + " volume from " + pkgSetting.volumeUuid
10245                    + " to " + volumeUuid);
10246            pkgSetting.volumeUuid = volumeUuid;
10247        }
10248
10249        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10250    }
10251
10252    /**
10253     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10254     */
10255    private static boolean apkHasCode(String fileName) {
10256        StrictJarFile jarFile = null;
10257        try {
10258            jarFile = new StrictJarFile(fileName,
10259                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10260            return jarFile.findEntry("classes.dex") != null;
10261        } catch (IOException ignore) {
10262        } finally {
10263            try {
10264                if (jarFile != null) {
10265                    jarFile.close();
10266                }
10267            } catch (IOException ignore) {}
10268        }
10269        return false;
10270    }
10271
10272    /**
10273     * Enforces code policy for the package. This ensures that if an APK has
10274     * declared hasCode="true" in its manifest that the APK actually contains
10275     * code.
10276     *
10277     * @throws PackageManagerException If bytecode could not be found when it should exist
10278     */
10279    private static void assertCodePolicy(PackageParser.Package pkg)
10280            throws PackageManagerException {
10281        final boolean shouldHaveCode =
10282                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10283        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10284            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10285                    "Package " + pkg.baseCodePath + " code is missing");
10286        }
10287
10288        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10289            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10290                final boolean splitShouldHaveCode =
10291                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10292                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10293                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10294                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10295                }
10296            }
10297        }
10298    }
10299
10300    /**
10301     * Applies policy to the parsed package based upon the given policy flags.
10302     * Ensures the package is in a good state.
10303     * <p>
10304     * Implementation detail: This method must NOT have any side effect. It would
10305     * ideally be static, but, it requires locks to read system state.
10306     */
10307    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10308            final @ScanFlags int scanFlags) {
10309        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10310            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10311            if (pkg.applicationInfo.isDirectBootAware()) {
10312                // we're direct boot aware; set for all components
10313                for (PackageParser.Service s : pkg.services) {
10314                    s.info.encryptionAware = s.info.directBootAware = true;
10315                }
10316                for (PackageParser.Provider p : pkg.providers) {
10317                    p.info.encryptionAware = p.info.directBootAware = true;
10318                }
10319                for (PackageParser.Activity a : pkg.activities) {
10320                    a.info.encryptionAware = a.info.directBootAware = true;
10321                }
10322                for (PackageParser.Activity r : pkg.receivers) {
10323                    r.info.encryptionAware = r.info.directBootAware = true;
10324                }
10325            }
10326            if (compressedFileExists(pkg.codePath)) {
10327                pkg.isStub = true;
10328            }
10329        } else {
10330            // non system apps can't be flagged as core
10331            pkg.coreApp = false;
10332            // clear flags not applicable to regular apps
10333            pkg.applicationInfo.flags &=
10334                    ~ApplicationInfo.FLAG_PERSISTENT;
10335            pkg.applicationInfo.privateFlags &=
10336                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10337            pkg.applicationInfo.privateFlags &=
10338                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10339            // clear protected broadcasts
10340            pkg.protectedBroadcasts = null;
10341            // cap permission priorities
10342            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10343                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10344                    pkg.permissionGroups.get(i).info.priority = 0;
10345                }
10346            }
10347        }
10348        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10349            // ignore export request for single user receivers
10350            if (pkg.receivers != null) {
10351                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10352                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10353                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10354                        receiver.info.exported = false;
10355                    }
10356                }
10357            }
10358            // ignore export request for single user services
10359            if (pkg.services != null) {
10360                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10361                    final PackageParser.Service service = pkg.services.get(i);
10362                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10363                        service.info.exported = false;
10364                    }
10365                }
10366            }
10367            // ignore export request for single user providers
10368            if (pkg.providers != null) {
10369                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10370                    final PackageParser.Provider provider = pkg.providers.get(i);
10371                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10372                        provider.info.exported = false;
10373                    }
10374                }
10375            }
10376        }
10377        pkg.mTrustedOverlay = (scanFlags & SCAN_TRUSTED_OVERLAY) != 0;
10378
10379        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10380            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10381        }
10382
10383        if ((scanFlags & SCAN_AS_OEM) != 0) {
10384            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10385        }
10386
10387        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10388            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10389        }
10390
10391        if (!isSystemApp(pkg)) {
10392            // Only system apps can use these features.
10393            pkg.mOriginalPackages = null;
10394            pkg.mRealPackage = null;
10395            pkg.mAdoptPermissions = null;
10396        }
10397    }
10398
10399    /**
10400     * Asserts the parsed package is valid according to the given policy. If the
10401     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10402     * <p>
10403     * Implementation detail: This method must NOT have any side effects. It would
10404     * ideally be static, but, it requires locks to read system state.
10405     *
10406     * @throws PackageManagerException If the package fails any of the validation checks
10407     */
10408    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10409            final @ScanFlags int scanFlags)
10410                    throws PackageManagerException {
10411        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10412            assertCodePolicy(pkg);
10413        }
10414
10415        if (pkg.applicationInfo.getCodePath() == null ||
10416                pkg.applicationInfo.getResourcePath() == null) {
10417            // Bail out. The resource and code paths haven't been set.
10418            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10419                    "Code and resource paths haven't been set correctly");
10420        }
10421
10422        // Make sure we're not adding any bogus keyset info
10423        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10424        ksms.assertScannedPackageValid(pkg);
10425
10426        synchronized (mPackages) {
10427            // The special "android" package can only be defined once
10428            if (pkg.packageName.equals("android")) {
10429                if (mAndroidApplication != null) {
10430                    Slog.w(TAG, "*************************************************");
10431                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10432                    Slog.w(TAG, " codePath=" + pkg.codePath);
10433                    Slog.w(TAG, "*************************************************");
10434                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10435                            "Core android package being redefined.  Skipping.");
10436                }
10437            }
10438
10439            // A package name must be unique; don't allow duplicates
10440            if (mPackages.containsKey(pkg.packageName)) {
10441                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10442                        "Application package " + pkg.packageName
10443                        + " already installed.  Skipping duplicate.");
10444            }
10445
10446            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10447                // Static libs have a synthetic package name containing the version
10448                // but we still want the base name to be unique.
10449                if (mPackages.containsKey(pkg.manifestPackageName)) {
10450                    throw new PackageManagerException(
10451                            "Duplicate static shared lib provider package");
10452                }
10453
10454                // Static shared libraries should have at least O target SDK
10455                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10456                    throw new PackageManagerException(
10457                            "Packages declaring static-shared libs must target O SDK or higher");
10458                }
10459
10460                // Package declaring static a shared lib cannot be instant apps
10461                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10462                    throw new PackageManagerException(
10463                            "Packages declaring static-shared libs cannot be instant apps");
10464                }
10465
10466                // Package declaring static a shared lib cannot be renamed since the package
10467                // name is synthetic and apps can't code around package manager internals.
10468                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10469                    throw new PackageManagerException(
10470                            "Packages declaring static-shared libs cannot be renamed");
10471                }
10472
10473                // Package declaring static a shared lib cannot declare child packages
10474                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10475                    throw new PackageManagerException(
10476                            "Packages declaring static-shared libs cannot have child packages");
10477                }
10478
10479                // Package declaring static a shared lib cannot declare dynamic libs
10480                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10481                    throw new PackageManagerException(
10482                            "Packages declaring static-shared libs cannot declare dynamic libs");
10483                }
10484
10485                // Package declaring static a shared lib cannot declare shared users
10486                if (pkg.mSharedUserId != null) {
10487                    throw new PackageManagerException(
10488                            "Packages declaring static-shared libs cannot declare shared users");
10489                }
10490
10491                // Static shared libs cannot declare activities
10492                if (!pkg.activities.isEmpty()) {
10493                    throw new PackageManagerException(
10494                            "Static shared libs cannot declare activities");
10495                }
10496
10497                // Static shared libs cannot declare services
10498                if (!pkg.services.isEmpty()) {
10499                    throw new PackageManagerException(
10500                            "Static shared libs cannot declare services");
10501                }
10502
10503                // Static shared libs cannot declare providers
10504                if (!pkg.providers.isEmpty()) {
10505                    throw new PackageManagerException(
10506                            "Static shared libs cannot declare content providers");
10507                }
10508
10509                // Static shared libs cannot declare receivers
10510                if (!pkg.receivers.isEmpty()) {
10511                    throw new PackageManagerException(
10512                            "Static shared libs cannot declare broadcast receivers");
10513                }
10514
10515                // Static shared libs cannot declare permission groups
10516                if (!pkg.permissionGroups.isEmpty()) {
10517                    throw new PackageManagerException(
10518                            "Static shared libs cannot declare permission groups");
10519                }
10520
10521                // Static shared libs cannot declare permissions
10522                if (!pkg.permissions.isEmpty()) {
10523                    throw new PackageManagerException(
10524                            "Static shared libs cannot declare permissions");
10525                }
10526
10527                // Static shared libs cannot declare protected broadcasts
10528                if (pkg.protectedBroadcasts != null) {
10529                    throw new PackageManagerException(
10530                            "Static shared libs cannot declare protected broadcasts");
10531                }
10532
10533                // Static shared libs cannot be overlay targets
10534                if (pkg.mOverlayTarget != null) {
10535                    throw new PackageManagerException(
10536                            "Static shared libs cannot be overlay targets");
10537                }
10538
10539                // The version codes must be ordered as lib versions
10540                long minVersionCode = Long.MIN_VALUE;
10541                long maxVersionCode = Long.MAX_VALUE;
10542
10543                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10544                        pkg.staticSharedLibName);
10545                if (versionedLib != null) {
10546                    final int versionCount = versionedLib.size();
10547                    for (int i = 0; i < versionCount; i++) {
10548                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10549                        final long libVersionCode = libInfo.getDeclaringPackage()
10550                                .getLongVersionCode();
10551                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10552                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10553                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10554                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10555                        } else {
10556                            minVersionCode = maxVersionCode = libVersionCode;
10557                            break;
10558                        }
10559                    }
10560                }
10561                if (pkg.getLongVersionCode() < minVersionCode
10562                        || pkg.getLongVersionCode() > maxVersionCode) {
10563                    throw new PackageManagerException("Static shared"
10564                            + " lib version codes must be ordered as lib versions");
10565                }
10566            }
10567
10568            // Only privileged apps and updated privileged apps can add child packages.
10569            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10570                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10571                    throw new PackageManagerException("Only privileged apps can add child "
10572                            + "packages. Ignoring package " + pkg.packageName);
10573                }
10574                final int childCount = pkg.childPackages.size();
10575                for (int i = 0; i < childCount; i++) {
10576                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10577                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10578                            childPkg.packageName)) {
10579                        throw new PackageManagerException("Can't override child of "
10580                                + "another disabled app. Ignoring package " + pkg.packageName);
10581                    }
10582                }
10583            }
10584
10585            // If we're only installing presumed-existing packages, require that the
10586            // scanned APK is both already known and at the path previously established
10587            // for it.  Previously unknown packages we pick up normally, but if we have an
10588            // a priori expectation about this package's install presence, enforce it.
10589            // With a singular exception for new system packages. When an OTA contains
10590            // a new system package, we allow the codepath to change from a system location
10591            // to the user-installed location. If we don't allow this change, any newer,
10592            // user-installed version of the application will be ignored.
10593            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10594                if (mExpectingBetter.containsKey(pkg.packageName)) {
10595                    logCriticalInfo(Log.WARN,
10596                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10597                } else {
10598                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10599                    if (known != null) {
10600                        if (DEBUG_PACKAGE_SCANNING) {
10601                            Log.d(TAG, "Examining " + pkg.codePath
10602                                    + " and requiring known paths " + known.codePathString
10603                                    + " & " + known.resourcePathString);
10604                        }
10605                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10606                                || !pkg.applicationInfo.getResourcePath().equals(
10607                                        known.resourcePathString)) {
10608                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10609                                    "Application package " + pkg.packageName
10610                                    + " found at " + pkg.applicationInfo.getCodePath()
10611                                    + " but expected at " + known.codePathString
10612                                    + "; ignoring.");
10613                        }
10614                    } else {
10615                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10616                                "Application package " + pkg.packageName
10617                                + " not found; ignoring.");
10618                    }
10619                }
10620            }
10621
10622            // Verify that this new package doesn't have any content providers
10623            // that conflict with existing packages.  Only do this if the
10624            // package isn't already installed, since we don't want to break
10625            // things that are installed.
10626            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10627                final int N = pkg.providers.size();
10628                int i;
10629                for (i=0; i<N; i++) {
10630                    PackageParser.Provider p = pkg.providers.get(i);
10631                    if (p.info.authority != null) {
10632                        String names[] = p.info.authority.split(";");
10633                        for (int j = 0; j < names.length; j++) {
10634                            if (mProvidersByAuthority.containsKey(names[j])) {
10635                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10636                                final String otherPackageName =
10637                                        ((other != null && other.getComponentName() != null) ?
10638                                                other.getComponentName().getPackageName() : "?");
10639                                throw new PackageManagerException(
10640                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10641                                        "Can't install because provider name " + names[j]
10642                                                + " (in package " + pkg.applicationInfo.packageName
10643                                                + ") is already used by " + otherPackageName);
10644                            }
10645                        }
10646                    }
10647                }
10648            }
10649        }
10650    }
10651
10652    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
10653            int type, String declaringPackageName, long declaringVersionCode) {
10654        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10655        if (versionedLib == null) {
10656            versionedLib = new LongSparseArray<>();
10657            mSharedLibraries.put(name, versionedLib);
10658            if (type == SharedLibraryInfo.TYPE_STATIC) {
10659                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10660            }
10661        } else if (versionedLib.indexOfKey(version) >= 0) {
10662            return false;
10663        }
10664        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10665                version, type, declaringPackageName, declaringVersionCode);
10666        versionedLib.put(version, libEntry);
10667        return true;
10668    }
10669
10670    private boolean removeSharedLibraryLPw(String name, long version) {
10671        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10672        if (versionedLib == null) {
10673            return false;
10674        }
10675        final int libIdx = versionedLib.indexOfKey(version);
10676        if (libIdx < 0) {
10677            return false;
10678        }
10679        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10680        versionedLib.remove(version);
10681        if (versionedLib.size() <= 0) {
10682            mSharedLibraries.remove(name);
10683            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10684                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10685                        .getPackageName());
10686            }
10687        }
10688        return true;
10689    }
10690
10691    /**
10692     * Adds a scanned package to the system. When this method is finished, the package will
10693     * be available for query, resolution, etc...
10694     */
10695    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10696            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
10697        final String pkgName = pkg.packageName;
10698        if (mCustomResolverComponentName != null &&
10699                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10700            setUpCustomResolverActivity(pkg);
10701        }
10702
10703        if (pkg.packageName.equals("android")) {
10704            synchronized (mPackages) {
10705                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10706                    // Set up information for our fall-back user intent resolution activity.
10707                    mPlatformPackage = pkg;
10708                    pkg.mVersionCode = mSdkVersion;
10709                    pkg.mVersionCodeMajor = 0;
10710                    mAndroidApplication = pkg.applicationInfo;
10711                    if (!mResolverReplaced) {
10712                        mResolveActivity.applicationInfo = mAndroidApplication;
10713                        mResolveActivity.name = ResolverActivity.class.getName();
10714                        mResolveActivity.packageName = mAndroidApplication.packageName;
10715                        mResolveActivity.processName = "system:ui";
10716                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10717                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10718                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10719                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10720                        mResolveActivity.exported = true;
10721                        mResolveActivity.enabled = true;
10722                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10723                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10724                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10725                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10726                                | ActivityInfo.CONFIG_ORIENTATION
10727                                | ActivityInfo.CONFIG_KEYBOARD
10728                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10729                        mResolveInfo.activityInfo = mResolveActivity;
10730                        mResolveInfo.priority = 0;
10731                        mResolveInfo.preferredOrder = 0;
10732                        mResolveInfo.match = 0;
10733                        mResolveComponentName = new ComponentName(
10734                                mAndroidApplication.packageName, mResolveActivity.name);
10735                    }
10736                }
10737            }
10738        }
10739
10740        ArrayList<PackageParser.Package> clientLibPkgs = null;
10741        // writer
10742        synchronized (mPackages) {
10743            boolean hasStaticSharedLibs = false;
10744
10745            // Any app can add new static shared libraries
10746            if (pkg.staticSharedLibName != null) {
10747                // Static shared libs don't allow renaming as they have synthetic package
10748                // names to allow install of multiple versions, so use name from manifest.
10749                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10750                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10751                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
10752                    hasStaticSharedLibs = true;
10753                } else {
10754                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10755                                + pkg.staticSharedLibName + " already exists; skipping");
10756                }
10757                // Static shared libs cannot be updated once installed since they
10758                // use synthetic package name which includes the version code, so
10759                // not need to update other packages's shared lib dependencies.
10760            }
10761
10762            if (!hasStaticSharedLibs
10763                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10764                // Only system apps can add new dynamic shared libraries.
10765                if (pkg.libraryNames != null) {
10766                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10767                        String name = pkg.libraryNames.get(i);
10768                        boolean allowed = false;
10769                        if (pkg.isUpdatedSystemApp()) {
10770                            // New library entries can only be added through the
10771                            // system image.  This is important to get rid of a lot
10772                            // of nasty edge cases: for example if we allowed a non-
10773                            // system update of the app to add a library, then uninstalling
10774                            // the update would make the library go away, and assumptions
10775                            // we made such as through app install filtering would now
10776                            // have allowed apps on the device which aren't compatible
10777                            // with it.  Better to just have the restriction here, be
10778                            // conservative, and create many fewer cases that can negatively
10779                            // impact the user experience.
10780                            final PackageSetting sysPs = mSettings
10781                                    .getDisabledSystemPkgLPr(pkg.packageName);
10782                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10783                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10784                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10785                                        allowed = true;
10786                                        break;
10787                                    }
10788                                }
10789                            }
10790                        } else {
10791                            allowed = true;
10792                        }
10793                        if (allowed) {
10794                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10795                                    SharedLibraryInfo.VERSION_UNDEFINED,
10796                                    SharedLibraryInfo.TYPE_DYNAMIC,
10797                                    pkg.packageName, pkg.getLongVersionCode())) {
10798                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10799                                        + name + " already exists; skipping");
10800                            }
10801                        } else {
10802                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10803                                    + name + " that is not declared on system image; skipping");
10804                        }
10805                    }
10806
10807                    if ((scanFlags & SCAN_BOOTING) == 0) {
10808                        // If we are not booting, we need to update any applications
10809                        // that are clients of our shared library.  If we are booting,
10810                        // this will all be done once the scan is complete.
10811                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10812                    }
10813                }
10814            }
10815        }
10816
10817        if ((scanFlags & SCAN_BOOTING) != 0) {
10818            // No apps can run during boot scan, so they don't need to be frozen
10819        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10820            // Caller asked to not kill app, so it's probably not frozen
10821        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10822            // Caller asked us to ignore frozen check for some reason; they
10823            // probably didn't know the package name
10824        } else {
10825            // We're doing major surgery on this package, so it better be frozen
10826            // right now to keep it from launching
10827            checkPackageFrozen(pkgName);
10828        }
10829
10830        // Also need to kill any apps that are dependent on the library.
10831        if (clientLibPkgs != null) {
10832            for (int i=0; i<clientLibPkgs.size(); i++) {
10833                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10834                killApplication(clientPkg.applicationInfo.packageName,
10835                        clientPkg.applicationInfo.uid, "update lib");
10836            }
10837        }
10838
10839        // writer
10840        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10841
10842        synchronized (mPackages) {
10843            // We don't expect installation to fail beyond this point
10844
10845            // Add the new setting to mSettings
10846            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10847            // Add the new setting to mPackages
10848            mPackages.put(pkg.applicationInfo.packageName, pkg);
10849            // Make sure we don't accidentally delete its data.
10850            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10851            while (iter.hasNext()) {
10852                PackageCleanItem item = iter.next();
10853                if (pkgName.equals(item.packageName)) {
10854                    iter.remove();
10855                }
10856            }
10857
10858            // Add the package's KeySets to the global KeySetManagerService
10859            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10860            ksms.addScannedPackageLPw(pkg);
10861
10862            int N = pkg.providers.size();
10863            StringBuilder r = null;
10864            int i;
10865            for (i=0; i<N; i++) {
10866                PackageParser.Provider p = pkg.providers.get(i);
10867                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10868                        p.info.processName);
10869                mProviders.addProvider(p);
10870                p.syncable = p.info.isSyncable;
10871                if (p.info.authority != null) {
10872                    String names[] = p.info.authority.split(";");
10873                    p.info.authority = null;
10874                    for (int j = 0; j < names.length; j++) {
10875                        if (j == 1 && p.syncable) {
10876                            // We only want the first authority for a provider to possibly be
10877                            // syncable, so if we already added this provider using a different
10878                            // authority clear the syncable flag. We copy the provider before
10879                            // changing it because the mProviders object contains a reference
10880                            // to a provider that we don't want to change.
10881                            // Only do this for the second authority since the resulting provider
10882                            // object can be the same for all future authorities for this provider.
10883                            p = new PackageParser.Provider(p);
10884                            p.syncable = false;
10885                        }
10886                        if (!mProvidersByAuthority.containsKey(names[j])) {
10887                            mProvidersByAuthority.put(names[j], p);
10888                            if (p.info.authority == null) {
10889                                p.info.authority = names[j];
10890                            } else {
10891                                p.info.authority = p.info.authority + ";" + names[j];
10892                            }
10893                            if (DEBUG_PACKAGE_SCANNING) {
10894                                if (chatty)
10895                                    Log.d(TAG, "Registered content provider: " + names[j]
10896                                            + ", className = " + p.info.name + ", isSyncable = "
10897                                            + p.info.isSyncable);
10898                            }
10899                        } else {
10900                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10901                            Slog.w(TAG, "Skipping provider name " + names[j] +
10902                                    " (in package " + pkg.applicationInfo.packageName +
10903                                    "): name already used by "
10904                                    + ((other != null && other.getComponentName() != null)
10905                                            ? other.getComponentName().getPackageName() : "?"));
10906                        }
10907                    }
10908                }
10909                if (chatty) {
10910                    if (r == null) {
10911                        r = new StringBuilder(256);
10912                    } else {
10913                        r.append(' ');
10914                    }
10915                    r.append(p.info.name);
10916                }
10917            }
10918            if (r != null) {
10919                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10920            }
10921
10922            N = pkg.services.size();
10923            r = null;
10924            for (i=0; i<N; i++) {
10925                PackageParser.Service s = pkg.services.get(i);
10926                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10927                        s.info.processName);
10928                mServices.addService(s);
10929                if (chatty) {
10930                    if (r == null) {
10931                        r = new StringBuilder(256);
10932                    } else {
10933                        r.append(' ');
10934                    }
10935                    r.append(s.info.name);
10936                }
10937            }
10938            if (r != null) {
10939                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10940            }
10941
10942            N = pkg.receivers.size();
10943            r = null;
10944            for (i=0; i<N; i++) {
10945                PackageParser.Activity a = pkg.receivers.get(i);
10946                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10947                        a.info.processName);
10948                mReceivers.addActivity(a, "receiver");
10949                if (chatty) {
10950                    if (r == null) {
10951                        r = new StringBuilder(256);
10952                    } else {
10953                        r.append(' ');
10954                    }
10955                    r.append(a.info.name);
10956                }
10957            }
10958            if (r != null) {
10959                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10960            }
10961
10962            N = pkg.activities.size();
10963            r = null;
10964            for (i=0; i<N; i++) {
10965                PackageParser.Activity a = pkg.activities.get(i);
10966                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10967                        a.info.processName);
10968                mActivities.addActivity(a, "activity");
10969                if (chatty) {
10970                    if (r == null) {
10971                        r = new StringBuilder(256);
10972                    } else {
10973                        r.append(' ');
10974                    }
10975                    r.append(a.info.name);
10976                }
10977            }
10978            if (r != null) {
10979                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10980            }
10981
10982            // Don't allow ephemeral applications to define new permissions groups.
10983            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10984                Slog.w(TAG, "Permission groups from package " + pkg.packageName
10985                        + " ignored: instant apps cannot define new permission groups.");
10986            } else {
10987                mPermissionManager.addAllPermissionGroups(pkg, chatty);
10988            }
10989
10990            // Don't allow ephemeral applications to define new permissions.
10991            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10992                Slog.w(TAG, "Permissions from package " + pkg.packageName
10993                        + " ignored: instant apps cannot define new permissions.");
10994            } else {
10995                mPermissionManager.addAllPermissions(pkg, chatty);
10996            }
10997
10998            N = pkg.instrumentation.size();
10999            r = null;
11000            for (i=0; i<N; i++) {
11001                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11002                a.info.packageName = pkg.applicationInfo.packageName;
11003                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11004                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11005                a.info.splitNames = pkg.splitNames;
11006                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11007                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11008                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11009                a.info.dataDir = pkg.applicationInfo.dataDir;
11010                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11011                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11012                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11013                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11014                mInstrumentation.put(a.getComponentName(), a);
11015                if (chatty) {
11016                    if (r == null) {
11017                        r = new StringBuilder(256);
11018                    } else {
11019                        r.append(' ');
11020                    }
11021                    r.append(a.info.name);
11022                }
11023            }
11024            if (r != null) {
11025                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11026            }
11027
11028            if (pkg.protectedBroadcasts != null) {
11029                N = pkg.protectedBroadcasts.size();
11030                synchronized (mProtectedBroadcasts) {
11031                    for (i = 0; i < N; i++) {
11032                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11033                    }
11034                }
11035            }
11036        }
11037
11038        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11039    }
11040
11041    /**
11042     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11043     * is derived purely on the basis of the contents of {@code scanFile} and
11044     * {@code cpuAbiOverride}.
11045     *
11046     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11047     */
11048    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11049            boolean extractLibs)
11050                    throws PackageManagerException {
11051        // Give ourselves some initial paths; we'll come back for another
11052        // pass once we've determined ABI below.
11053        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11054
11055        // We would never need to extract libs for forward-locked and external packages,
11056        // since the container service will do it for us. We shouldn't attempt to
11057        // extract libs from system app when it was not updated.
11058        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11059                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11060            extractLibs = false;
11061        }
11062
11063        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11064        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11065
11066        NativeLibraryHelper.Handle handle = null;
11067        try {
11068            handle = NativeLibraryHelper.Handle.create(pkg);
11069            // TODO(multiArch): This can be null for apps that didn't go through the
11070            // usual installation process. We can calculate it again, like we
11071            // do during install time.
11072            //
11073            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11074            // unnecessary.
11075            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11076
11077            // Null out the abis so that they can be recalculated.
11078            pkg.applicationInfo.primaryCpuAbi = null;
11079            pkg.applicationInfo.secondaryCpuAbi = null;
11080            if (isMultiArch(pkg.applicationInfo)) {
11081                // Warn if we've set an abiOverride for multi-lib packages..
11082                // By definition, we need to copy both 32 and 64 bit libraries for
11083                // such packages.
11084                if (pkg.cpuAbiOverride != null
11085                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11086                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11087                }
11088
11089                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11090                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11091                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11092                    if (extractLibs) {
11093                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11094                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11095                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11096                                useIsaSpecificSubdirs);
11097                    } else {
11098                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11099                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11100                    }
11101                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11102                }
11103
11104                // Shared library native code should be in the APK zip aligned
11105                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11106                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11107                            "Shared library native lib extraction not supported");
11108                }
11109
11110                maybeThrowExceptionForMultiArchCopy(
11111                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11112
11113                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11114                    if (extractLibs) {
11115                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11116                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11117                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11118                                useIsaSpecificSubdirs);
11119                    } else {
11120                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11121                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11122                    }
11123                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11124                }
11125
11126                maybeThrowExceptionForMultiArchCopy(
11127                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11128
11129                if (abi64 >= 0) {
11130                    // Shared library native libs should be in the APK zip aligned
11131                    if (extractLibs && pkg.isLibrary()) {
11132                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11133                                "Shared library native lib extraction not supported");
11134                    }
11135                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11136                }
11137
11138                if (abi32 >= 0) {
11139                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11140                    if (abi64 >= 0) {
11141                        if (pkg.use32bitAbi) {
11142                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11143                            pkg.applicationInfo.primaryCpuAbi = abi;
11144                        } else {
11145                            pkg.applicationInfo.secondaryCpuAbi = abi;
11146                        }
11147                    } else {
11148                        pkg.applicationInfo.primaryCpuAbi = abi;
11149                    }
11150                }
11151            } else {
11152                String[] abiList = (cpuAbiOverride != null) ?
11153                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11154
11155                // Enable gross and lame hacks for apps that are built with old
11156                // SDK tools. We must scan their APKs for renderscript bitcode and
11157                // not launch them if it's present. Don't bother checking on devices
11158                // that don't have 64 bit support.
11159                boolean needsRenderScriptOverride = false;
11160                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11161                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11162                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11163                    needsRenderScriptOverride = true;
11164                }
11165
11166                final int copyRet;
11167                if (extractLibs) {
11168                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11169                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11170                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11171                } else {
11172                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11173                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11174                }
11175                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11176
11177                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11178                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11179                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11180                }
11181
11182                if (copyRet >= 0) {
11183                    // Shared libraries that have native libs must be multi-architecture
11184                    if (pkg.isLibrary()) {
11185                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11186                                "Shared library with native libs must be multiarch");
11187                    }
11188                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11189                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11190                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11191                } else if (needsRenderScriptOverride) {
11192                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11193                }
11194            }
11195        } catch (IOException ioe) {
11196            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11197        } finally {
11198            IoUtils.closeQuietly(handle);
11199        }
11200
11201        // Now that we've calculated the ABIs and determined if it's an internal app,
11202        // we will go ahead and populate the nativeLibraryPath.
11203        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11204    }
11205
11206    /**
11207     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11208     * i.e, so that all packages can be run inside a single process if required.
11209     *
11210     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11211     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11212     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11213     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11214     * updating a package that belongs to a shared user.
11215     *
11216     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11217     * adds unnecessary complexity.
11218     */
11219    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11220            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11221        List<String> changedAbiCodePath = null;
11222        String requiredInstructionSet = null;
11223        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11224            requiredInstructionSet = VMRuntime.getInstructionSet(
11225                     scannedPackage.applicationInfo.primaryCpuAbi);
11226        }
11227
11228        PackageSetting requirer = null;
11229        for (PackageSetting ps : packagesForUser) {
11230            // If packagesForUser contains scannedPackage, we skip it. This will happen
11231            // when scannedPackage is an update of an existing package. Without this check,
11232            // we will never be able to change the ABI of any package belonging to a shared
11233            // user, even if it's compatible with other packages.
11234            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11235                if (ps.primaryCpuAbiString == null) {
11236                    continue;
11237                }
11238
11239                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11240                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11241                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11242                    // this but there's not much we can do.
11243                    String errorMessage = "Instruction set mismatch, "
11244                            + ((requirer == null) ? "[caller]" : requirer)
11245                            + " requires " + requiredInstructionSet + " whereas " + ps
11246                            + " requires " + instructionSet;
11247                    Slog.w(TAG, errorMessage);
11248                }
11249
11250                if (requiredInstructionSet == null) {
11251                    requiredInstructionSet = instructionSet;
11252                    requirer = ps;
11253                }
11254            }
11255        }
11256
11257        if (requiredInstructionSet != null) {
11258            String adjustedAbi;
11259            if (requirer != null) {
11260                // requirer != null implies that either scannedPackage was null or that scannedPackage
11261                // did not require an ABI, in which case we have to adjust scannedPackage to match
11262                // the ABI of the set (which is the same as requirer's ABI)
11263                adjustedAbi = requirer.primaryCpuAbiString;
11264                if (scannedPackage != null) {
11265                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11266                }
11267            } else {
11268                // requirer == null implies that we're updating all ABIs in the set to
11269                // match scannedPackage.
11270                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11271            }
11272
11273            for (PackageSetting ps : packagesForUser) {
11274                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11275                    if (ps.primaryCpuAbiString != null) {
11276                        continue;
11277                    }
11278
11279                    ps.primaryCpuAbiString = adjustedAbi;
11280                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11281                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11282                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11283                        if (DEBUG_ABI_SELECTION) {
11284                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11285                                    + " (requirer="
11286                                    + (requirer != null ? requirer.pkg : "null")
11287                                    + ", scannedPackage="
11288                                    + (scannedPackage != null ? scannedPackage : "null")
11289                                    + ")");
11290                        }
11291                        if (changedAbiCodePath == null) {
11292                            changedAbiCodePath = new ArrayList<>();
11293                        }
11294                        changedAbiCodePath.add(ps.codePathString);
11295                    }
11296                }
11297            }
11298        }
11299        return changedAbiCodePath;
11300    }
11301
11302    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11303        synchronized (mPackages) {
11304            mResolverReplaced = true;
11305            // Set up information for custom user intent resolution activity.
11306            mResolveActivity.applicationInfo = pkg.applicationInfo;
11307            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11308            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11309            mResolveActivity.processName = pkg.applicationInfo.packageName;
11310            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11311            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11312                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11313            mResolveActivity.theme = 0;
11314            mResolveActivity.exported = true;
11315            mResolveActivity.enabled = true;
11316            mResolveInfo.activityInfo = mResolveActivity;
11317            mResolveInfo.priority = 0;
11318            mResolveInfo.preferredOrder = 0;
11319            mResolveInfo.match = 0;
11320            mResolveComponentName = mCustomResolverComponentName;
11321            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11322                    mResolveComponentName);
11323        }
11324    }
11325
11326    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11327        if (installerActivity == null) {
11328            if (DEBUG_EPHEMERAL) {
11329                Slog.d(TAG, "Clear ephemeral installer activity");
11330            }
11331            mInstantAppInstallerActivity = null;
11332            return;
11333        }
11334
11335        if (DEBUG_EPHEMERAL) {
11336            Slog.d(TAG, "Set ephemeral installer activity: "
11337                    + installerActivity.getComponentName());
11338        }
11339        // Set up information for ephemeral installer activity
11340        mInstantAppInstallerActivity = installerActivity;
11341        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11342                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11343        mInstantAppInstallerActivity.exported = true;
11344        mInstantAppInstallerActivity.enabled = true;
11345        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11346        mInstantAppInstallerInfo.priority = 0;
11347        mInstantAppInstallerInfo.preferredOrder = 1;
11348        mInstantAppInstallerInfo.isDefault = true;
11349        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11350                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11351    }
11352
11353    private static String calculateBundledApkRoot(final String codePathString) {
11354        final File codePath = new File(codePathString);
11355        final File codeRoot;
11356        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11357            codeRoot = Environment.getRootDirectory();
11358        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11359            codeRoot = Environment.getOemDirectory();
11360        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11361            codeRoot = Environment.getVendorDirectory();
11362        } else {
11363            // Unrecognized code path; take its top real segment as the apk root:
11364            // e.g. /something/app/blah.apk => /something
11365            try {
11366                File f = codePath.getCanonicalFile();
11367                File parent = f.getParentFile();    // non-null because codePath is a file
11368                File tmp;
11369                while ((tmp = parent.getParentFile()) != null) {
11370                    f = parent;
11371                    parent = tmp;
11372                }
11373                codeRoot = f;
11374                Slog.w(TAG, "Unrecognized code path "
11375                        + codePath + " - using " + codeRoot);
11376            } catch (IOException e) {
11377                // Can't canonicalize the code path -- shenanigans?
11378                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11379                return Environment.getRootDirectory().getPath();
11380            }
11381        }
11382        return codeRoot.getPath();
11383    }
11384
11385    /**
11386     * Derive and set the location of native libraries for the given package,
11387     * which varies depending on where and how the package was installed.
11388     */
11389    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11390        final ApplicationInfo info = pkg.applicationInfo;
11391        final String codePath = pkg.codePath;
11392        final File codeFile = new File(codePath);
11393        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11394        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11395
11396        info.nativeLibraryRootDir = null;
11397        info.nativeLibraryRootRequiresIsa = false;
11398        info.nativeLibraryDir = null;
11399        info.secondaryNativeLibraryDir = null;
11400
11401        if (isApkFile(codeFile)) {
11402            // Monolithic install
11403            if (bundledApp) {
11404                // If "/system/lib64/apkname" exists, assume that is the per-package
11405                // native library directory to use; otherwise use "/system/lib/apkname".
11406                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11407                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11408                        getPrimaryInstructionSet(info));
11409
11410                // This is a bundled system app so choose the path based on the ABI.
11411                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11412                // is just the default path.
11413                final String apkName = deriveCodePathName(codePath);
11414                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11415                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11416                        apkName).getAbsolutePath();
11417
11418                if (info.secondaryCpuAbi != null) {
11419                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11420                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11421                            secondaryLibDir, apkName).getAbsolutePath();
11422                }
11423            } else if (asecApp) {
11424                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11425                        .getAbsolutePath();
11426            } else {
11427                final String apkName = deriveCodePathName(codePath);
11428                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11429                        .getAbsolutePath();
11430            }
11431
11432            info.nativeLibraryRootRequiresIsa = false;
11433            info.nativeLibraryDir = info.nativeLibraryRootDir;
11434        } else {
11435            // Cluster install
11436            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11437            info.nativeLibraryRootRequiresIsa = true;
11438
11439            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11440                    getPrimaryInstructionSet(info)).getAbsolutePath();
11441
11442            if (info.secondaryCpuAbi != null) {
11443                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11444                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11445            }
11446        }
11447    }
11448
11449    /**
11450     * Calculate the abis and roots for a bundled app. These can uniquely
11451     * be determined from the contents of the system partition, i.e whether
11452     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11453     * of this information, and instead assume that the system was built
11454     * sensibly.
11455     */
11456    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11457                                           PackageSetting pkgSetting) {
11458        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11459
11460        // If "/system/lib64/apkname" exists, assume that is the per-package
11461        // native library directory to use; otherwise use "/system/lib/apkname".
11462        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11463        setBundledAppAbi(pkg, apkRoot, apkName);
11464        // pkgSetting might be null during rescan following uninstall of updates
11465        // to a bundled app, so accommodate that possibility.  The settings in
11466        // that case will be established later from the parsed package.
11467        //
11468        // If the settings aren't null, sync them up with what we've just derived.
11469        // note that apkRoot isn't stored in the package settings.
11470        if (pkgSetting != null) {
11471            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11472            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11473        }
11474    }
11475
11476    /**
11477     * Deduces the ABI of a bundled app and sets the relevant fields on the
11478     * parsed pkg object.
11479     *
11480     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11481     *        under which system libraries are installed.
11482     * @param apkName the name of the installed package.
11483     */
11484    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11485        final File codeFile = new File(pkg.codePath);
11486
11487        final boolean has64BitLibs;
11488        final boolean has32BitLibs;
11489        if (isApkFile(codeFile)) {
11490            // Monolithic install
11491            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11492            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11493        } else {
11494            // Cluster install
11495            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11496            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11497                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11498                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11499                has64BitLibs = (new File(rootDir, isa)).exists();
11500            } else {
11501                has64BitLibs = false;
11502            }
11503            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11504                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11505                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11506                has32BitLibs = (new File(rootDir, isa)).exists();
11507            } else {
11508                has32BitLibs = false;
11509            }
11510        }
11511
11512        if (has64BitLibs && !has32BitLibs) {
11513            // The package has 64 bit libs, but not 32 bit libs. Its primary
11514            // ABI should be 64 bit. We can safely assume here that the bundled
11515            // native libraries correspond to the most preferred ABI in the list.
11516
11517            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11518            pkg.applicationInfo.secondaryCpuAbi = null;
11519        } else if (has32BitLibs && !has64BitLibs) {
11520            // The package has 32 bit libs but not 64 bit libs. Its primary
11521            // ABI should be 32 bit.
11522
11523            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11524            pkg.applicationInfo.secondaryCpuAbi = null;
11525        } else if (has32BitLibs && has64BitLibs) {
11526            // The application has both 64 and 32 bit bundled libraries. We check
11527            // here that the app declares multiArch support, and warn if it doesn't.
11528            //
11529            // We will be lenient here and record both ABIs. The primary will be the
11530            // ABI that's higher on the list, i.e, a device that's configured to prefer
11531            // 64 bit apps will see a 64 bit primary ABI,
11532
11533            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11534                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11535            }
11536
11537            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11538                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11539                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11540            } else {
11541                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11542                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11543            }
11544        } else {
11545            pkg.applicationInfo.primaryCpuAbi = null;
11546            pkg.applicationInfo.secondaryCpuAbi = null;
11547        }
11548    }
11549
11550    private void killApplication(String pkgName, int appId, String reason) {
11551        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11552    }
11553
11554    private void killApplication(String pkgName, int appId, int userId, String reason) {
11555        // Request the ActivityManager to kill the process(only for existing packages)
11556        // so that we do not end up in a confused state while the user is still using the older
11557        // version of the application while the new one gets installed.
11558        final long token = Binder.clearCallingIdentity();
11559        try {
11560            IActivityManager am = ActivityManager.getService();
11561            if (am != null) {
11562                try {
11563                    am.killApplication(pkgName, appId, userId, reason);
11564                } catch (RemoteException e) {
11565                }
11566            }
11567        } finally {
11568            Binder.restoreCallingIdentity(token);
11569        }
11570    }
11571
11572    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11573        // Remove the parent package setting
11574        PackageSetting ps = (PackageSetting) pkg.mExtras;
11575        if (ps != null) {
11576            removePackageLI(ps, chatty);
11577        }
11578        // Remove the child package setting
11579        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11580        for (int i = 0; i < childCount; i++) {
11581            PackageParser.Package childPkg = pkg.childPackages.get(i);
11582            ps = (PackageSetting) childPkg.mExtras;
11583            if (ps != null) {
11584                removePackageLI(ps, chatty);
11585            }
11586        }
11587    }
11588
11589    void removePackageLI(PackageSetting ps, boolean chatty) {
11590        if (DEBUG_INSTALL) {
11591            if (chatty)
11592                Log.d(TAG, "Removing package " + ps.name);
11593        }
11594
11595        // writer
11596        synchronized (mPackages) {
11597            mPackages.remove(ps.name);
11598            final PackageParser.Package pkg = ps.pkg;
11599            if (pkg != null) {
11600                cleanPackageDataStructuresLILPw(pkg, chatty);
11601            }
11602        }
11603    }
11604
11605    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11606        if (DEBUG_INSTALL) {
11607            if (chatty)
11608                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11609        }
11610
11611        // writer
11612        synchronized (mPackages) {
11613            // Remove the parent package
11614            mPackages.remove(pkg.applicationInfo.packageName);
11615            cleanPackageDataStructuresLILPw(pkg, chatty);
11616
11617            // Remove the child packages
11618            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11619            for (int i = 0; i < childCount; i++) {
11620                PackageParser.Package childPkg = pkg.childPackages.get(i);
11621                mPackages.remove(childPkg.applicationInfo.packageName);
11622                cleanPackageDataStructuresLILPw(childPkg, chatty);
11623            }
11624        }
11625    }
11626
11627    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11628        int N = pkg.providers.size();
11629        StringBuilder r = null;
11630        int i;
11631        for (i=0; i<N; i++) {
11632            PackageParser.Provider p = pkg.providers.get(i);
11633            mProviders.removeProvider(p);
11634            if (p.info.authority == null) {
11635
11636                /* There was another ContentProvider with this authority when
11637                 * this app was installed so this authority is null,
11638                 * Ignore it as we don't have to unregister the provider.
11639                 */
11640                continue;
11641            }
11642            String names[] = p.info.authority.split(";");
11643            for (int j = 0; j < names.length; j++) {
11644                if (mProvidersByAuthority.get(names[j]) == p) {
11645                    mProvidersByAuthority.remove(names[j]);
11646                    if (DEBUG_REMOVE) {
11647                        if (chatty)
11648                            Log.d(TAG, "Unregistered content provider: " + names[j]
11649                                    + ", className = " + p.info.name + ", isSyncable = "
11650                                    + p.info.isSyncable);
11651                    }
11652                }
11653            }
11654            if (DEBUG_REMOVE && chatty) {
11655                if (r == null) {
11656                    r = new StringBuilder(256);
11657                } else {
11658                    r.append(' ');
11659                }
11660                r.append(p.info.name);
11661            }
11662        }
11663        if (r != null) {
11664            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11665        }
11666
11667        N = pkg.services.size();
11668        r = null;
11669        for (i=0; i<N; i++) {
11670            PackageParser.Service s = pkg.services.get(i);
11671            mServices.removeService(s);
11672            if (chatty) {
11673                if (r == null) {
11674                    r = new StringBuilder(256);
11675                } else {
11676                    r.append(' ');
11677                }
11678                r.append(s.info.name);
11679            }
11680        }
11681        if (r != null) {
11682            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11683        }
11684
11685        N = pkg.receivers.size();
11686        r = null;
11687        for (i=0; i<N; i++) {
11688            PackageParser.Activity a = pkg.receivers.get(i);
11689            mReceivers.removeActivity(a, "receiver");
11690            if (DEBUG_REMOVE && chatty) {
11691                if (r == null) {
11692                    r = new StringBuilder(256);
11693                } else {
11694                    r.append(' ');
11695                }
11696                r.append(a.info.name);
11697            }
11698        }
11699        if (r != null) {
11700            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11701        }
11702
11703        N = pkg.activities.size();
11704        r = null;
11705        for (i=0; i<N; i++) {
11706            PackageParser.Activity a = pkg.activities.get(i);
11707            mActivities.removeActivity(a, "activity");
11708            if (DEBUG_REMOVE && chatty) {
11709                if (r == null) {
11710                    r = new StringBuilder(256);
11711                } else {
11712                    r.append(' ');
11713                }
11714                r.append(a.info.name);
11715            }
11716        }
11717        if (r != null) {
11718            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11719        }
11720
11721        mPermissionManager.removeAllPermissions(pkg, chatty);
11722
11723        N = pkg.instrumentation.size();
11724        r = null;
11725        for (i=0; i<N; i++) {
11726            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11727            mInstrumentation.remove(a.getComponentName());
11728            if (DEBUG_REMOVE && chatty) {
11729                if (r == null) {
11730                    r = new StringBuilder(256);
11731                } else {
11732                    r.append(' ');
11733                }
11734                r.append(a.info.name);
11735            }
11736        }
11737        if (r != null) {
11738            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11739        }
11740
11741        r = null;
11742        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11743            // Only system apps can hold shared libraries.
11744            if (pkg.libraryNames != null) {
11745                for (i = 0; i < pkg.libraryNames.size(); i++) {
11746                    String name = pkg.libraryNames.get(i);
11747                    if (removeSharedLibraryLPw(name, 0)) {
11748                        if (DEBUG_REMOVE && chatty) {
11749                            if (r == null) {
11750                                r = new StringBuilder(256);
11751                            } else {
11752                                r.append(' ');
11753                            }
11754                            r.append(name);
11755                        }
11756                    }
11757                }
11758            }
11759        }
11760
11761        r = null;
11762
11763        // Any package can hold static shared libraries.
11764        if (pkg.staticSharedLibName != null) {
11765            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11766                if (DEBUG_REMOVE && chatty) {
11767                    if (r == null) {
11768                        r = new StringBuilder(256);
11769                    } else {
11770                        r.append(' ');
11771                    }
11772                    r.append(pkg.staticSharedLibName);
11773                }
11774            }
11775        }
11776
11777        if (r != null) {
11778            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11779        }
11780    }
11781
11782
11783    final class ActivityIntentResolver
11784            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11785        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11786                boolean defaultOnly, int userId) {
11787            if (!sUserManager.exists(userId)) return null;
11788            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11789            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11790        }
11791
11792        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11793                int userId) {
11794            if (!sUserManager.exists(userId)) return null;
11795            mFlags = flags;
11796            return super.queryIntent(intent, resolvedType,
11797                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11798                    userId);
11799        }
11800
11801        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11802                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11803            if (!sUserManager.exists(userId)) return null;
11804            if (packageActivities == null) {
11805                return null;
11806            }
11807            mFlags = flags;
11808            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11809            final int N = packageActivities.size();
11810            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11811                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11812
11813            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11814            for (int i = 0; i < N; ++i) {
11815                intentFilters = packageActivities.get(i).intents;
11816                if (intentFilters != null && intentFilters.size() > 0) {
11817                    PackageParser.ActivityIntentInfo[] array =
11818                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
11819                    intentFilters.toArray(array);
11820                    listCut.add(array);
11821                }
11822            }
11823            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11824        }
11825
11826        /**
11827         * Finds a privileged activity that matches the specified activity names.
11828         */
11829        private PackageParser.Activity findMatchingActivity(
11830                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
11831            for (PackageParser.Activity sysActivity : activityList) {
11832                if (sysActivity.info.name.equals(activityInfo.name)) {
11833                    return sysActivity;
11834                }
11835                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
11836                    return sysActivity;
11837                }
11838                if (sysActivity.info.targetActivity != null) {
11839                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
11840                        return sysActivity;
11841                    }
11842                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
11843                        return sysActivity;
11844                    }
11845                }
11846            }
11847            return null;
11848        }
11849
11850        public class IterGenerator<E> {
11851            public Iterator<E> generate(ActivityIntentInfo info) {
11852                return null;
11853            }
11854        }
11855
11856        public class ActionIterGenerator extends IterGenerator<String> {
11857            @Override
11858            public Iterator<String> generate(ActivityIntentInfo info) {
11859                return info.actionsIterator();
11860            }
11861        }
11862
11863        public class CategoriesIterGenerator extends IterGenerator<String> {
11864            @Override
11865            public Iterator<String> generate(ActivityIntentInfo info) {
11866                return info.categoriesIterator();
11867            }
11868        }
11869
11870        public class SchemesIterGenerator extends IterGenerator<String> {
11871            @Override
11872            public Iterator<String> generate(ActivityIntentInfo info) {
11873                return info.schemesIterator();
11874            }
11875        }
11876
11877        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
11878            @Override
11879            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
11880                return info.authoritiesIterator();
11881            }
11882        }
11883
11884        /**
11885         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
11886         * MODIFIED. Do not pass in a list that should not be changed.
11887         */
11888        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
11889                IterGenerator<T> generator, Iterator<T> searchIterator) {
11890            // loop through the set of actions; every one must be found in the intent filter
11891            while (searchIterator.hasNext()) {
11892                // we must have at least one filter in the list to consider a match
11893                if (intentList.size() == 0) {
11894                    break;
11895                }
11896
11897                final T searchAction = searchIterator.next();
11898
11899                // loop through the set of intent filters
11900                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
11901                while (intentIter.hasNext()) {
11902                    final ActivityIntentInfo intentInfo = intentIter.next();
11903                    boolean selectionFound = false;
11904
11905                    // loop through the intent filter's selection criteria; at least one
11906                    // of them must match the searched criteria
11907                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
11908                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
11909                        final T intentSelection = intentSelectionIter.next();
11910                        if (intentSelection != null && intentSelection.equals(searchAction)) {
11911                            selectionFound = true;
11912                            break;
11913                        }
11914                    }
11915
11916                    // the selection criteria wasn't found in this filter's set; this filter
11917                    // is not a potential match
11918                    if (!selectionFound) {
11919                        intentIter.remove();
11920                    }
11921                }
11922            }
11923        }
11924
11925        private boolean isProtectedAction(ActivityIntentInfo filter) {
11926            final Iterator<String> actionsIter = filter.actionsIterator();
11927            while (actionsIter != null && actionsIter.hasNext()) {
11928                final String filterAction = actionsIter.next();
11929                if (PROTECTED_ACTIONS.contains(filterAction)) {
11930                    return true;
11931                }
11932            }
11933            return false;
11934        }
11935
11936        /**
11937         * Adjusts the priority of the given intent filter according to policy.
11938         * <p>
11939         * <ul>
11940         * <li>The priority for non privileged applications is capped to '0'</li>
11941         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
11942         * <li>The priority for unbundled updates to privileged applications is capped to the
11943         *      priority defined on the system partition</li>
11944         * </ul>
11945         * <p>
11946         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
11947         * allowed to obtain any priority on any action.
11948         */
11949        private void adjustPriority(
11950                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
11951            // nothing to do; priority is fine as-is
11952            if (intent.getPriority() <= 0) {
11953                return;
11954            }
11955
11956            final ActivityInfo activityInfo = intent.activity.info;
11957            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
11958
11959            final boolean privilegedApp =
11960                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
11961            if (!privilegedApp) {
11962                // non-privileged applications can never define a priority >0
11963                if (DEBUG_FILTERS) {
11964                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
11965                            + " package: " + applicationInfo.packageName
11966                            + " activity: " + intent.activity.className
11967                            + " origPrio: " + intent.getPriority());
11968                }
11969                intent.setPriority(0);
11970                return;
11971            }
11972
11973            if (systemActivities == null) {
11974                // the system package is not disabled; we're parsing the system partition
11975                if (isProtectedAction(intent)) {
11976                    if (mDeferProtectedFilters) {
11977                        // We can't deal with these just yet. No component should ever obtain a
11978                        // >0 priority for a protected actions, with ONE exception -- the setup
11979                        // wizard. The setup wizard, however, cannot be known until we're able to
11980                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
11981                        // until all intent filters have been processed. Chicken, meet egg.
11982                        // Let the filter temporarily have a high priority and rectify the
11983                        // priorities after all system packages have been scanned.
11984                        mProtectedFilters.add(intent);
11985                        if (DEBUG_FILTERS) {
11986                            Slog.i(TAG, "Protected action; save for later;"
11987                                    + " package: " + applicationInfo.packageName
11988                                    + " activity: " + intent.activity.className
11989                                    + " origPrio: " + intent.getPriority());
11990                        }
11991                        return;
11992                    } else {
11993                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
11994                            Slog.i(TAG, "No setup wizard;"
11995                                + " All protected intents capped to priority 0");
11996                        }
11997                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
11998                            if (DEBUG_FILTERS) {
11999                                Slog.i(TAG, "Found setup wizard;"
12000                                    + " allow priority " + intent.getPriority() + ";"
12001                                    + " package: " + intent.activity.info.packageName
12002                                    + " activity: " + intent.activity.className
12003                                    + " priority: " + intent.getPriority());
12004                            }
12005                            // setup wizard gets whatever it wants
12006                            return;
12007                        }
12008                        if (DEBUG_FILTERS) {
12009                            Slog.i(TAG, "Protected action; cap priority to 0;"
12010                                    + " package: " + intent.activity.info.packageName
12011                                    + " activity: " + intent.activity.className
12012                                    + " origPrio: " + intent.getPriority());
12013                        }
12014                        intent.setPriority(0);
12015                        return;
12016                    }
12017                }
12018                // privileged apps on the system image get whatever priority they request
12019                return;
12020            }
12021
12022            // privileged app unbundled update ... try to find the same activity
12023            final PackageParser.Activity foundActivity =
12024                    findMatchingActivity(systemActivities, activityInfo);
12025            if (foundActivity == null) {
12026                // this is a new activity; it cannot obtain >0 priority
12027                if (DEBUG_FILTERS) {
12028                    Slog.i(TAG, "New activity; cap priority to 0;"
12029                            + " package: " + applicationInfo.packageName
12030                            + " activity: " + intent.activity.className
12031                            + " origPrio: " + intent.getPriority());
12032                }
12033                intent.setPriority(0);
12034                return;
12035            }
12036
12037            // found activity, now check for filter equivalence
12038
12039            // a shallow copy is enough; we modify the list, not its contents
12040            final List<ActivityIntentInfo> intentListCopy =
12041                    new ArrayList<>(foundActivity.intents);
12042            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12043
12044            // find matching action subsets
12045            final Iterator<String> actionsIterator = intent.actionsIterator();
12046            if (actionsIterator != null) {
12047                getIntentListSubset(
12048                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12049                if (intentListCopy.size() == 0) {
12050                    // no more intents to match; we're not equivalent
12051                    if (DEBUG_FILTERS) {
12052                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12053                                + " package: " + applicationInfo.packageName
12054                                + " activity: " + intent.activity.className
12055                                + " origPrio: " + intent.getPriority());
12056                    }
12057                    intent.setPriority(0);
12058                    return;
12059                }
12060            }
12061
12062            // find matching category subsets
12063            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12064            if (categoriesIterator != null) {
12065                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12066                        categoriesIterator);
12067                if (intentListCopy.size() == 0) {
12068                    // no more intents to match; we're not equivalent
12069                    if (DEBUG_FILTERS) {
12070                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12071                                + " package: " + applicationInfo.packageName
12072                                + " activity: " + intent.activity.className
12073                                + " origPrio: " + intent.getPriority());
12074                    }
12075                    intent.setPriority(0);
12076                    return;
12077                }
12078            }
12079
12080            // find matching schemes subsets
12081            final Iterator<String> schemesIterator = intent.schemesIterator();
12082            if (schemesIterator != null) {
12083                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12084                        schemesIterator);
12085                if (intentListCopy.size() == 0) {
12086                    // no more intents to match; we're not equivalent
12087                    if (DEBUG_FILTERS) {
12088                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12089                                + " package: " + applicationInfo.packageName
12090                                + " activity: " + intent.activity.className
12091                                + " origPrio: " + intent.getPriority());
12092                    }
12093                    intent.setPriority(0);
12094                    return;
12095                }
12096            }
12097
12098            // find matching authorities subsets
12099            final Iterator<IntentFilter.AuthorityEntry>
12100                    authoritiesIterator = intent.authoritiesIterator();
12101            if (authoritiesIterator != null) {
12102                getIntentListSubset(intentListCopy,
12103                        new AuthoritiesIterGenerator(),
12104                        authoritiesIterator);
12105                if (intentListCopy.size() == 0) {
12106                    // no more intents to match; we're not equivalent
12107                    if (DEBUG_FILTERS) {
12108                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12109                                + " package: " + applicationInfo.packageName
12110                                + " activity: " + intent.activity.className
12111                                + " origPrio: " + intent.getPriority());
12112                    }
12113                    intent.setPriority(0);
12114                    return;
12115                }
12116            }
12117
12118            // we found matching filter(s); app gets the max priority of all intents
12119            int cappedPriority = 0;
12120            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12121                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12122            }
12123            if (intent.getPriority() > cappedPriority) {
12124                if (DEBUG_FILTERS) {
12125                    Slog.i(TAG, "Found matching filter(s);"
12126                            + " cap priority to " + cappedPriority + ";"
12127                            + " package: " + applicationInfo.packageName
12128                            + " activity: " + intent.activity.className
12129                            + " origPrio: " + intent.getPriority());
12130                }
12131                intent.setPriority(cappedPriority);
12132                return;
12133            }
12134            // all this for nothing; the requested priority was <= what was on the system
12135        }
12136
12137        public final void addActivity(PackageParser.Activity a, String type) {
12138            mActivities.put(a.getComponentName(), a);
12139            if (DEBUG_SHOW_INFO)
12140                Log.v(
12141                TAG, "  " + type + " " +
12142                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12143            if (DEBUG_SHOW_INFO)
12144                Log.v(TAG, "    Class=" + a.info.name);
12145            final int NI = a.intents.size();
12146            for (int j=0; j<NI; j++) {
12147                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12148                if ("activity".equals(type)) {
12149                    final PackageSetting ps =
12150                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12151                    final List<PackageParser.Activity> systemActivities =
12152                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12153                    adjustPriority(systemActivities, intent);
12154                }
12155                if (DEBUG_SHOW_INFO) {
12156                    Log.v(TAG, "    IntentFilter:");
12157                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12158                }
12159                if (!intent.debugCheck()) {
12160                    Log.w(TAG, "==> For Activity " + a.info.name);
12161                }
12162                addFilter(intent);
12163            }
12164        }
12165
12166        public final void removeActivity(PackageParser.Activity a, String type) {
12167            mActivities.remove(a.getComponentName());
12168            if (DEBUG_SHOW_INFO) {
12169                Log.v(TAG, "  " + type + " "
12170                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12171                                : a.info.name) + ":");
12172                Log.v(TAG, "    Class=" + a.info.name);
12173            }
12174            final int NI = a.intents.size();
12175            for (int j=0; j<NI; j++) {
12176                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12177                if (DEBUG_SHOW_INFO) {
12178                    Log.v(TAG, "    IntentFilter:");
12179                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12180                }
12181                removeFilter(intent);
12182            }
12183        }
12184
12185        @Override
12186        protected boolean allowFilterResult(
12187                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12188            ActivityInfo filterAi = filter.activity.info;
12189            for (int i=dest.size()-1; i>=0; i--) {
12190                ActivityInfo destAi = dest.get(i).activityInfo;
12191                if (destAi.name == filterAi.name
12192                        && destAi.packageName == filterAi.packageName) {
12193                    return false;
12194                }
12195            }
12196            return true;
12197        }
12198
12199        @Override
12200        protected ActivityIntentInfo[] newArray(int size) {
12201            return new ActivityIntentInfo[size];
12202        }
12203
12204        @Override
12205        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12206            if (!sUserManager.exists(userId)) return true;
12207            PackageParser.Package p = filter.activity.owner;
12208            if (p != null) {
12209                PackageSetting ps = (PackageSetting)p.mExtras;
12210                if (ps != null) {
12211                    // System apps are never considered stopped for purposes of
12212                    // filtering, because there may be no way for the user to
12213                    // actually re-launch them.
12214                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12215                            && ps.getStopped(userId);
12216                }
12217            }
12218            return false;
12219        }
12220
12221        @Override
12222        protected boolean isPackageForFilter(String packageName,
12223                PackageParser.ActivityIntentInfo info) {
12224            return packageName.equals(info.activity.owner.packageName);
12225        }
12226
12227        @Override
12228        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12229                int match, int userId) {
12230            if (!sUserManager.exists(userId)) return null;
12231            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12232                return null;
12233            }
12234            final PackageParser.Activity activity = info.activity;
12235            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12236            if (ps == null) {
12237                return null;
12238            }
12239            final PackageUserState userState = ps.readUserState(userId);
12240            ActivityInfo ai =
12241                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12242            if (ai == null) {
12243                return null;
12244            }
12245            final boolean matchExplicitlyVisibleOnly =
12246                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12247            final boolean matchVisibleToInstantApp =
12248                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12249            final boolean componentVisible =
12250                    matchVisibleToInstantApp
12251                    && info.isVisibleToInstantApp()
12252                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12253            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12254            // throw out filters that aren't visible to ephemeral apps
12255            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12256                return null;
12257            }
12258            // throw out instant app filters if we're not explicitly requesting them
12259            if (!matchInstantApp && userState.instantApp) {
12260                return null;
12261            }
12262            // throw out instant app filters if updates are available; will trigger
12263            // instant app resolution
12264            if (userState.instantApp && ps.isUpdateAvailable()) {
12265                return null;
12266            }
12267            final ResolveInfo res = new ResolveInfo();
12268            res.activityInfo = ai;
12269            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12270                res.filter = info;
12271            }
12272            if (info != null) {
12273                res.handleAllWebDataURI = info.handleAllWebDataURI();
12274            }
12275            res.priority = info.getPriority();
12276            res.preferredOrder = activity.owner.mPreferredOrder;
12277            //System.out.println("Result: " + res.activityInfo.className +
12278            //                   " = " + res.priority);
12279            res.match = match;
12280            res.isDefault = info.hasDefault;
12281            res.labelRes = info.labelRes;
12282            res.nonLocalizedLabel = info.nonLocalizedLabel;
12283            if (userNeedsBadging(userId)) {
12284                res.noResourceId = true;
12285            } else {
12286                res.icon = info.icon;
12287            }
12288            res.iconResourceId = info.icon;
12289            res.system = res.activityInfo.applicationInfo.isSystemApp();
12290            res.isInstantAppAvailable = userState.instantApp;
12291            return res;
12292        }
12293
12294        @Override
12295        protected void sortResults(List<ResolveInfo> results) {
12296            Collections.sort(results, mResolvePrioritySorter);
12297        }
12298
12299        @Override
12300        protected void dumpFilter(PrintWriter out, String prefix,
12301                PackageParser.ActivityIntentInfo filter) {
12302            out.print(prefix); out.print(
12303                    Integer.toHexString(System.identityHashCode(filter.activity)));
12304                    out.print(' ');
12305                    filter.activity.printComponentShortName(out);
12306                    out.print(" filter ");
12307                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12308        }
12309
12310        @Override
12311        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12312            return filter.activity;
12313        }
12314
12315        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12316            PackageParser.Activity activity = (PackageParser.Activity)label;
12317            out.print(prefix); out.print(
12318                    Integer.toHexString(System.identityHashCode(activity)));
12319                    out.print(' ');
12320                    activity.printComponentShortName(out);
12321            if (count > 1) {
12322                out.print(" ("); out.print(count); out.print(" filters)");
12323            }
12324            out.println();
12325        }
12326
12327        // Keys are String (activity class name), values are Activity.
12328        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12329                = new ArrayMap<ComponentName, PackageParser.Activity>();
12330        private int mFlags;
12331    }
12332
12333    private final class ServiceIntentResolver
12334            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12335        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12336                boolean defaultOnly, int userId) {
12337            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12338            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12339        }
12340
12341        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12342                int userId) {
12343            if (!sUserManager.exists(userId)) return null;
12344            mFlags = flags;
12345            return super.queryIntent(intent, resolvedType,
12346                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12347                    userId);
12348        }
12349
12350        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12351                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12352            if (!sUserManager.exists(userId)) return null;
12353            if (packageServices == null) {
12354                return null;
12355            }
12356            mFlags = flags;
12357            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12358            final int N = packageServices.size();
12359            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12360                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12361
12362            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12363            for (int i = 0; i < N; ++i) {
12364                intentFilters = packageServices.get(i).intents;
12365                if (intentFilters != null && intentFilters.size() > 0) {
12366                    PackageParser.ServiceIntentInfo[] array =
12367                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12368                    intentFilters.toArray(array);
12369                    listCut.add(array);
12370                }
12371            }
12372            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12373        }
12374
12375        public final void addService(PackageParser.Service s) {
12376            mServices.put(s.getComponentName(), s);
12377            if (DEBUG_SHOW_INFO) {
12378                Log.v(TAG, "  "
12379                        + (s.info.nonLocalizedLabel != null
12380                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12381                Log.v(TAG, "    Class=" + s.info.name);
12382            }
12383            final int NI = s.intents.size();
12384            int j;
12385            for (j=0; j<NI; j++) {
12386                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12387                if (DEBUG_SHOW_INFO) {
12388                    Log.v(TAG, "    IntentFilter:");
12389                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12390                }
12391                if (!intent.debugCheck()) {
12392                    Log.w(TAG, "==> For Service " + s.info.name);
12393                }
12394                addFilter(intent);
12395            }
12396        }
12397
12398        public final void removeService(PackageParser.Service s) {
12399            mServices.remove(s.getComponentName());
12400            if (DEBUG_SHOW_INFO) {
12401                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12402                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12403                Log.v(TAG, "    Class=" + s.info.name);
12404            }
12405            final int NI = s.intents.size();
12406            int j;
12407            for (j=0; j<NI; j++) {
12408                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12409                if (DEBUG_SHOW_INFO) {
12410                    Log.v(TAG, "    IntentFilter:");
12411                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12412                }
12413                removeFilter(intent);
12414            }
12415        }
12416
12417        @Override
12418        protected boolean allowFilterResult(
12419                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12420            ServiceInfo filterSi = filter.service.info;
12421            for (int i=dest.size()-1; i>=0; i--) {
12422                ServiceInfo destAi = dest.get(i).serviceInfo;
12423                if (destAi.name == filterSi.name
12424                        && destAi.packageName == filterSi.packageName) {
12425                    return false;
12426                }
12427            }
12428            return true;
12429        }
12430
12431        @Override
12432        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12433            return new PackageParser.ServiceIntentInfo[size];
12434        }
12435
12436        @Override
12437        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12438            if (!sUserManager.exists(userId)) return true;
12439            PackageParser.Package p = filter.service.owner;
12440            if (p != null) {
12441                PackageSetting ps = (PackageSetting)p.mExtras;
12442                if (ps != null) {
12443                    // System apps are never considered stopped for purposes of
12444                    // filtering, because there may be no way for the user to
12445                    // actually re-launch them.
12446                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12447                            && ps.getStopped(userId);
12448                }
12449            }
12450            return false;
12451        }
12452
12453        @Override
12454        protected boolean isPackageForFilter(String packageName,
12455                PackageParser.ServiceIntentInfo info) {
12456            return packageName.equals(info.service.owner.packageName);
12457        }
12458
12459        @Override
12460        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12461                int match, int userId) {
12462            if (!sUserManager.exists(userId)) return null;
12463            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12464            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12465                return null;
12466            }
12467            final PackageParser.Service service = info.service;
12468            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12469            if (ps == null) {
12470                return null;
12471            }
12472            final PackageUserState userState = ps.readUserState(userId);
12473            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12474                    userState, userId);
12475            if (si == null) {
12476                return null;
12477            }
12478            final boolean matchVisibleToInstantApp =
12479                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12480            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12481            // throw out filters that aren't visible to ephemeral apps
12482            if (matchVisibleToInstantApp
12483                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12484                return null;
12485            }
12486            // throw out ephemeral filters if we're not explicitly requesting them
12487            if (!isInstantApp && userState.instantApp) {
12488                return null;
12489            }
12490            // throw out instant app filters if updates are available; will trigger
12491            // instant app resolution
12492            if (userState.instantApp && ps.isUpdateAvailable()) {
12493                return null;
12494            }
12495            final ResolveInfo res = new ResolveInfo();
12496            res.serviceInfo = si;
12497            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12498                res.filter = filter;
12499            }
12500            res.priority = info.getPriority();
12501            res.preferredOrder = service.owner.mPreferredOrder;
12502            res.match = match;
12503            res.isDefault = info.hasDefault;
12504            res.labelRes = info.labelRes;
12505            res.nonLocalizedLabel = info.nonLocalizedLabel;
12506            res.icon = info.icon;
12507            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12508            return res;
12509        }
12510
12511        @Override
12512        protected void sortResults(List<ResolveInfo> results) {
12513            Collections.sort(results, mResolvePrioritySorter);
12514        }
12515
12516        @Override
12517        protected void dumpFilter(PrintWriter out, String prefix,
12518                PackageParser.ServiceIntentInfo filter) {
12519            out.print(prefix); out.print(
12520                    Integer.toHexString(System.identityHashCode(filter.service)));
12521                    out.print(' ');
12522                    filter.service.printComponentShortName(out);
12523                    out.print(" filter ");
12524                    out.print(Integer.toHexString(System.identityHashCode(filter)));
12525                    if (filter.service.info.permission != null) {
12526                        out.print(" permission "); out.println(filter.service.info.permission);
12527                    } else {
12528                        out.println();
12529                    }
12530        }
12531
12532        @Override
12533        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12534            return filter.service;
12535        }
12536
12537        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12538            PackageParser.Service service = (PackageParser.Service)label;
12539            out.print(prefix); out.print(
12540                    Integer.toHexString(System.identityHashCode(service)));
12541                    out.print(' ');
12542                    service.printComponentShortName(out);
12543            if (count > 1) {
12544                out.print(" ("); out.print(count); out.print(" filters)");
12545            }
12546            out.println();
12547        }
12548
12549//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12550//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12551//            final List<ResolveInfo> retList = Lists.newArrayList();
12552//            while (i.hasNext()) {
12553//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12554//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12555//                    retList.add(resolveInfo);
12556//                }
12557//            }
12558//            return retList;
12559//        }
12560
12561        // Keys are String (activity class name), values are Activity.
12562        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12563                = new ArrayMap<ComponentName, PackageParser.Service>();
12564        private int mFlags;
12565    }
12566
12567    private final class ProviderIntentResolver
12568            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12569        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12570                boolean defaultOnly, int userId) {
12571            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12572            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12573        }
12574
12575        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12576                int userId) {
12577            if (!sUserManager.exists(userId))
12578                return null;
12579            mFlags = flags;
12580            return super.queryIntent(intent, resolvedType,
12581                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12582                    userId);
12583        }
12584
12585        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12586                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12587            if (!sUserManager.exists(userId))
12588                return null;
12589            if (packageProviders == null) {
12590                return null;
12591            }
12592            mFlags = flags;
12593            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12594            final int N = packageProviders.size();
12595            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12596                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12597
12598            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12599            for (int i = 0; i < N; ++i) {
12600                intentFilters = packageProviders.get(i).intents;
12601                if (intentFilters != null && intentFilters.size() > 0) {
12602                    PackageParser.ProviderIntentInfo[] array =
12603                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12604                    intentFilters.toArray(array);
12605                    listCut.add(array);
12606                }
12607            }
12608            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12609        }
12610
12611        public final void addProvider(PackageParser.Provider p) {
12612            if (mProviders.containsKey(p.getComponentName())) {
12613                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12614                return;
12615            }
12616
12617            mProviders.put(p.getComponentName(), p);
12618            if (DEBUG_SHOW_INFO) {
12619                Log.v(TAG, "  "
12620                        + (p.info.nonLocalizedLabel != null
12621                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12622                Log.v(TAG, "    Class=" + p.info.name);
12623            }
12624            final int NI = p.intents.size();
12625            int j;
12626            for (j = 0; j < NI; j++) {
12627                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12628                if (DEBUG_SHOW_INFO) {
12629                    Log.v(TAG, "    IntentFilter:");
12630                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12631                }
12632                if (!intent.debugCheck()) {
12633                    Log.w(TAG, "==> For Provider " + p.info.name);
12634                }
12635                addFilter(intent);
12636            }
12637        }
12638
12639        public final void removeProvider(PackageParser.Provider p) {
12640            mProviders.remove(p.getComponentName());
12641            if (DEBUG_SHOW_INFO) {
12642                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12643                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12644                Log.v(TAG, "    Class=" + p.info.name);
12645            }
12646            final int NI = p.intents.size();
12647            int j;
12648            for (j = 0; j < NI; j++) {
12649                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12650                if (DEBUG_SHOW_INFO) {
12651                    Log.v(TAG, "    IntentFilter:");
12652                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12653                }
12654                removeFilter(intent);
12655            }
12656        }
12657
12658        @Override
12659        protected boolean allowFilterResult(
12660                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12661            ProviderInfo filterPi = filter.provider.info;
12662            for (int i = dest.size() - 1; i >= 0; i--) {
12663                ProviderInfo destPi = dest.get(i).providerInfo;
12664                if (destPi.name == filterPi.name
12665                        && destPi.packageName == filterPi.packageName) {
12666                    return false;
12667                }
12668            }
12669            return true;
12670        }
12671
12672        @Override
12673        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12674            return new PackageParser.ProviderIntentInfo[size];
12675        }
12676
12677        @Override
12678        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12679            if (!sUserManager.exists(userId))
12680                return true;
12681            PackageParser.Package p = filter.provider.owner;
12682            if (p != null) {
12683                PackageSetting ps = (PackageSetting) p.mExtras;
12684                if (ps != null) {
12685                    // System apps are never considered stopped for purposes of
12686                    // filtering, because there may be no way for the user to
12687                    // actually re-launch them.
12688                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12689                            && ps.getStopped(userId);
12690                }
12691            }
12692            return false;
12693        }
12694
12695        @Override
12696        protected boolean isPackageForFilter(String packageName,
12697                PackageParser.ProviderIntentInfo info) {
12698            return packageName.equals(info.provider.owner.packageName);
12699        }
12700
12701        @Override
12702        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12703                int match, int userId) {
12704            if (!sUserManager.exists(userId))
12705                return null;
12706            final PackageParser.ProviderIntentInfo info = filter;
12707            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12708                return null;
12709            }
12710            final PackageParser.Provider provider = info.provider;
12711            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12712            if (ps == null) {
12713                return null;
12714            }
12715            final PackageUserState userState = ps.readUserState(userId);
12716            final boolean matchVisibleToInstantApp =
12717                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12718            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12719            // throw out filters that aren't visible to instant applications
12720            if (matchVisibleToInstantApp
12721                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12722                return null;
12723            }
12724            // throw out instant application filters if we're not explicitly requesting them
12725            if (!isInstantApp && userState.instantApp) {
12726                return null;
12727            }
12728            // throw out instant application filters if updates are available; will trigger
12729            // instant application resolution
12730            if (userState.instantApp && ps.isUpdateAvailable()) {
12731                return null;
12732            }
12733            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12734                    userState, userId);
12735            if (pi == null) {
12736                return null;
12737            }
12738            final ResolveInfo res = new ResolveInfo();
12739            res.providerInfo = pi;
12740            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12741                res.filter = filter;
12742            }
12743            res.priority = info.getPriority();
12744            res.preferredOrder = provider.owner.mPreferredOrder;
12745            res.match = match;
12746            res.isDefault = info.hasDefault;
12747            res.labelRes = info.labelRes;
12748            res.nonLocalizedLabel = info.nonLocalizedLabel;
12749            res.icon = info.icon;
12750            res.system = res.providerInfo.applicationInfo.isSystemApp();
12751            return res;
12752        }
12753
12754        @Override
12755        protected void sortResults(List<ResolveInfo> results) {
12756            Collections.sort(results, mResolvePrioritySorter);
12757        }
12758
12759        @Override
12760        protected void dumpFilter(PrintWriter out, String prefix,
12761                PackageParser.ProviderIntentInfo filter) {
12762            out.print(prefix);
12763            out.print(
12764                    Integer.toHexString(System.identityHashCode(filter.provider)));
12765            out.print(' ');
12766            filter.provider.printComponentShortName(out);
12767            out.print(" filter ");
12768            out.println(Integer.toHexString(System.identityHashCode(filter)));
12769        }
12770
12771        @Override
12772        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12773            return filter.provider;
12774        }
12775
12776        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12777            PackageParser.Provider provider = (PackageParser.Provider)label;
12778            out.print(prefix); out.print(
12779                    Integer.toHexString(System.identityHashCode(provider)));
12780                    out.print(' ');
12781                    provider.printComponentShortName(out);
12782            if (count > 1) {
12783                out.print(" ("); out.print(count); out.print(" filters)");
12784            }
12785            out.println();
12786        }
12787
12788        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12789                = new ArrayMap<ComponentName, PackageParser.Provider>();
12790        private int mFlags;
12791    }
12792
12793    static final class EphemeralIntentResolver
12794            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12795        /**
12796         * The result that has the highest defined order. Ordering applies on a
12797         * per-package basis. Mapping is from package name to Pair of order and
12798         * EphemeralResolveInfo.
12799         * <p>
12800         * NOTE: This is implemented as a field variable for convenience and efficiency.
12801         * By having a field variable, we're able to track filter ordering as soon as
12802         * a non-zero order is defined. Otherwise, multiple loops across the result set
12803         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12804         * this needs to be contained entirely within {@link #filterResults}.
12805         */
12806        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12807
12808        @Override
12809        protected AuxiliaryResolveInfo[] newArray(int size) {
12810            return new AuxiliaryResolveInfo[size];
12811        }
12812
12813        @Override
12814        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12815            return true;
12816        }
12817
12818        @Override
12819        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12820                int userId) {
12821            if (!sUserManager.exists(userId)) {
12822                return null;
12823            }
12824            final String packageName = responseObj.resolveInfo.getPackageName();
12825            final Integer order = responseObj.getOrder();
12826            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12827                    mOrderResult.get(packageName);
12828            // ordering is enabled and this item's order isn't high enough
12829            if (lastOrderResult != null && lastOrderResult.first >= order) {
12830                return null;
12831            }
12832            final InstantAppResolveInfo res = responseObj.resolveInfo;
12833            if (order > 0) {
12834                // non-zero order, enable ordering
12835                mOrderResult.put(packageName, new Pair<>(order, res));
12836            }
12837            return responseObj;
12838        }
12839
12840        @Override
12841        protected void filterResults(List<AuxiliaryResolveInfo> results) {
12842            // only do work if ordering is enabled [most of the time it won't be]
12843            if (mOrderResult.size() == 0) {
12844                return;
12845            }
12846            int resultSize = results.size();
12847            for (int i = 0; i < resultSize; i++) {
12848                final InstantAppResolveInfo info = results.get(i).resolveInfo;
12849                final String packageName = info.getPackageName();
12850                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
12851                if (savedInfo == null) {
12852                    // package doesn't having ordering
12853                    continue;
12854                }
12855                if (savedInfo.second == info) {
12856                    // circled back to the highest ordered item; remove from order list
12857                    mOrderResult.remove(packageName);
12858                    if (mOrderResult.size() == 0) {
12859                        // no more ordered items
12860                        break;
12861                    }
12862                    continue;
12863                }
12864                // item has a worse order, remove it from the result list
12865                results.remove(i);
12866                resultSize--;
12867                i--;
12868            }
12869        }
12870    }
12871
12872    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
12873            new Comparator<ResolveInfo>() {
12874        public int compare(ResolveInfo r1, ResolveInfo r2) {
12875            int v1 = r1.priority;
12876            int v2 = r2.priority;
12877            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
12878            if (v1 != v2) {
12879                return (v1 > v2) ? -1 : 1;
12880            }
12881            v1 = r1.preferredOrder;
12882            v2 = r2.preferredOrder;
12883            if (v1 != v2) {
12884                return (v1 > v2) ? -1 : 1;
12885            }
12886            if (r1.isDefault != r2.isDefault) {
12887                return r1.isDefault ? -1 : 1;
12888            }
12889            v1 = r1.match;
12890            v2 = r2.match;
12891            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
12892            if (v1 != v2) {
12893                return (v1 > v2) ? -1 : 1;
12894            }
12895            if (r1.system != r2.system) {
12896                return r1.system ? -1 : 1;
12897            }
12898            if (r1.activityInfo != null) {
12899                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
12900            }
12901            if (r1.serviceInfo != null) {
12902                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
12903            }
12904            if (r1.providerInfo != null) {
12905                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
12906            }
12907            return 0;
12908        }
12909    };
12910
12911    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
12912            new Comparator<ProviderInfo>() {
12913        public int compare(ProviderInfo p1, ProviderInfo p2) {
12914            final int v1 = p1.initOrder;
12915            final int v2 = p2.initOrder;
12916            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12917        }
12918    };
12919
12920    @Override
12921    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12922            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12923            final int[] userIds, int[] instantUserIds) {
12924        mHandler.post(new Runnable() {
12925            @Override
12926            public void run() {
12927                try {
12928                    final IActivityManager am = ActivityManager.getService();
12929                    if (am == null) return;
12930                    final int[] resolvedUserIds;
12931                    if (userIds == null) {
12932                        resolvedUserIds = am.getRunningUserIds();
12933                    } else {
12934                        resolvedUserIds = userIds;
12935                    }
12936                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12937                            resolvedUserIds, false);
12938                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
12939                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
12940                                instantUserIds, true);
12941                    }
12942                } catch (RemoteException ex) {
12943                }
12944            }
12945        });
12946    }
12947
12948    @Override
12949    public void notifyPackageAdded(String packageName) {
12950        final PackageListObserver[] observers;
12951        synchronized (mPackages) {
12952            if (mPackageListObservers.size() == 0) {
12953                return;
12954            }
12955            observers = (PackageListObserver[]) mPackageListObservers.toArray();
12956        }
12957        for (int i = observers.length - 1; i >= 0; --i) {
12958            observers[i].onPackageAdded(packageName);
12959        }
12960    }
12961
12962    @Override
12963    public void notifyPackageRemoved(String packageName) {
12964        final PackageListObserver[] observers;
12965        synchronized (mPackages) {
12966            if (mPackageListObservers.size() == 0) {
12967                return;
12968            }
12969            observers = (PackageListObserver[]) mPackageListObservers.toArray();
12970        }
12971        for (int i = observers.length - 1; i >= 0; --i) {
12972            observers[i].onPackageRemoved(packageName);
12973        }
12974    }
12975
12976    /**
12977     * Sends a broadcast for the given action.
12978     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
12979     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
12980     * the system and applications allowed to see instant applications to receive package
12981     * lifecycle events for instant applications.
12982     */
12983    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
12984            int flags, String targetPkg, IIntentReceiver finishedReceiver,
12985            int[] userIds, boolean isInstantApp)
12986                    throws RemoteException {
12987        for (int id : userIds) {
12988            final Intent intent = new Intent(action,
12989                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12990            final String[] requiredPermissions =
12991                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
12992            if (extras != null) {
12993                intent.putExtras(extras);
12994            }
12995            if (targetPkg != null) {
12996                intent.setPackage(targetPkg);
12997            }
12998            // Modify the UID when posting to other users
12999            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13000            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13001                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13002                intent.putExtra(Intent.EXTRA_UID, uid);
13003            }
13004            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13005            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13006            if (DEBUG_BROADCASTS) {
13007                RuntimeException here = new RuntimeException("here");
13008                here.fillInStackTrace();
13009                Slog.d(TAG, "Sending to user " + id + ": "
13010                        + intent.toShortString(false, true, false, false)
13011                        + " " + intent.getExtras(), here);
13012            }
13013            am.broadcastIntent(null, intent, null, finishedReceiver,
13014                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13015                    null, finishedReceiver != null, false, id);
13016        }
13017    }
13018
13019    /**
13020     * Check if the external storage media is available. This is true if there
13021     * is a mounted external storage medium or if the external storage is
13022     * emulated.
13023     */
13024    private boolean isExternalMediaAvailable() {
13025        return mMediaMounted || Environment.isExternalStorageEmulated();
13026    }
13027
13028    @Override
13029    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13030        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13031            return null;
13032        }
13033        if (!isExternalMediaAvailable()) {
13034                // If the external storage is no longer mounted at this point,
13035                // the caller may not have been able to delete all of this
13036                // packages files and can not delete any more.  Bail.
13037            return null;
13038        }
13039        synchronized (mPackages) {
13040            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13041            if (lastPackage != null) {
13042                pkgs.remove(lastPackage);
13043            }
13044            if (pkgs.size() > 0) {
13045                return pkgs.get(0);
13046            }
13047        }
13048        return null;
13049    }
13050
13051    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13052        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13053                userId, andCode ? 1 : 0, packageName);
13054        if (mSystemReady) {
13055            msg.sendToTarget();
13056        } else {
13057            if (mPostSystemReadyMessages == null) {
13058                mPostSystemReadyMessages = new ArrayList<>();
13059            }
13060            mPostSystemReadyMessages.add(msg);
13061        }
13062    }
13063
13064    void startCleaningPackages() {
13065        // reader
13066        if (!isExternalMediaAvailable()) {
13067            return;
13068        }
13069        synchronized (mPackages) {
13070            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13071                return;
13072            }
13073        }
13074        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13075        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13076        IActivityManager am = ActivityManager.getService();
13077        if (am != null) {
13078            int dcsUid = -1;
13079            synchronized (mPackages) {
13080                if (!mDefaultContainerWhitelisted) {
13081                    mDefaultContainerWhitelisted = true;
13082                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13083                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13084                }
13085            }
13086            try {
13087                if (dcsUid > 0) {
13088                    am.backgroundWhitelistUid(dcsUid);
13089                }
13090                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13091                        UserHandle.USER_SYSTEM);
13092            } catch (RemoteException e) {
13093            }
13094        }
13095    }
13096
13097    /**
13098     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13099     * it is acting on behalf on an enterprise or the user).
13100     *
13101     * Note that the ordering of the conditionals in this method is important. The checks we perform
13102     * are as follows, in this order:
13103     *
13104     * 1) If the install is being performed by a system app, we can trust the app to have set the
13105     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13106     *    what it is.
13107     * 2) If the install is being performed by a device or profile owner app, the install reason
13108     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13109     *    set the install reason correctly. If the app targets an older SDK version where install
13110     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13111     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13112     * 3) In all other cases, the install is being performed by a regular app that is neither part
13113     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13114     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13115     *    set to enterprise policy and if so, change it to unknown instead.
13116     */
13117    private int fixUpInstallReason(String installerPackageName, int installerUid,
13118            int installReason) {
13119        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13120                == PERMISSION_GRANTED) {
13121            // If the install is being performed by a system app, we trust that app to have set the
13122            // install reason correctly.
13123            return installReason;
13124        }
13125
13126        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13127            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13128        if (dpm != null) {
13129            ComponentName owner = null;
13130            try {
13131                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13132                if (owner == null) {
13133                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13134                }
13135            } catch (RemoteException e) {
13136            }
13137            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13138                // If the install is being performed by a device or profile owner, the install
13139                // reason should be enterprise policy.
13140                return PackageManager.INSTALL_REASON_POLICY;
13141            }
13142        }
13143
13144        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13145            // If the install is being performed by a regular app (i.e. neither system app nor
13146            // device or profile owner), we have no reason to believe that the app is acting on
13147            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13148            // change it to unknown instead.
13149            return PackageManager.INSTALL_REASON_UNKNOWN;
13150        }
13151
13152        // If the install is being performed by a regular app and the install reason was set to any
13153        // value but enterprise policy, leave the install reason unchanged.
13154        return installReason;
13155    }
13156
13157    void installStage(String packageName, File stagedDir,
13158            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13159            String installerPackageName, int installerUid, UserHandle user,
13160            PackageParser.SigningDetails signingDetails) {
13161        if (DEBUG_EPHEMERAL) {
13162            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13163                Slog.d(TAG, "Ephemeral install of " + packageName);
13164            }
13165        }
13166        final VerificationInfo verificationInfo = new VerificationInfo(
13167                sessionParams.originatingUri, sessionParams.referrerUri,
13168                sessionParams.originatingUid, installerUid);
13169
13170        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13171
13172        final Message msg = mHandler.obtainMessage(INIT_COPY);
13173        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13174                sessionParams.installReason);
13175        final InstallParams params = new InstallParams(origin, null, observer,
13176                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13177                verificationInfo, user, sessionParams.abiOverride,
13178                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13179        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13180        msg.obj = params;
13181
13182        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13183                System.identityHashCode(msg.obj));
13184        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13185                System.identityHashCode(msg.obj));
13186
13187        mHandler.sendMessage(msg);
13188    }
13189
13190    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13191            int userId) {
13192        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13193        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13194        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13195        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13196        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13197                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13198
13199        // Send a session commit broadcast
13200        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13201        info.installReason = pkgSetting.getInstallReason(userId);
13202        info.appPackageName = packageName;
13203        sendSessionCommitBroadcast(info, userId);
13204    }
13205
13206    @Override
13207    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13208            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13209        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13210            return;
13211        }
13212        Bundle extras = new Bundle(1);
13213        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13214        final int uid = UserHandle.getUid(
13215                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13216        extras.putInt(Intent.EXTRA_UID, uid);
13217
13218        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13219                packageName, extras, 0, null, null, userIds, instantUserIds);
13220        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13221            mHandler.post(() -> {
13222                        for (int userId : userIds) {
13223                            sendBootCompletedBroadcastToSystemApp(
13224                                    packageName, includeStopped, userId);
13225                        }
13226                    }
13227            );
13228        }
13229    }
13230
13231    /**
13232     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13233     * automatically without needing an explicit launch.
13234     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13235     */
13236    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13237            int userId) {
13238        // If user is not running, the app didn't miss any broadcast
13239        if (!mUserManagerInternal.isUserRunning(userId)) {
13240            return;
13241        }
13242        final IActivityManager am = ActivityManager.getService();
13243        try {
13244            // Deliver LOCKED_BOOT_COMPLETED first
13245            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13246                    .setPackage(packageName);
13247            if (includeStopped) {
13248                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13249            }
13250            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13251            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13252                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13253
13254            // Deliver BOOT_COMPLETED only if user is unlocked
13255            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13256                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13257                if (includeStopped) {
13258                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13259                }
13260                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13261                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13262            }
13263        } catch (RemoteException e) {
13264            throw e.rethrowFromSystemServer();
13265        }
13266    }
13267
13268    @Override
13269    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13270            int userId) {
13271        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13272        PackageSetting pkgSetting;
13273        final int callingUid = Binder.getCallingUid();
13274        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13275                true /* requireFullPermission */, true /* checkShell */,
13276                "setApplicationHiddenSetting for user " + userId);
13277
13278        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13279            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13280            return false;
13281        }
13282
13283        long callingId = Binder.clearCallingIdentity();
13284        try {
13285            boolean sendAdded = false;
13286            boolean sendRemoved = false;
13287            // writer
13288            synchronized (mPackages) {
13289                pkgSetting = mSettings.mPackages.get(packageName);
13290                if (pkgSetting == null) {
13291                    return false;
13292                }
13293                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13294                    return false;
13295                }
13296                // Do not allow "android" is being disabled
13297                if ("android".equals(packageName)) {
13298                    Slog.w(TAG, "Cannot hide package: android");
13299                    return false;
13300                }
13301                // Cannot hide static shared libs as they are considered
13302                // a part of the using app (emulating static linking). Also
13303                // static libs are installed always on internal storage.
13304                PackageParser.Package pkg = mPackages.get(packageName);
13305                if (pkg != null && pkg.staticSharedLibName != null) {
13306                    Slog.w(TAG, "Cannot hide package: " + packageName
13307                            + " providing static shared library: "
13308                            + pkg.staticSharedLibName);
13309                    return false;
13310                }
13311                // Only allow protected packages to hide themselves.
13312                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13313                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13314                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13315                    return false;
13316                }
13317
13318                if (pkgSetting.getHidden(userId) != hidden) {
13319                    pkgSetting.setHidden(hidden, userId);
13320                    mSettings.writePackageRestrictionsLPr(userId);
13321                    if (hidden) {
13322                        sendRemoved = true;
13323                    } else {
13324                        sendAdded = true;
13325                    }
13326                }
13327            }
13328            if (sendAdded) {
13329                sendPackageAddedForUser(packageName, pkgSetting, userId);
13330                return true;
13331            }
13332            if (sendRemoved) {
13333                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13334                        "hiding pkg");
13335                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13336                return true;
13337            }
13338        } finally {
13339            Binder.restoreCallingIdentity(callingId);
13340        }
13341        return false;
13342    }
13343
13344    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13345            int userId) {
13346        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13347        info.removedPackage = packageName;
13348        info.installerPackageName = pkgSetting.installerPackageName;
13349        info.removedUsers = new int[] {userId};
13350        info.broadcastUsers = new int[] {userId};
13351        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13352        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13353    }
13354
13355    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13356        if (pkgList.length > 0) {
13357            Bundle extras = new Bundle(1);
13358            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13359
13360            sendPackageBroadcast(
13361                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13362                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13363                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13364                    new int[] {userId}, null);
13365        }
13366    }
13367
13368    /**
13369     * Returns true if application is not found or there was an error. Otherwise it returns
13370     * the hidden state of the package for the given user.
13371     */
13372    @Override
13373    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13374        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13375        final int callingUid = Binder.getCallingUid();
13376        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13377                true /* requireFullPermission */, false /* checkShell */,
13378                "getApplicationHidden for user " + userId);
13379        PackageSetting ps;
13380        long callingId = Binder.clearCallingIdentity();
13381        try {
13382            // writer
13383            synchronized (mPackages) {
13384                ps = mSettings.mPackages.get(packageName);
13385                if (ps == null) {
13386                    return true;
13387                }
13388                if (filterAppAccessLPr(ps, callingUid, userId)) {
13389                    return true;
13390                }
13391                return ps.getHidden(userId);
13392            }
13393        } finally {
13394            Binder.restoreCallingIdentity(callingId);
13395        }
13396    }
13397
13398    /**
13399     * @hide
13400     */
13401    @Override
13402    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13403            int installReason) {
13404        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13405                null);
13406        PackageSetting pkgSetting;
13407        final int callingUid = Binder.getCallingUid();
13408        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13409                true /* requireFullPermission */, true /* checkShell */,
13410                "installExistingPackage for user " + userId);
13411        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13412            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13413        }
13414
13415        long callingId = Binder.clearCallingIdentity();
13416        try {
13417            boolean installed = false;
13418            final boolean instantApp =
13419                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13420            final boolean fullApp =
13421                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13422
13423            // writer
13424            synchronized (mPackages) {
13425                pkgSetting = mSettings.mPackages.get(packageName);
13426                if (pkgSetting == null) {
13427                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13428                }
13429                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13430                    // only allow the existing package to be used if it's installed as a full
13431                    // application for at least one user
13432                    boolean installAllowed = false;
13433                    for (int checkUserId : sUserManager.getUserIds()) {
13434                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13435                        if (installAllowed) {
13436                            break;
13437                        }
13438                    }
13439                    if (!installAllowed) {
13440                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13441                    }
13442                }
13443                if (!pkgSetting.getInstalled(userId)) {
13444                    pkgSetting.setInstalled(true, userId);
13445                    pkgSetting.setHidden(false, userId);
13446                    pkgSetting.setInstallReason(installReason, userId);
13447                    mSettings.writePackageRestrictionsLPr(userId);
13448                    mSettings.writeKernelMappingLPr(pkgSetting);
13449                    installed = true;
13450                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13451                    // upgrade app from instant to full; we don't allow app downgrade
13452                    installed = true;
13453                }
13454                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13455            }
13456
13457            if (installed) {
13458                if (pkgSetting.pkg != null) {
13459                    synchronized (mInstallLock) {
13460                        // We don't need to freeze for a brand new install
13461                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13462                    }
13463                }
13464                sendPackageAddedForUser(packageName, pkgSetting, userId);
13465                synchronized (mPackages) {
13466                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13467                }
13468            }
13469        } finally {
13470            Binder.restoreCallingIdentity(callingId);
13471        }
13472
13473        return PackageManager.INSTALL_SUCCEEDED;
13474    }
13475
13476    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13477            boolean instantApp, boolean fullApp) {
13478        // no state specified; do nothing
13479        if (!instantApp && !fullApp) {
13480            return;
13481        }
13482        if (userId != UserHandle.USER_ALL) {
13483            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13484                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13485            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13486                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13487            }
13488        } else {
13489            for (int currentUserId : sUserManager.getUserIds()) {
13490                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13491                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13492                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13493                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13494                }
13495            }
13496        }
13497    }
13498
13499    boolean isUserRestricted(int userId, String restrictionKey) {
13500        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13501        if (restrictions.getBoolean(restrictionKey, false)) {
13502            Log.w(TAG, "User is restricted: " + restrictionKey);
13503            return true;
13504        }
13505        return false;
13506    }
13507
13508    @Override
13509    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13510            int userId) {
13511        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13512        final int callingUid = Binder.getCallingUid();
13513        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13514                true /* requireFullPermission */, true /* checkShell */,
13515                "setPackagesSuspended for user " + userId);
13516
13517        if (ArrayUtils.isEmpty(packageNames)) {
13518            return packageNames;
13519        }
13520
13521        // List of package names for whom the suspended state has changed.
13522        List<String> changedPackages = new ArrayList<>(packageNames.length);
13523        // List of package names for whom the suspended state is not set as requested in this
13524        // method.
13525        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13526        long callingId = Binder.clearCallingIdentity();
13527        try {
13528            for (int i = 0; i < packageNames.length; i++) {
13529                String packageName = packageNames[i];
13530                boolean changed = false;
13531                final int appId;
13532                synchronized (mPackages) {
13533                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13534                    if (pkgSetting == null
13535                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13536                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13537                                + "\". Skipping suspending/un-suspending.");
13538                        unactionedPackages.add(packageName);
13539                        continue;
13540                    }
13541                    appId = pkgSetting.appId;
13542                    if (pkgSetting.getSuspended(userId) != suspended) {
13543                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13544                            unactionedPackages.add(packageName);
13545                            continue;
13546                        }
13547                        pkgSetting.setSuspended(suspended, userId);
13548                        mSettings.writePackageRestrictionsLPr(userId);
13549                        changed = true;
13550                        changedPackages.add(packageName);
13551                    }
13552                }
13553
13554                if (changed && suspended) {
13555                    killApplication(packageName, UserHandle.getUid(userId, appId),
13556                            "suspending package");
13557                }
13558            }
13559        } finally {
13560            Binder.restoreCallingIdentity(callingId);
13561        }
13562
13563        if (!changedPackages.isEmpty()) {
13564            sendPackagesSuspendedForUser(changedPackages.toArray(
13565                    new String[changedPackages.size()]), userId, suspended);
13566        }
13567
13568        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13569    }
13570
13571    @Override
13572    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13573        final int callingUid = Binder.getCallingUid();
13574        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13575                true /* requireFullPermission */, false /* checkShell */,
13576                "isPackageSuspendedForUser for user " + userId);
13577        synchronized (mPackages) {
13578            final PackageSetting ps = mSettings.mPackages.get(packageName);
13579            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13580                throw new IllegalArgumentException("Unknown target package: " + packageName);
13581            }
13582            return ps.getSuspended(userId);
13583        }
13584    }
13585
13586    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13587        if (isPackageDeviceAdmin(packageName, userId)) {
13588            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13589                    + "\": has an active device admin");
13590            return false;
13591        }
13592
13593        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13594        if (packageName.equals(activeLauncherPackageName)) {
13595            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13596                    + "\": contains the active launcher");
13597            return false;
13598        }
13599
13600        if (packageName.equals(mRequiredInstallerPackage)) {
13601            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13602                    + "\": required for package installation");
13603            return false;
13604        }
13605
13606        if (packageName.equals(mRequiredUninstallerPackage)) {
13607            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13608                    + "\": required for package uninstallation");
13609            return false;
13610        }
13611
13612        if (packageName.equals(mRequiredVerifierPackage)) {
13613            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13614                    + "\": required for package verification");
13615            return false;
13616        }
13617
13618        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13619            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13620                    + "\": is the default dialer");
13621            return false;
13622        }
13623
13624        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13625            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13626                    + "\": protected package");
13627            return false;
13628        }
13629
13630        // Cannot suspend static shared libs as they are considered
13631        // a part of the using app (emulating static linking). Also
13632        // static libs are installed always on internal storage.
13633        PackageParser.Package pkg = mPackages.get(packageName);
13634        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13635            Slog.w(TAG, "Cannot suspend package: " + packageName
13636                    + " providing static shared library: "
13637                    + pkg.staticSharedLibName);
13638            return false;
13639        }
13640
13641        return true;
13642    }
13643
13644    private String getActiveLauncherPackageName(int userId) {
13645        Intent intent = new Intent(Intent.ACTION_MAIN);
13646        intent.addCategory(Intent.CATEGORY_HOME);
13647        ResolveInfo resolveInfo = resolveIntent(
13648                intent,
13649                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13650                PackageManager.MATCH_DEFAULT_ONLY,
13651                userId);
13652
13653        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13654    }
13655
13656    private String getDefaultDialerPackageName(int userId) {
13657        synchronized (mPackages) {
13658            return mSettings.getDefaultDialerPackageNameLPw(userId);
13659        }
13660    }
13661
13662    @Override
13663    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13664        mContext.enforceCallingOrSelfPermission(
13665                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13666                "Only package verification agents can verify applications");
13667
13668        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13669        final PackageVerificationResponse response = new PackageVerificationResponse(
13670                verificationCode, Binder.getCallingUid());
13671        msg.arg1 = id;
13672        msg.obj = response;
13673        mHandler.sendMessage(msg);
13674    }
13675
13676    @Override
13677    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13678            long millisecondsToDelay) {
13679        mContext.enforceCallingOrSelfPermission(
13680                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13681                "Only package verification agents can extend verification timeouts");
13682
13683        final PackageVerificationState state = mPendingVerification.get(id);
13684        final PackageVerificationResponse response = new PackageVerificationResponse(
13685                verificationCodeAtTimeout, Binder.getCallingUid());
13686
13687        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13688            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13689        }
13690        if (millisecondsToDelay < 0) {
13691            millisecondsToDelay = 0;
13692        }
13693        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13694                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13695            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13696        }
13697
13698        if ((state != null) && !state.timeoutExtended()) {
13699            state.extendTimeout();
13700
13701            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13702            msg.arg1 = id;
13703            msg.obj = response;
13704            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13705        }
13706    }
13707
13708    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13709            int verificationCode, UserHandle user) {
13710        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13711        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13712        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13713        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13714        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13715
13716        mContext.sendBroadcastAsUser(intent, user,
13717                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13718    }
13719
13720    private ComponentName matchComponentForVerifier(String packageName,
13721            List<ResolveInfo> receivers) {
13722        ActivityInfo targetReceiver = null;
13723
13724        final int NR = receivers.size();
13725        for (int i = 0; i < NR; i++) {
13726            final ResolveInfo info = receivers.get(i);
13727            if (info.activityInfo == null) {
13728                continue;
13729            }
13730
13731            if (packageName.equals(info.activityInfo.packageName)) {
13732                targetReceiver = info.activityInfo;
13733                break;
13734            }
13735        }
13736
13737        if (targetReceiver == null) {
13738            return null;
13739        }
13740
13741        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13742    }
13743
13744    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13745            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13746        if (pkgInfo.verifiers.length == 0) {
13747            return null;
13748        }
13749
13750        final int N = pkgInfo.verifiers.length;
13751        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13752        for (int i = 0; i < N; i++) {
13753            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13754
13755            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13756                    receivers);
13757            if (comp == null) {
13758                continue;
13759            }
13760
13761            final int verifierUid = getUidForVerifier(verifierInfo);
13762            if (verifierUid == -1) {
13763                continue;
13764            }
13765
13766            if (DEBUG_VERIFY) {
13767                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13768                        + " with the correct signature");
13769            }
13770            sufficientVerifiers.add(comp);
13771            verificationState.addSufficientVerifier(verifierUid);
13772        }
13773
13774        return sufficientVerifiers;
13775    }
13776
13777    private int getUidForVerifier(VerifierInfo verifierInfo) {
13778        synchronized (mPackages) {
13779            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13780            if (pkg == null) {
13781                return -1;
13782            } else if (pkg.mSigningDetails.signatures.length != 1) {
13783                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13784                        + " has more than one signature; ignoring");
13785                return -1;
13786            }
13787
13788            /*
13789             * If the public key of the package's signature does not match
13790             * our expected public key, then this is a different package and
13791             * we should skip.
13792             */
13793
13794            final byte[] expectedPublicKey;
13795            try {
13796                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
13797                final PublicKey publicKey = verifierSig.getPublicKey();
13798                expectedPublicKey = publicKey.getEncoded();
13799            } catch (CertificateException e) {
13800                return -1;
13801            }
13802
13803            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13804
13805            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13806                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13807                        + " does not have the expected public key; ignoring");
13808                return -1;
13809            }
13810
13811            return pkg.applicationInfo.uid;
13812        }
13813    }
13814
13815    @Override
13816    public void finishPackageInstall(int token, boolean didLaunch) {
13817        enforceSystemOrRoot("Only the system is allowed to finish installs");
13818
13819        if (DEBUG_INSTALL) {
13820            Slog.v(TAG, "BM finishing package install for " + token);
13821        }
13822        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13823
13824        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13825        mHandler.sendMessage(msg);
13826    }
13827
13828    /**
13829     * Get the verification agent timeout.  Used for both the APK verifier and the
13830     * intent filter verifier.
13831     *
13832     * @return verification timeout in milliseconds
13833     */
13834    private long getVerificationTimeout() {
13835        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13836                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13837                DEFAULT_VERIFICATION_TIMEOUT);
13838    }
13839
13840    /**
13841     * Get the default verification agent response code.
13842     *
13843     * @return default verification response code
13844     */
13845    private int getDefaultVerificationResponse(UserHandle user) {
13846        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13847            return PackageManager.VERIFICATION_REJECT;
13848        }
13849        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13850                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13851                DEFAULT_VERIFICATION_RESPONSE);
13852    }
13853
13854    /**
13855     * Check whether or not package verification has been enabled.
13856     *
13857     * @return true if verification should be performed
13858     */
13859    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
13860        if (!DEFAULT_VERIFY_ENABLE) {
13861            return false;
13862        }
13863
13864        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
13865
13866        // Check if installing from ADB
13867        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13868            // Do not run verification in a test harness environment
13869            if (ActivityManager.isRunningInTestHarness()) {
13870                return false;
13871            }
13872            if (ensureVerifyAppsEnabled) {
13873                return true;
13874            }
13875            // Check if the developer does not want package verification for ADB installs
13876            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13877                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
13878                return false;
13879            }
13880        } else {
13881            // only when not installed from ADB, skip verification for instant apps when
13882            // the installer and verifier are the same.
13883            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13884                if (mInstantAppInstallerActivity != null
13885                        && mInstantAppInstallerActivity.packageName.equals(
13886                                mRequiredVerifierPackage)) {
13887                    try {
13888                        mContext.getSystemService(AppOpsManager.class)
13889                                .checkPackage(installerUid, mRequiredVerifierPackage);
13890                        if (DEBUG_VERIFY) {
13891                            Slog.i(TAG, "disable verification for instant app");
13892                        }
13893                        return false;
13894                    } catch (SecurityException ignore) { }
13895                }
13896            }
13897        }
13898
13899        if (ensureVerifyAppsEnabled) {
13900            return true;
13901        }
13902
13903        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13904                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
13905    }
13906
13907    @Override
13908    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13909            throws RemoteException {
13910        mContext.enforceCallingOrSelfPermission(
13911                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13912                "Only intentfilter verification agents can verify applications");
13913
13914        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13915        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13916                Binder.getCallingUid(), verificationCode, failedDomains);
13917        msg.arg1 = id;
13918        msg.obj = response;
13919        mHandler.sendMessage(msg);
13920    }
13921
13922    @Override
13923    public int getIntentVerificationStatus(String packageName, int userId) {
13924        final int callingUid = Binder.getCallingUid();
13925        if (UserHandle.getUserId(callingUid) != userId) {
13926            mContext.enforceCallingOrSelfPermission(
13927                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13928                    "getIntentVerificationStatus" + userId);
13929        }
13930        if (getInstantAppPackageName(callingUid) != null) {
13931            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13932        }
13933        synchronized (mPackages) {
13934            final PackageSetting ps = mSettings.mPackages.get(packageName);
13935            if (ps == null
13936                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
13937                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13938            }
13939            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13940        }
13941    }
13942
13943    @Override
13944    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13945        mContext.enforceCallingOrSelfPermission(
13946                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13947
13948        boolean result = false;
13949        synchronized (mPackages) {
13950            final PackageSetting ps = mSettings.mPackages.get(packageName);
13951            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13952                return false;
13953            }
13954            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13955        }
13956        if (result) {
13957            scheduleWritePackageRestrictionsLocked(userId);
13958        }
13959        return result;
13960    }
13961
13962    @Override
13963    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13964            String packageName) {
13965        final int callingUid = Binder.getCallingUid();
13966        if (getInstantAppPackageName(callingUid) != null) {
13967            return ParceledListSlice.emptyList();
13968        }
13969        synchronized (mPackages) {
13970            final PackageSetting ps = mSettings.mPackages.get(packageName);
13971            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
13972                return ParceledListSlice.emptyList();
13973            }
13974            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13975        }
13976    }
13977
13978    @Override
13979    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13980        if (TextUtils.isEmpty(packageName)) {
13981            return ParceledListSlice.emptyList();
13982        }
13983        final int callingUid = Binder.getCallingUid();
13984        final int callingUserId = UserHandle.getUserId(callingUid);
13985        synchronized (mPackages) {
13986            PackageParser.Package pkg = mPackages.get(packageName);
13987            if (pkg == null || pkg.activities == null) {
13988                return ParceledListSlice.emptyList();
13989            }
13990            if (pkg.mExtras == null) {
13991                return ParceledListSlice.emptyList();
13992            }
13993            final PackageSetting ps = (PackageSetting) pkg.mExtras;
13994            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
13995                return ParceledListSlice.emptyList();
13996            }
13997            final int count = pkg.activities.size();
13998            ArrayList<IntentFilter> result = new ArrayList<>();
13999            for (int n=0; n<count; n++) {
14000                PackageParser.Activity activity = pkg.activities.get(n);
14001                if (activity.intents != null && activity.intents.size() > 0) {
14002                    result.addAll(activity.intents);
14003                }
14004            }
14005            return new ParceledListSlice<>(result);
14006        }
14007    }
14008
14009    @Override
14010    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14011        mContext.enforceCallingOrSelfPermission(
14012                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14013        if (UserHandle.getCallingUserId() != userId) {
14014            mContext.enforceCallingOrSelfPermission(
14015                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14016        }
14017
14018        synchronized (mPackages) {
14019            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14020            if (packageName != null) {
14021                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14022                        packageName, userId);
14023            }
14024            return result;
14025        }
14026    }
14027
14028    @Override
14029    public String getDefaultBrowserPackageName(int userId) {
14030        if (UserHandle.getCallingUserId() != userId) {
14031            mContext.enforceCallingOrSelfPermission(
14032                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14033        }
14034        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14035            return null;
14036        }
14037        synchronized (mPackages) {
14038            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14039        }
14040    }
14041
14042    /**
14043     * Get the "allow unknown sources" setting.
14044     *
14045     * @return the current "allow unknown sources" setting
14046     */
14047    private int getUnknownSourcesSettings() {
14048        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14049                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14050                -1);
14051    }
14052
14053    @Override
14054    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14055        final int callingUid = Binder.getCallingUid();
14056        if (getInstantAppPackageName(callingUid) != null) {
14057            return;
14058        }
14059        // writer
14060        synchronized (mPackages) {
14061            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14062            if (targetPackageSetting == null
14063                    || filterAppAccessLPr(
14064                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14065                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14066            }
14067
14068            PackageSetting installerPackageSetting;
14069            if (installerPackageName != null) {
14070                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14071                if (installerPackageSetting == null) {
14072                    throw new IllegalArgumentException("Unknown installer package: "
14073                            + installerPackageName);
14074                }
14075            } else {
14076                installerPackageSetting = null;
14077            }
14078
14079            Signature[] callerSignature;
14080            Object obj = mSettings.getUserIdLPr(callingUid);
14081            if (obj != null) {
14082                if (obj instanceof SharedUserSetting) {
14083                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14084                } else if (obj instanceof PackageSetting) {
14085                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14086                } else {
14087                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14088                }
14089            } else {
14090                throw new SecurityException("Unknown calling UID: " + callingUid);
14091            }
14092
14093            // Verify: can't set installerPackageName to a package that is
14094            // not signed with the same cert as the caller.
14095            if (installerPackageSetting != null) {
14096                if (compareSignatures(callerSignature,
14097                        installerPackageSetting.signatures.mSignatures)
14098                        != PackageManager.SIGNATURE_MATCH) {
14099                    throw new SecurityException(
14100                            "Caller does not have same cert as new installer package "
14101                            + installerPackageName);
14102                }
14103            }
14104
14105            // Verify: if target already has an installer package, it must
14106            // be signed with the same cert as the caller.
14107            if (targetPackageSetting.installerPackageName != null) {
14108                PackageSetting setting = mSettings.mPackages.get(
14109                        targetPackageSetting.installerPackageName);
14110                // If the currently set package isn't valid, then it's always
14111                // okay to change it.
14112                if (setting != null) {
14113                    if (compareSignatures(callerSignature,
14114                            setting.signatures.mSignatures)
14115                            != PackageManager.SIGNATURE_MATCH) {
14116                        throw new SecurityException(
14117                                "Caller does not have same cert as old installer package "
14118                                + targetPackageSetting.installerPackageName);
14119                    }
14120                }
14121            }
14122
14123            // Okay!
14124            targetPackageSetting.installerPackageName = installerPackageName;
14125            if (installerPackageName != null) {
14126                mSettings.mInstallerPackages.add(installerPackageName);
14127            }
14128            scheduleWriteSettingsLocked();
14129        }
14130    }
14131
14132    @Override
14133    public void setApplicationCategoryHint(String packageName, int categoryHint,
14134            String callerPackageName) {
14135        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14136            throw new SecurityException("Instant applications don't have access to this method");
14137        }
14138        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14139                callerPackageName);
14140        synchronized (mPackages) {
14141            PackageSetting ps = mSettings.mPackages.get(packageName);
14142            if (ps == null) {
14143                throw new IllegalArgumentException("Unknown target package " + packageName);
14144            }
14145            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14146                throw new IllegalArgumentException("Unknown target package " + packageName);
14147            }
14148            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14149                throw new IllegalArgumentException("Calling package " + callerPackageName
14150                        + " is not installer for " + packageName);
14151            }
14152
14153            if (ps.categoryHint != categoryHint) {
14154                ps.categoryHint = categoryHint;
14155                scheduleWriteSettingsLocked();
14156            }
14157        }
14158    }
14159
14160    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14161        // Queue up an async operation since the package installation may take a little while.
14162        mHandler.post(new Runnable() {
14163            public void run() {
14164                mHandler.removeCallbacks(this);
14165                 // Result object to be returned
14166                PackageInstalledInfo res = new PackageInstalledInfo();
14167                res.setReturnCode(currentStatus);
14168                res.uid = -1;
14169                res.pkg = null;
14170                res.removedInfo = null;
14171                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14172                    args.doPreInstall(res.returnCode);
14173                    synchronized (mInstallLock) {
14174                        installPackageTracedLI(args, res);
14175                    }
14176                    args.doPostInstall(res.returnCode, res.uid);
14177                }
14178
14179                // A restore should be performed at this point if (a) the install
14180                // succeeded, (b) the operation is not an update, and (c) the new
14181                // package has not opted out of backup participation.
14182                final boolean update = res.removedInfo != null
14183                        && res.removedInfo.removedPackage != null;
14184                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14185                boolean doRestore = !update
14186                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14187
14188                // Set up the post-install work request bookkeeping.  This will be used
14189                // and cleaned up by the post-install event handling regardless of whether
14190                // there's a restore pass performed.  Token values are >= 1.
14191                int token;
14192                if (mNextInstallToken < 0) mNextInstallToken = 1;
14193                token = mNextInstallToken++;
14194
14195                PostInstallData data = new PostInstallData(args, res);
14196                mRunningInstalls.put(token, data);
14197                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14198
14199                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14200                    // Pass responsibility to the Backup Manager.  It will perform a
14201                    // restore if appropriate, then pass responsibility back to the
14202                    // Package Manager to run the post-install observer callbacks
14203                    // and broadcasts.
14204                    IBackupManager bm = IBackupManager.Stub.asInterface(
14205                            ServiceManager.getService(Context.BACKUP_SERVICE));
14206                    if (bm != null) {
14207                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14208                                + " to BM for possible restore");
14209                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14210                        try {
14211                            // TODO: http://b/22388012
14212                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14213                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14214                            } else {
14215                                doRestore = false;
14216                            }
14217                        } catch (RemoteException e) {
14218                            // can't happen; the backup manager is local
14219                        } catch (Exception e) {
14220                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14221                            doRestore = false;
14222                        }
14223                    } else {
14224                        Slog.e(TAG, "Backup Manager not found!");
14225                        doRestore = false;
14226                    }
14227                }
14228
14229                if (!doRestore) {
14230                    // No restore possible, or the Backup Manager was mysteriously not
14231                    // available -- just fire the post-install work request directly.
14232                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14233
14234                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14235
14236                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14237                    mHandler.sendMessage(msg);
14238                }
14239            }
14240        });
14241    }
14242
14243    /**
14244     * Callback from PackageSettings whenever an app is first transitioned out of the
14245     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14246     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14247     * here whether the app is the target of an ongoing install, and only send the
14248     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14249     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14250     * handling.
14251     */
14252    void notifyFirstLaunch(final String packageName, final String installerPackage,
14253            final int userId) {
14254        // Serialize this with the rest of the install-process message chain.  In the
14255        // restore-at-install case, this Runnable will necessarily run before the
14256        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14257        // are coherent.  In the non-restore case, the app has already completed install
14258        // and been launched through some other means, so it is not in a problematic
14259        // state for observers to see the FIRST_LAUNCH signal.
14260        mHandler.post(new Runnable() {
14261            @Override
14262            public void run() {
14263                for (int i = 0; i < mRunningInstalls.size(); i++) {
14264                    final PostInstallData data = mRunningInstalls.valueAt(i);
14265                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14266                        continue;
14267                    }
14268                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14269                        // right package; but is it for the right user?
14270                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14271                            if (userId == data.res.newUsers[uIndex]) {
14272                                if (DEBUG_BACKUP) {
14273                                    Slog.i(TAG, "Package " + packageName
14274                                            + " being restored so deferring FIRST_LAUNCH");
14275                                }
14276                                return;
14277                            }
14278                        }
14279                    }
14280                }
14281                // didn't find it, so not being restored
14282                if (DEBUG_BACKUP) {
14283                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14284                }
14285                final boolean isInstantApp = isInstantApp(packageName, userId);
14286                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14287                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14288                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14289            }
14290        });
14291    }
14292
14293    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14294            int[] userIds, int[] instantUserIds) {
14295        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14296                installerPkg, null, userIds, instantUserIds);
14297    }
14298
14299    private abstract class HandlerParams {
14300        private static final int MAX_RETRIES = 4;
14301
14302        /**
14303         * Number of times startCopy() has been attempted and had a non-fatal
14304         * error.
14305         */
14306        private int mRetries = 0;
14307
14308        /** User handle for the user requesting the information or installation. */
14309        private final UserHandle mUser;
14310        String traceMethod;
14311        int traceCookie;
14312
14313        HandlerParams(UserHandle user) {
14314            mUser = user;
14315        }
14316
14317        UserHandle getUser() {
14318            return mUser;
14319        }
14320
14321        HandlerParams setTraceMethod(String traceMethod) {
14322            this.traceMethod = traceMethod;
14323            return this;
14324        }
14325
14326        HandlerParams setTraceCookie(int traceCookie) {
14327            this.traceCookie = traceCookie;
14328            return this;
14329        }
14330
14331        final boolean startCopy() {
14332            boolean res;
14333            try {
14334                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14335
14336                if (++mRetries > MAX_RETRIES) {
14337                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14338                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14339                    handleServiceError();
14340                    return false;
14341                } else {
14342                    handleStartCopy();
14343                    res = true;
14344                }
14345            } catch (RemoteException e) {
14346                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14347                mHandler.sendEmptyMessage(MCS_RECONNECT);
14348                res = false;
14349            }
14350            handleReturnCode();
14351            return res;
14352        }
14353
14354        final void serviceError() {
14355            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14356            handleServiceError();
14357            handleReturnCode();
14358        }
14359
14360        abstract void handleStartCopy() throws RemoteException;
14361        abstract void handleServiceError();
14362        abstract void handleReturnCode();
14363    }
14364
14365    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14366        for (File path : paths) {
14367            try {
14368                mcs.clearDirectory(path.getAbsolutePath());
14369            } catch (RemoteException e) {
14370            }
14371        }
14372    }
14373
14374    static class OriginInfo {
14375        /**
14376         * Location where install is coming from, before it has been
14377         * copied/renamed into place. This could be a single monolithic APK
14378         * file, or a cluster directory. This location may be untrusted.
14379         */
14380        final File file;
14381
14382        /**
14383         * Flag indicating that {@link #file} or {@link #cid} has already been
14384         * staged, meaning downstream users don't need to defensively copy the
14385         * contents.
14386         */
14387        final boolean staged;
14388
14389        /**
14390         * Flag indicating that {@link #file} or {@link #cid} is an already
14391         * installed app that is being moved.
14392         */
14393        final boolean existing;
14394
14395        final String resolvedPath;
14396        final File resolvedFile;
14397
14398        static OriginInfo fromNothing() {
14399            return new OriginInfo(null, false, false);
14400        }
14401
14402        static OriginInfo fromUntrustedFile(File file) {
14403            return new OriginInfo(file, false, false);
14404        }
14405
14406        static OriginInfo fromExistingFile(File file) {
14407            return new OriginInfo(file, false, true);
14408        }
14409
14410        static OriginInfo fromStagedFile(File file) {
14411            return new OriginInfo(file, true, false);
14412        }
14413
14414        private OriginInfo(File file, boolean staged, boolean existing) {
14415            this.file = file;
14416            this.staged = staged;
14417            this.existing = existing;
14418
14419            if (file != null) {
14420                resolvedPath = file.getAbsolutePath();
14421                resolvedFile = file;
14422            } else {
14423                resolvedPath = null;
14424                resolvedFile = null;
14425            }
14426        }
14427    }
14428
14429    static class MoveInfo {
14430        final int moveId;
14431        final String fromUuid;
14432        final String toUuid;
14433        final String packageName;
14434        final String dataAppName;
14435        final int appId;
14436        final String seinfo;
14437        final int targetSdkVersion;
14438
14439        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14440                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14441            this.moveId = moveId;
14442            this.fromUuid = fromUuid;
14443            this.toUuid = toUuid;
14444            this.packageName = packageName;
14445            this.dataAppName = dataAppName;
14446            this.appId = appId;
14447            this.seinfo = seinfo;
14448            this.targetSdkVersion = targetSdkVersion;
14449        }
14450    }
14451
14452    static class VerificationInfo {
14453        /** A constant used to indicate that a uid value is not present. */
14454        public static final int NO_UID = -1;
14455
14456        /** URI referencing where the package was downloaded from. */
14457        final Uri originatingUri;
14458
14459        /** HTTP referrer URI associated with the originatingURI. */
14460        final Uri referrer;
14461
14462        /** UID of the application that the install request originated from. */
14463        final int originatingUid;
14464
14465        /** UID of application requesting the install */
14466        final int installerUid;
14467
14468        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14469            this.originatingUri = originatingUri;
14470            this.referrer = referrer;
14471            this.originatingUid = originatingUid;
14472            this.installerUid = installerUid;
14473        }
14474    }
14475
14476    class InstallParams extends HandlerParams {
14477        final OriginInfo origin;
14478        final MoveInfo move;
14479        final IPackageInstallObserver2 observer;
14480        int installFlags;
14481        final String installerPackageName;
14482        final String volumeUuid;
14483        private InstallArgs mArgs;
14484        private int mRet;
14485        final String packageAbiOverride;
14486        final String[] grantedRuntimePermissions;
14487        final VerificationInfo verificationInfo;
14488        final PackageParser.SigningDetails signingDetails;
14489        final int installReason;
14490
14491        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14492                int installFlags, String installerPackageName, String volumeUuid,
14493                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14494                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
14495            super(user);
14496            this.origin = origin;
14497            this.move = move;
14498            this.observer = observer;
14499            this.installFlags = installFlags;
14500            this.installerPackageName = installerPackageName;
14501            this.volumeUuid = volumeUuid;
14502            this.verificationInfo = verificationInfo;
14503            this.packageAbiOverride = packageAbiOverride;
14504            this.grantedRuntimePermissions = grantedPermissions;
14505            this.signingDetails = signingDetails;
14506            this.installReason = installReason;
14507        }
14508
14509        @Override
14510        public String toString() {
14511            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14512                    + " file=" + origin.file + "}";
14513        }
14514
14515        private int installLocationPolicy(PackageInfoLite pkgLite) {
14516            String packageName = pkgLite.packageName;
14517            int installLocation = pkgLite.installLocation;
14518            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14519            // reader
14520            synchronized (mPackages) {
14521                // Currently installed package which the new package is attempting to replace or
14522                // null if no such package is installed.
14523                PackageParser.Package installedPkg = mPackages.get(packageName);
14524                // Package which currently owns the data which the new package will own if installed.
14525                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14526                // will be null whereas dataOwnerPkg will contain information about the package
14527                // which was uninstalled while keeping its data.
14528                PackageParser.Package dataOwnerPkg = installedPkg;
14529                if (dataOwnerPkg  == null) {
14530                    PackageSetting ps = mSettings.mPackages.get(packageName);
14531                    if (ps != null) {
14532                        dataOwnerPkg = ps.pkg;
14533                    }
14534                }
14535
14536                if (dataOwnerPkg != null) {
14537                    // If installed, the package will get access to data left on the device by its
14538                    // predecessor. As a security measure, this is permited only if this is not a
14539                    // version downgrade or if the predecessor package is marked as debuggable and
14540                    // a downgrade is explicitly requested.
14541                    //
14542                    // On debuggable platform builds, downgrades are permitted even for
14543                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14544                    // not offer security guarantees and thus it's OK to disable some security
14545                    // mechanisms to make debugging/testing easier on those builds. However, even on
14546                    // debuggable builds downgrades of packages are permitted only if requested via
14547                    // installFlags. This is because we aim to keep the behavior of debuggable
14548                    // platform builds as close as possible to the behavior of non-debuggable
14549                    // platform builds.
14550                    final boolean downgradeRequested =
14551                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14552                    final boolean packageDebuggable =
14553                                (dataOwnerPkg.applicationInfo.flags
14554                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14555                    final boolean downgradePermitted =
14556                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14557                    if (!downgradePermitted) {
14558                        try {
14559                            checkDowngrade(dataOwnerPkg, pkgLite);
14560                        } catch (PackageManagerException e) {
14561                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14562                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14563                        }
14564                    }
14565                }
14566
14567                if (installedPkg != null) {
14568                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14569                        // Check for updated system application.
14570                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14571                            if (onSd) {
14572                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14573                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14574                            }
14575                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14576                        } else {
14577                            if (onSd) {
14578                                // Install flag overrides everything.
14579                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14580                            }
14581                            // If current upgrade specifies particular preference
14582                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14583                                // Application explicitly specified internal.
14584                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14585                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14586                                // App explictly prefers external. Let policy decide
14587                            } else {
14588                                // Prefer previous location
14589                                if (isExternal(installedPkg)) {
14590                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14591                                }
14592                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14593                            }
14594                        }
14595                    } else {
14596                        // Invalid install. Return error code
14597                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14598                    }
14599                }
14600            }
14601            // All the special cases have been taken care of.
14602            // Return result based on recommended install location.
14603            if (onSd) {
14604                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14605            }
14606            return pkgLite.recommendedInstallLocation;
14607        }
14608
14609        /*
14610         * Invoke remote method to get package information and install
14611         * location values. Override install location based on default
14612         * policy if needed and then create install arguments based
14613         * on the install location.
14614         */
14615        public void handleStartCopy() throws RemoteException {
14616            int ret = PackageManager.INSTALL_SUCCEEDED;
14617
14618            // If we're already staged, we've firmly committed to an install location
14619            if (origin.staged) {
14620                if (origin.file != null) {
14621                    installFlags |= PackageManager.INSTALL_INTERNAL;
14622                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14623                } else {
14624                    throw new IllegalStateException("Invalid stage location");
14625                }
14626            }
14627
14628            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14629            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14630            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14631            PackageInfoLite pkgLite = null;
14632
14633            if (onInt && onSd) {
14634                // Check if both bits are set.
14635                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14636                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14637            } else if (onSd && ephemeral) {
14638                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14639                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14640            } else {
14641                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14642                        packageAbiOverride);
14643
14644                if (DEBUG_EPHEMERAL && ephemeral) {
14645                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14646                }
14647
14648                /*
14649                 * If we have too little free space, try to free cache
14650                 * before giving up.
14651                 */
14652                if (!origin.staged && pkgLite.recommendedInstallLocation
14653                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14654                    // TODO: focus freeing disk space on the target device
14655                    final StorageManager storage = StorageManager.from(mContext);
14656                    final long lowThreshold = storage.getStorageLowBytes(
14657                            Environment.getDataDirectory());
14658
14659                    final long sizeBytes = mContainerService.calculateInstalledSize(
14660                            origin.resolvedPath, packageAbiOverride);
14661
14662                    try {
14663                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14664                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14665                                installFlags, packageAbiOverride);
14666                    } catch (InstallerException e) {
14667                        Slog.w(TAG, "Failed to free cache", e);
14668                    }
14669
14670                    /*
14671                     * The cache free must have deleted the file we
14672                     * downloaded to install.
14673                     *
14674                     * TODO: fix the "freeCache" call to not delete
14675                     *       the file we care about.
14676                     */
14677                    if (pkgLite.recommendedInstallLocation
14678                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14679                        pkgLite.recommendedInstallLocation
14680                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14681                    }
14682                }
14683            }
14684
14685            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14686                int loc = pkgLite.recommendedInstallLocation;
14687                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14688                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14689                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14690                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14691                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14692                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14693                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14694                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14695                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14696                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14697                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14698                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14699                } else {
14700                    // Override with defaults if needed.
14701                    loc = installLocationPolicy(pkgLite);
14702                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14703                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14704                    } else if (!onSd && !onInt) {
14705                        // Override install location with flags
14706                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14707                            // Set the flag to install on external media.
14708                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14709                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14710                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14711                            if (DEBUG_EPHEMERAL) {
14712                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14713                            }
14714                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14715                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14716                                    |PackageManager.INSTALL_INTERNAL);
14717                        } else {
14718                            // Make sure the flag for installing on external
14719                            // media is unset
14720                            installFlags |= PackageManager.INSTALL_INTERNAL;
14721                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14722                        }
14723                    }
14724                }
14725            }
14726
14727            final InstallArgs args = createInstallArgs(this);
14728            mArgs = args;
14729
14730            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14731                // TODO: http://b/22976637
14732                // Apps installed for "all" users use the device owner to verify the app
14733                UserHandle verifierUser = getUser();
14734                if (verifierUser == UserHandle.ALL) {
14735                    verifierUser = UserHandle.SYSTEM;
14736                }
14737
14738                /*
14739                 * Determine if we have any installed package verifiers. If we
14740                 * do, then we'll defer to them to verify the packages.
14741                 */
14742                final int requiredUid = mRequiredVerifierPackage == null ? -1
14743                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14744                                verifierUser.getIdentifier());
14745                final int installerUid =
14746                        verificationInfo == null ? -1 : verificationInfo.installerUid;
14747                if (!origin.existing && requiredUid != -1
14748                        && isVerificationEnabled(
14749                                verifierUser.getIdentifier(), installFlags, installerUid)) {
14750                    final Intent verification = new Intent(
14751                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14752                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14753                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14754                            PACKAGE_MIME_TYPE);
14755                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14756
14757                    // Query all live verifiers based on current user state
14758                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14759                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14760                            false /*allowDynamicSplits*/);
14761
14762                    if (DEBUG_VERIFY) {
14763                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14764                                + verification.toString() + " with " + pkgLite.verifiers.length
14765                                + " optional verifiers");
14766                    }
14767
14768                    final int verificationId = mPendingVerificationToken++;
14769
14770                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14771
14772                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14773                            installerPackageName);
14774
14775                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14776                            installFlags);
14777
14778                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14779                            pkgLite.packageName);
14780
14781                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14782                            pkgLite.versionCode);
14783
14784                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14785                            pkgLite.getLongVersionCode());
14786
14787                    if (verificationInfo != null) {
14788                        if (verificationInfo.originatingUri != null) {
14789                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14790                                    verificationInfo.originatingUri);
14791                        }
14792                        if (verificationInfo.referrer != null) {
14793                            verification.putExtra(Intent.EXTRA_REFERRER,
14794                                    verificationInfo.referrer);
14795                        }
14796                        if (verificationInfo.originatingUid >= 0) {
14797                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14798                                    verificationInfo.originatingUid);
14799                        }
14800                        if (verificationInfo.installerUid >= 0) {
14801                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14802                                    verificationInfo.installerUid);
14803                        }
14804                    }
14805
14806                    final PackageVerificationState verificationState = new PackageVerificationState(
14807                            requiredUid, args);
14808
14809                    mPendingVerification.append(verificationId, verificationState);
14810
14811                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14812                            receivers, verificationState);
14813
14814                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14815                    final long idleDuration = getVerificationTimeout();
14816
14817                    /*
14818                     * If any sufficient verifiers were listed in the package
14819                     * manifest, attempt to ask them.
14820                     */
14821                    if (sufficientVerifiers != null) {
14822                        final int N = sufficientVerifiers.size();
14823                        if (N == 0) {
14824                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14825                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14826                        } else {
14827                            for (int i = 0; i < N; i++) {
14828                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14829                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14830                                        verifierComponent.getPackageName(), idleDuration,
14831                                        verifierUser.getIdentifier(), false, "package verifier");
14832
14833                                final Intent sufficientIntent = new Intent(verification);
14834                                sufficientIntent.setComponent(verifierComponent);
14835                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14836                            }
14837                        }
14838                    }
14839
14840                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14841                            mRequiredVerifierPackage, receivers);
14842                    if (ret == PackageManager.INSTALL_SUCCEEDED
14843                            && mRequiredVerifierPackage != null) {
14844                        Trace.asyncTraceBegin(
14845                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14846                        /*
14847                         * Send the intent to the required verification agent,
14848                         * but only start the verification timeout after the
14849                         * target BroadcastReceivers have run.
14850                         */
14851                        verification.setComponent(requiredVerifierComponent);
14852                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14853                                mRequiredVerifierPackage, idleDuration,
14854                                verifierUser.getIdentifier(), false, "package verifier");
14855                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14856                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14857                                new BroadcastReceiver() {
14858                                    @Override
14859                                    public void onReceive(Context context, Intent intent) {
14860                                        final Message msg = mHandler
14861                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14862                                        msg.arg1 = verificationId;
14863                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14864                                    }
14865                                }, null, 0, null, null);
14866
14867                        /*
14868                         * We don't want the copy to proceed until verification
14869                         * succeeds, so null out this field.
14870                         */
14871                        mArgs = null;
14872                    }
14873                } else {
14874                    /*
14875                     * No package verification is enabled, so immediately start
14876                     * the remote call to initiate copy using temporary file.
14877                     */
14878                    ret = args.copyApk(mContainerService, true);
14879                }
14880            }
14881
14882            mRet = ret;
14883        }
14884
14885        @Override
14886        void handleReturnCode() {
14887            // If mArgs is null, then MCS couldn't be reached. When it
14888            // reconnects, it will try again to install. At that point, this
14889            // will succeed.
14890            if (mArgs != null) {
14891                processPendingInstall(mArgs, mRet);
14892            }
14893        }
14894
14895        @Override
14896        void handleServiceError() {
14897            mArgs = createInstallArgs(this);
14898            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14899        }
14900    }
14901
14902    private InstallArgs createInstallArgs(InstallParams params) {
14903        if (params.move != null) {
14904            return new MoveInstallArgs(params);
14905        } else {
14906            return new FileInstallArgs(params);
14907        }
14908    }
14909
14910    /**
14911     * Create args that describe an existing installed package. Typically used
14912     * when cleaning up old installs, or used as a move source.
14913     */
14914    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
14915            String resourcePath, String[] instructionSets) {
14916        return new FileInstallArgs(codePath, resourcePath, instructionSets);
14917    }
14918
14919    static abstract class InstallArgs {
14920        /** @see InstallParams#origin */
14921        final OriginInfo origin;
14922        /** @see InstallParams#move */
14923        final MoveInfo move;
14924
14925        final IPackageInstallObserver2 observer;
14926        // Always refers to PackageManager flags only
14927        final int installFlags;
14928        final String installerPackageName;
14929        final String volumeUuid;
14930        final UserHandle user;
14931        final String abiOverride;
14932        final String[] installGrantPermissions;
14933        /** If non-null, drop an async trace when the install completes */
14934        final String traceMethod;
14935        final int traceCookie;
14936        final PackageParser.SigningDetails signingDetails;
14937        final int installReason;
14938
14939        // The list of instruction sets supported by this app. This is currently
14940        // only used during the rmdex() phase to clean up resources. We can get rid of this
14941        // if we move dex files under the common app path.
14942        /* nullable */ String[] instructionSets;
14943
14944        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14945                int installFlags, String installerPackageName, String volumeUuid,
14946                UserHandle user, String[] instructionSets,
14947                String abiOverride, String[] installGrantPermissions,
14948                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
14949                int installReason) {
14950            this.origin = origin;
14951            this.move = move;
14952            this.installFlags = installFlags;
14953            this.observer = observer;
14954            this.installerPackageName = installerPackageName;
14955            this.volumeUuid = volumeUuid;
14956            this.user = user;
14957            this.instructionSets = instructionSets;
14958            this.abiOverride = abiOverride;
14959            this.installGrantPermissions = installGrantPermissions;
14960            this.traceMethod = traceMethod;
14961            this.traceCookie = traceCookie;
14962            this.signingDetails = signingDetails;
14963            this.installReason = installReason;
14964        }
14965
14966        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
14967        abstract int doPreInstall(int status);
14968
14969        /**
14970         * Rename package into final resting place. All paths on the given
14971         * scanned package should be updated to reflect the rename.
14972         */
14973        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
14974        abstract int doPostInstall(int status, int uid);
14975
14976        /** @see PackageSettingBase#codePathString */
14977        abstract String getCodePath();
14978        /** @see PackageSettingBase#resourcePathString */
14979        abstract String getResourcePath();
14980
14981        // Need installer lock especially for dex file removal.
14982        abstract void cleanUpResourcesLI();
14983        abstract boolean doPostDeleteLI(boolean delete);
14984
14985        /**
14986         * Called before the source arguments are copied. This is used mostly
14987         * for MoveParams when it needs to read the source file to put it in the
14988         * destination.
14989         */
14990        int doPreCopy() {
14991            return PackageManager.INSTALL_SUCCEEDED;
14992        }
14993
14994        /**
14995         * Called after the source arguments are copied. This is used mostly for
14996         * MoveParams when it needs to read the source file to put it in the
14997         * destination.
14998         */
14999        int doPostCopy(int uid) {
15000            return PackageManager.INSTALL_SUCCEEDED;
15001        }
15002
15003        protected boolean isFwdLocked() {
15004            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15005        }
15006
15007        protected boolean isExternalAsec() {
15008            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15009        }
15010
15011        protected boolean isEphemeral() {
15012            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15013        }
15014
15015        UserHandle getUser() {
15016            return user;
15017        }
15018    }
15019
15020    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15021        if (!allCodePaths.isEmpty()) {
15022            if (instructionSets == null) {
15023                throw new IllegalStateException("instructionSet == null");
15024            }
15025            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15026            for (String codePath : allCodePaths) {
15027                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15028                    try {
15029                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15030                    } catch (InstallerException ignored) {
15031                    }
15032                }
15033            }
15034        }
15035    }
15036
15037    /**
15038     * Logic to handle installation of non-ASEC applications, including copying
15039     * and renaming logic.
15040     */
15041    class FileInstallArgs extends InstallArgs {
15042        private File codeFile;
15043        private File resourceFile;
15044
15045        // Example topology:
15046        // /data/app/com.example/base.apk
15047        // /data/app/com.example/split_foo.apk
15048        // /data/app/com.example/lib/arm/libfoo.so
15049        // /data/app/com.example/lib/arm64/libfoo.so
15050        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15051
15052        /** New install */
15053        FileInstallArgs(InstallParams params) {
15054            super(params.origin, params.move, params.observer, params.installFlags,
15055                    params.installerPackageName, params.volumeUuid,
15056                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15057                    params.grantedRuntimePermissions,
15058                    params.traceMethod, params.traceCookie, params.signingDetails,
15059                    params.installReason);
15060            if (isFwdLocked()) {
15061                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15062            }
15063        }
15064
15065        /** Existing install */
15066        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15067            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15068                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15069                    PackageManager.INSTALL_REASON_UNKNOWN);
15070            this.codeFile = (codePath != null) ? new File(codePath) : null;
15071            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15072        }
15073
15074        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15075            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15076            try {
15077                return doCopyApk(imcs, temp);
15078            } finally {
15079                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15080            }
15081        }
15082
15083        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15084            if (origin.staged) {
15085                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15086                codeFile = origin.file;
15087                resourceFile = origin.file;
15088                return PackageManager.INSTALL_SUCCEEDED;
15089            }
15090
15091            try {
15092                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15093                final File tempDir =
15094                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15095                codeFile = tempDir;
15096                resourceFile = tempDir;
15097            } catch (IOException e) {
15098                Slog.w(TAG, "Failed to create copy file: " + e);
15099                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15100            }
15101
15102            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15103                @Override
15104                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15105                    if (!FileUtils.isValidExtFilename(name)) {
15106                        throw new IllegalArgumentException("Invalid filename: " + name);
15107                    }
15108                    try {
15109                        final File file = new File(codeFile, name);
15110                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15111                                O_RDWR | O_CREAT, 0644);
15112                        Os.chmod(file.getAbsolutePath(), 0644);
15113                        return new ParcelFileDescriptor(fd);
15114                    } catch (ErrnoException e) {
15115                        throw new RemoteException("Failed to open: " + e.getMessage());
15116                    }
15117                }
15118            };
15119
15120            int ret = PackageManager.INSTALL_SUCCEEDED;
15121            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15122            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15123                Slog.e(TAG, "Failed to copy package");
15124                return ret;
15125            }
15126
15127            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15128            NativeLibraryHelper.Handle handle = null;
15129            try {
15130                handle = NativeLibraryHelper.Handle.create(codeFile);
15131                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15132                        abiOverride);
15133            } catch (IOException e) {
15134                Slog.e(TAG, "Copying native libraries failed", e);
15135                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15136            } finally {
15137                IoUtils.closeQuietly(handle);
15138            }
15139
15140            return ret;
15141        }
15142
15143        int doPreInstall(int status) {
15144            if (status != PackageManager.INSTALL_SUCCEEDED) {
15145                cleanUp();
15146            }
15147            return status;
15148        }
15149
15150        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15151            if (status != PackageManager.INSTALL_SUCCEEDED) {
15152                cleanUp();
15153                return false;
15154            }
15155
15156            final File targetDir = codeFile.getParentFile();
15157            final File beforeCodeFile = codeFile;
15158            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15159
15160            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15161            try {
15162                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15163            } catch (ErrnoException e) {
15164                Slog.w(TAG, "Failed to rename", e);
15165                return false;
15166            }
15167
15168            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15169                Slog.w(TAG, "Failed to restorecon");
15170                return false;
15171            }
15172
15173            // Reflect the rename internally
15174            codeFile = afterCodeFile;
15175            resourceFile = afterCodeFile;
15176
15177            // Reflect the rename in scanned details
15178            try {
15179                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15180            } catch (IOException e) {
15181                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15182                return false;
15183            }
15184            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15185                    afterCodeFile, pkg.baseCodePath));
15186            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15187                    afterCodeFile, pkg.splitCodePaths));
15188
15189            // Reflect the rename in app info
15190            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15191            pkg.setApplicationInfoCodePath(pkg.codePath);
15192            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15193            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15194            pkg.setApplicationInfoResourcePath(pkg.codePath);
15195            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15196            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15197
15198            return true;
15199        }
15200
15201        int doPostInstall(int status, int uid) {
15202            if (status != PackageManager.INSTALL_SUCCEEDED) {
15203                cleanUp();
15204            }
15205            return status;
15206        }
15207
15208        @Override
15209        String getCodePath() {
15210            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15211        }
15212
15213        @Override
15214        String getResourcePath() {
15215            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15216        }
15217
15218        private boolean cleanUp() {
15219            if (codeFile == null || !codeFile.exists()) {
15220                return false;
15221            }
15222
15223            removeCodePathLI(codeFile);
15224
15225            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15226                resourceFile.delete();
15227            }
15228
15229            return true;
15230        }
15231
15232        void cleanUpResourcesLI() {
15233            // Try enumerating all code paths before deleting
15234            List<String> allCodePaths = Collections.EMPTY_LIST;
15235            if (codeFile != null && codeFile.exists()) {
15236                try {
15237                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15238                    allCodePaths = pkg.getAllCodePaths();
15239                } catch (PackageParserException e) {
15240                    // Ignored; we tried our best
15241                }
15242            }
15243
15244            cleanUp();
15245            removeDexFiles(allCodePaths, instructionSets);
15246        }
15247
15248        boolean doPostDeleteLI(boolean delete) {
15249            // XXX err, shouldn't we respect the delete flag?
15250            cleanUpResourcesLI();
15251            return true;
15252        }
15253    }
15254
15255    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15256            PackageManagerException {
15257        if (copyRet < 0) {
15258            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15259                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15260                throw new PackageManagerException(copyRet, message);
15261            }
15262        }
15263    }
15264
15265    /**
15266     * Extract the StorageManagerService "container ID" from the full code path of an
15267     * .apk.
15268     */
15269    static String cidFromCodePath(String fullCodePath) {
15270        int eidx = fullCodePath.lastIndexOf("/");
15271        String subStr1 = fullCodePath.substring(0, eidx);
15272        int sidx = subStr1.lastIndexOf("/");
15273        return subStr1.substring(sidx+1, eidx);
15274    }
15275
15276    /**
15277     * Logic to handle movement of existing installed applications.
15278     */
15279    class MoveInstallArgs extends InstallArgs {
15280        private File codeFile;
15281        private File resourceFile;
15282
15283        /** New install */
15284        MoveInstallArgs(InstallParams params) {
15285            super(params.origin, params.move, params.observer, params.installFlags,
15286                    params.installerPackageName, params.volumeUuid,
15287                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15288                    params.grantedRuntimePermissions,
15289                    params.traceMethod, params.traceCookie, params.signingDetails,
15290                    params.installReason);
15291        }
15292
15293        int copyApk(IMediaContainerService imcs, boolean temp) {
15294            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15295                    + move.fromUuid + " to " + move.toUuid);
15296            synchronized (mInstaller) {
15297                try {
15298                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15299                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15300                } catch (InstallerException e) {
15301                    Slog.w(TAG, "Failed to move app", e);
15302                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15303                }
15304            }
15305
15306            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15307            resourceFile = codeFile;
15308            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15309
15310            return PackageManager.INSTALL_SUCCEEDED;
15311        }
15312
15313        int doPreInstall(int status) {
15314            if (status != PackageManager.INSTALL_SUCCEEDED) {
15315                cleanUp(move.toUuid);
15316            }
15317            return status;
15318        }
15319
15320        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15321            if (status != PackageManager.INSTALL_SUCCEEDED) {
15322                cleanUp(move.toUuid);
15323                return false;
15324            }
15325
15326            // Reflect the move in app info
15327            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15328            pkg.setApplicationInfoCodePath(pkg.codePath);
15329            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15330            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15331            pkg.setApplicationInfoResourcePath(pkg.codePath);
15332            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15333            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15334
15335            return true;
15336        }
15337
15338        int doPostInstall(int status, int uid) {
15339            if (status == PackageManager.INSTALL_SUCCEEDED) {
15340                cleanUp(move.fromUuid);
15341            } else {
15342                cleanUp(move.toUuid);
15343            }
15344            return status;
15345        }
15346
15347        @Override
15348        String getCodePath() {
15349            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15350        }
15351
15352        @Override
15353        String getResourcePath() {
15354            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15355        }
15356
15357        private boolean cleanUp(String volumeUuid) {
15358            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15359                    move.dataAppName);
15360            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15361            final int[] userIds = sUserManager.getUserIds();
15362            synchronized (mInstallLock) {
15363                // Clean up both app data and code
15364                // All package moves are frozen until finished
15365                for (int userId : userIds) {
15366                    try {
15367                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15368                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15369                    } catch (InstallerException e) {
15370                        Slog.w(TAG, String.valueOf(e));
15371                    }
15372                }
15373                removeCodePathLI(codeFile);
15374            }
15375            return true;
15376        }
15377
15378        void cleanUpResourcesLI() {
15379            throw new UnsupportedOperationException();
15380        }
15381
15382        boolean doPostDeleteLI(boolean delete) {
15383            throw new UnsupportedOperationException();
15384        }
15385    }
15386
15387    static String getAsecPackageName(String packageCid) {
15388        int idx = packageCid.lastIndexOf("-");
15389        if (idx == -1) {
15390            return packageCid;
15391        }
15392        return packageCid.substring(0, idx);
15393    }
15394
15395    // Utility method used to create code paths based on package name and available index.
15396    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15397        String idxStr = "";
15398        int idx = 1;
15399        // Fall back to default value of idx=1 if prefix is not
15400        // part of oldCodePath
15401        if (oldCodePath != null) {
15402            String subStr = oldCodePath;
15403            // Drop the suffix right away
15404            if (suffix != null && subStr.endsWith(suffix)) {
15405                subStr = subStr.substring(0, subStr.length() - suffix.length());
15406            }
15407            // If oldCodePath already contains prefix find out the
15408            // ending index to either increment or decrement.
15409            int sidx = subStr.lastIndexOf(prefix);
15410            if (sidx != -1) {
15411                subStr = subStr.substring(sidx + prefix.length());
15412                if (subStr != null) {
15413                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15414                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15415                    }
15416                    try {
15417                        idx = Integer.parseInt(subStr);
15418                        if (idx <= 1) {
15419                            idx++;
15420                        } else {
15421                            idx--;
15422                        }
15423                    } catch(NumberFormatException e) {
15424                    }
15425                }
15426            }
15427        }
15428        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15429        return prefix + idxStr;
15430    }
15431
15432    private File getNextCodePath(File targetDir, String packageName) {
15433        File result;
15434        SecureRandom random = new SecureRandom();
15435        byte[] bytes = new byte[16];
15436        do {
15437            random.nextBytes(bytes);
15438            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15439            result = new File(targetDir, packageName + "-" + suffix);
15440        } while (result.exists());
15441        return result;
15442    }
15443
15444    // Utility method that returns the relative package path with respect
15445    // to the installation directory. Like say for /data/data/com.test-1.apk
15446    // string com.test-1 is returned.
15447    static String deriveCodePathName(String codePath) {
15448        if (codePath == null) {
15449            return null;
15450        }
15451        final File codeFile = new File(codePath);
15452        final String name = codeFile.getName();
15453        if (codeFile.isDirectory()) {
15454            return name;
15455        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15456            final int lastDot = name.lastIndexOf('.');
15457            return name.substring(0, lastDot);
15458        } else {
15459            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15460            return null;
15461        }
15462    }
15463
15464    static class PackageInstalledInfo {
15465        String name;
15466        int uid;
15467        // The set of users that originally had this package installed.
15468        int[] origUsers;
15469        // The set of users that now have this package installed.
15470        int[] newUsers;
15471        PackageParser.Package pkg;
15472        int returnCode;
15473        String returnMsg;
15474        String installerPackageName;
15475        PackageRemovedInfo removedInfo;
15476        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15477
15478        public void setError(int code, String msg) {
15479            setReturnCode(code);
15480            setReturnMessage(msg);
15481            Slog.w(TAG, msg);
15482        }
15483
15484        public void setError(String msg, PackageParserException e) {
15485            setReturnCode(e.error);
15486            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15487            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15488            for (int i = 0; i < childCount; i++) {
15489                addedChildPackages.valueAt(i).setError(msg, e);
15490            }
15491            Slog.w(TAG, msg, e);
15492        }
15493
15494        public void setError(String msg, PackageManagerException e) {
15495            returnCode = e.error;
15496            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15497            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15498            for (int i = 0; i < childCount; i++) {
15499                addedChildPackages.valueAt(i).setError(msg, e);
15500            }
15501            Slog.w(TAG, msg, e);
15502        }
15503
15504        public void setReturnCode(int returnCode) {
15505            this.returnCode = returnCode;
15506            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15507            for (int i = 0; i < childCount; i++) {
15508                addedChildPackages.valueAt(i).returnCode = returnCode;
15509            }
15510        }
15511
15512        private void setReturnMessage(String returnMsg) {
15513            this.returnMsg = returnMsg;
15514            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15515            for (int i = 0; i < childCount; i++) {
15516                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15517            }
15518        }
15519
15520        // In some error cases we want to convey more info back to the observer
15521        String origPackage;
15522        String origPermission;
15523    }
15524
15525    /*
15526     * Install a non-existing package.
15527     */
15528    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15529            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15530            String volumeUuid, PackageInstalledInfo res, int installReason) {
15531        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15532
15533        // Remember this for later, in case we need to rollback this install
15534        String pkgName = pkg.packageName;
15535
15536        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15537
15538        synchronized(mPackages) {
15539            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15540            if (renamedPackage != null) {
15541                // A package with the same name is already installed, though
15542                // it has been renamed to an older name.  The package we
15543                // are trying to install should be installed as an update to
15544                // the existing one, but that has not been requested, so bail.
15545                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15546                        + " without first uninstalling package running as "
15547                        + renamedPackage);
15548                return;
15549            }
15550            if (mPackages.containsKey(pkgName)) {
15551                // Don't allow installation over an existing package with the same name.
15552                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15553                        + " without first uninstalling.");
15554                return;
15555            }
15556        }
15557
15558        try {
15559            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15560                    System.currentTimeMillis(), user);
15561
15562            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15563
15564            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15565                prepareAppDataAfterInstallLIF(newPackage);
15566
15567            } else {
15568                // Remove package from internal structures, but keep around any
15569                // data that might have already existed
15570                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15571                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15572            }
15573        } catch (PackageManagerException e) {
15574            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15575        }
15576
15577        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15578    }
15579
15580    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15581        try (DigestInputStream digestStream =
15582                new DigestInputStream(new FileInputStream(file), digest)) {
15583            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15584        }
15585    }
15586
15587    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15588            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15589            PackageInstalledInfo res, int installReason) {
15590        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15591
15592        final PackageParser.Package oldPackage;
15593        final PackageSetting ps;
15594        final String pkgName = pkg.packageName;
15595        final int[] allUsers;
15596        final int[] installedUsers;
15597
15598        synchronized(mPackages) {
15599            oldPackage = mPackages.get(pkgName);
15600            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15601
15602            // don't allow upgrade to target a release SDK from a pre-release SDK
15603            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15604                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15605            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15606                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15607            if (oldTargetsPreRelease
15608                    && !newTargetsPreRelease
15609                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15610                Slog.w(TAG, "Can't install package targeting released sdk");
15611                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15612                return;
15613            }
15614
15615            ps = mSettings.mPackages.get(pkgName);
15616
15617            // verify signatures are valid
15618            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
15619            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
15620                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
15621                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15622                            "New package not signed by keys specified by upgrade-keysets: "
15623                                    + pkgName);
15624                    return;
15625                }
15626            } else {
15627                // default to original signature matching
15628                if (compareSignatures(oldPackage.mSigningDetails.signatures,
15629                        pkg.mSigningDetails.signatures)
15630                        != PackageManager.SIGNATURE_MATCH) {
15631                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15632                            "New package has a different signature: " + pkgName);
15633                    return;
15634                }
15635            }
15636
15637            // don't allow a system upgrade unless the upgrade hash matches
15638            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
15639                byte[] digestBytes = null;
15640                try {
15641                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15642                    updateDigest(digest, new File(pkg.baseCodePath));
15643                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15644                        for (String path : pkg.splitCodePaths) {
15645                            updateDigest(digest, new File(path));
15646                        }
15647                    }
15648                    digestBytes = digest.digest();
15649                } catch (NoSuchAlgorithmException | IOException e) {
15650                    res.setError(INSTALL_FAILED_INVALID_APK,
15651                            "Could not compute hash: " + pkgName);
15652                    return;
15653                }
15654                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15655                    res.setError(INSTALL_FAILED_INVALID_APK,
15656                            "New package fails restrict-update check: " + pkgName);
15657                    return;
15658                }
15659                // retain upgrade restriction
15660                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15661            }
15662
15663            // Check for shared user id changes
15664            String invalidPackageName =
15665                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15666            if (invalidPackageName != null) {
15667                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15668                        "Package " + invalidPackageName + " tried to change user "
15669                                + oldPackage.mSharedUserId);
15670                return;
15671            }
15672
15673            // check if the new package supports all of the abis which the old package supports
15674            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
15675            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
15676            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
15677                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15678                        "Update to package " + pkgName + " doesn't support multi arch");
15679                return;
15680            }
15681
15682            // In case of rollback, remember per-user/profile install state
15683            allUsers = sUserManager.getUserIds();
15684            installedUsers = ps.queryInstalledUsers(allUsers, true);
15685
15686            // don't allow an upgrade from full to ephemeral
15687            if (isInstantApp) {
15688                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
15689                    for (int currentUser : allUsers) {
15690                        if (!ps.getInstantApp(currentUser)) {
15691                            // can't downgrade from full to instant
15692                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15693                                    + " for user: " + currentUser);
15694                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15695                            return;
15696                        }
15697                    }
15698                } else if (!ps.getInstantApp(user.getIdentifier())) {
15699                    // can't downgrade from full to instant
15700                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15701                            + " for user: " + user.getIdentifier());
15702                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15703                    return;
15704                }
15705            }
15706        }
15707
15708        // Update what is removed
15709        res.removedInfo = new PackageRemovedInfo(this);
15710        res.removedInfo.uid = oldPackage.applicationInfo.uid;
15711        res.removedInfo.removedPackage = oldPackage.packageName;
15712        res.removedInfo.installerPackageName = ps.installerPackageName;
15713        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15714        res.removedInfo.isUpdate = true;
15715        res.removedInfo.origUsers = installedUsers;
15716        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15717        for (int i = 0; i < installedUsers.length; i++) {
15718            final int userId = installedUsers[i];
15719            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15720        }
15721
15722        final int childCount = (oldPackage.childPackages != null)
15723                ? oldPackage.childPackages.size() : 0;
15724        for (int i = 0; i < childCount; i++) {
15725            boolean childPackageUpdated = false;
15726            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15727            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15728            if (res.addedChildPackages != null) {
15729                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15730                if (childRes != null) {
15731                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15732                    childRes.removedInfo.removedPackage = childPkg.packageName;
15733                    if (childPs != null) {
15734                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
15735                    }
15736                    childRes.removedInfo.isUpdate = true;
15737                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15738                    childPackageUpdated = true;
15739                }
15740            }
15741            if (!childPackageUpdated) {
15742                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
15743                childRemovedRes.removedPackage = childPkg.packageName;
15744                if (childPs != null) {
15745                    childRemovedRes.installerPackageName = childPs.installerPackageName;
15746                }
15747                childRemovedRes.isUpdate = false;
15748                childRemovedRes.dataRemoved = true;
15749                synchronized (mPackages) {
15750                    if (childPs != null) {
15751                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15752                    }
15753                }
15754                if (res.removedInfo.removedChildPackages == null) {
15755                    res.removedInfo.removedChildPackages = new ArrayMap<>();
15756                }
15757                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15758            }
15759        }
15760
15761        boolean sysPkg = (isSystemApp(oldPackage));
15762        if (sysPkg) {
15763            // Set the system/privileged/oem/vendor flags as needed
15764            final boolean privileged =
15765                    (oldPackage.applicationInfo.privateFlags
15766                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15767            final boolean oem =
15768                    (oldPackage.applicationInfo.privateFlags
15769                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
15770            final boolean vendor =
15771                    (oldPackage.applicationInfo.privateFlags
15772                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
15773            final @ParseFlags int systemParseFlags = parseFlags;
15774            final @ScanFlags int systemScanFlags = scanFlags
15775                    | SCAN_AS_SYSTEM
15776                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
15777                    | (oem ? SCAN_AS_OEM : 0)
15778                    | (vendor ? SCAN_AS_VENDOR : 0);
15779
15780            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
15781                    user, allUsers, installerPackageName, res, installReason);
15782        } else {
15783            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
15784                    user, allUsers, installerPackageName, res, installReason);
15785        }
15786    }
15787
15788    @Override
15789    public List<String> getPreviousCodePaths(String packageName) {
15790        final int callingUid = Binder.getCallingUid();
15791        final List<String> result = new ArrayList<>();
15792        if (getInstantAppPackageName(callingUid) != null) {
15793            return result;
15794        }
15795        final PackageSetting ps = mSettings.mPackages.get(packageName);
15796        if (ps != null
15797                && ps.oldCodePaths != null
15798                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15799            result.addAll(ps.oldCodePaths);
15800        }
15801        return result;
15802    }
15803
15804    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15805            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15806            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
15807            String installerPackageName, PackageInstalledInfo res, int installReason) {
15808        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15809                + deletedPackage);
15810
15811        String pkgName = deletedPackage.packageName;
15812        boolean deletedPkg = true;
15813        boolean addedPkg = false;
15814        boolean updatedSettings = false;
15815        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15816        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15817                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15818
15819        final long origUpdateTime = (pkg.mExtras != null)
15820                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15821
15822        // First delete the existing package while retaining the data directory
15823        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15824                res.removedInfo, true, pkg)) {
15825            // If the existing package wasn't successfully deleted
15826            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15827            deletedPkg = false;
15828        } else {
15829            // Successfully deleted the old package; proceed with replace.
15830
15831            // If deleted package lived in a container, give users a chance to
15832            // relinquish resources before killing.
15833            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
15834                if (DEBUG_INSTALL) {
15835                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
15836                }
15837                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
15838                final ArrayList<String> pkgList = new ArrayList<String>(1);
15839                pkgList.add(deletedPackage.applicationInfo.packageName);
15840                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
15841            }
15842
15843            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15844                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15845            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15846
15847            try {
15848                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
15849                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
15850                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15851                        installReason);
15852
15853                // Update the in-memory copy of the previous code paths.
15854                PackageSetting ps = mSettings.mPackages.get(pkgName);
15855                if (!killApp) {
15856                    if (ps.oldCodePaths == null) {
15857                        ps.oldCodePaths = new ArraySet<>();
15858                    }
15859                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
15860                    if (deletedPackage.splitCodePaths != null) {
15861                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
15862                    }
15863                } else {
15864                    ps.oldCodePaths = null;
15865                }
15866                if (ps.childPackageNames != null) {
15867                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
15868                        final String childPkgName = ps.childPackageNames.get(i);
15869                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
15870                        childPs.oldCodePaths = ps.oldCodePaths;
15871                    }
15872                }
15873                // set instant app status, but, only if it's explicitly specified
15874                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15875                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
15876                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
15877                prepareAppDataAfterInstallLIF(newPackage);
15878                addedPkg = true;
15879                mDexManager.notifyPackageUpdated(newPackage.packageName,
15880                        newPackage.baseCodePath, newPackage.splitCodePaths);
15881            } catch (PackageManagerException e) {
15882                res.setError("Package couldn't be installed in " + pkg.codePath, e);
15883            }
15884        }
15885
15886        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15887            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
15888
15889            // Revert all internal state mutations and added folders for the failed install
15890            if (addedPkg) {
15891                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15892                        res.removedInfo, true, null);
15893            }
15894
15895            // Restore the old package
15896            if (deletedPkg) {
15897                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
15898                File restoreFile = new File(deletedPackage.codePath);
15899                // Parse old package
15900                boolean oldExternal = isExternal(deletedPackage);
15901                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
15902                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
15903                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
15904                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
15905                try {
15906                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
15907                            null);
15908                } catch (PackageManagerException e) {
15909                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
15910                            + e.getMessage());
15911                    return;
15912                }
15913
15914                synchronized (mPackages) {
15915                    // Ensure the installer package name up to date
15916                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
15917
15918                    // Update permissions for restored package
15919                    mPermissionManager.updatePermissions(
15920                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
15921                            mPermissionCallback);
15922
15923                    mSettings.writeLPr();
15924                }
15925
15926                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
15927            }
15928        } else {
15929            synchronized (mPackages) {
15930                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
15931                if (ps != null) {
15932                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
15933                    if (res.removedInfo.removedChildPackages != null) {
15934                        final int childCount = res.removedInfo.removedChildPackages.size();
15935                        // Iterate in reverse as we may modify the collection
15936                        for (int i = childCount - 1; i >= 0; i--) {
15937                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
15938                            if (res.addedChildPackages.containsKey(childPackageName)) {
15939                                res.removedInfo.removedChildPackages.removeAt(i);
15940                            } else {
15941                                PackageRemovedInfo childInfo = res.removedInfo
15942                                        .removedChildPackages.valueAt(i);
15943                                childInfo.removedForAllUsers = mPackages.get(
15944                                        childInfo.removedPackage) == null;
15945                            }
15946                        }
15947                    }
15948                }
15949            }
15950        }
15951    }
15952
15953    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
15954            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15955            final @ScanFlags int scanFlags, UserHandle user,
15956            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
15957            int installReason) {
15958        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
15959                + ", old=" + deletedPackage);
15960
15961        final boolean disabledSystem;
15962
15963        // Remove existing system package
15964        removePackageLI(deletedPackage, true);
15965
15966        synchronized (mPackages) {
15967            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
15968        }
15969        if (!disabledSystem) {
15970            // We didn't need to disable the .apk as a current system package,
15971            // which means we are replacing another update that is already
15972            // installed.  We need to make sure to delete the older one's .apk.
15973            res.removedInfo.args = createInstallArgsForExisting(0,
15974                    deletedPackage.applicationInfo.getCodePath(),
15975                    deletedPackage.applicationInfo.getResourcePath(),
15976                    getAppDexInstructionSets(deletedPackage.applicationInfo));
15977        } else {
15978            res.removedInfo.args = null;
15979        }
15980
15981        // Successfully disabled the old package. Now proceed with re-installation
15982        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15983                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15984        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15985
15986        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15987        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
15988                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
15989
15990        PackageParser.Package newPackage = null;
15991        try {
15992            // Add the package to the internal data structures
15993            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
15994
15995            // Set the update and install times
15996            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
15997            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
15998                    System.currentTimeMillis());
15999
16000            // Update the package dynamic state if succeeded
16001            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16002                // Now that the install succeeded make sure we remove data
16003                // directories for any child package the update removed.
16004                final int deletedChildCount = (deletedPackage.childPackages != null)
16005                        ? deletedPackage.childPackages.size() : 0;
16006                final int newChildCount = (newPackage.childPackages != null)
16007                        ? newPackage.childPackages.size() : 0;
16008                for (int i = 0; i < deletedChildCount; i++) {
16009                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16010                    boolean childPackageDeleted = true;
16011                    for (int j = 0; j < newChildCount; j++) {
16012                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16013                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16014                            childPackageDeleted = false;
16015                            break;
16016                        }
16017                    }
16018                    if (childPackageDeleted) {
16019                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16020                                deletedChildPkg.packageName);
16021                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16022                            PackageRemovedInfo removedChildRes = res.removedInfo
16023                                    .removedChildPackages.get(deletedChildPkg.packageName);
16024                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16025                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16026                        }
16027                    }
16028                }
16029
16030                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16031                        installReason);
16032                prepareAppDataAfterInstallLIF(newPackage);
16033
16034                mDexManager.notifyPackageUpdated(newPackage.packageName,
16035                            newPackage.baseCodePath, newPackage.splitCodePaths);
16036            }
16037        } catch (PackageManagerException e) {
16038            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16039            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16040        }
16041
16042        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16043            // Re installation failed. Restore old information
16044            // Remove new pkg information
16045            if (newPackage != null) {
16046                removeInstalledPackageLI(newPackage, true);
16047            }
16048            // Add back the old system package
16049            try {
16050                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16051            } catch (PackageManagerException e) {
16052                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16053            }
16054
16055            synchronized (mPackages) {
16056                if (disabledSystem) {
16057                    enableSystemPackageLPw(deletedPackage);
16058                }
16059
16060                // Ensure the installer package name up to date
16061                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16062
16063                // Update permissions for restored package
16064                mPermissionManager.updatePermissions(
16065                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16066                        mPermissionCallback);
16067
16068                mSettings.writeLPr();
16069            }
16070
16071            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16072                    + " after failed upgrade");
16073        }
16074    }
16075
16076    /**
16077     * Checks whether the parent or any of the child packages have a change shared
16078     * user. For a package to be a valid update the shred users of the parent and
16079     * the children should match. We may later support changing child shared users.
16080     * @param oldPkg The updated package.
16081     * @param newPkg The update package.
16082     * @return The shared user that change between the versions.
16083     */
16084    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16085            PackageParser.Package newPkg) {
16086        // Check parent shared user
16087        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16088            return newPkg.packageName;
16089        }
16090        // Check child shared users
16091        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16092        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16093        for (int i = 0; i < newChildCount; i++) {
16094            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16095            // If this child was present, did it have the same shared user?
16096            for (int j = 0; j < oldChildCount; j++) {
16097                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16098                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16099                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16100                    return newChildPkg.packageName;
16101                }
16102            }
16103        }
16104        return null;
16105    }
16106
16107    private void removeNativeBinariesLI(PackageSetting ps) {
16108        // Remove the lib path for the parent package
16109        if (ps != null) {
16110            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16111            // Remove the lib path for the child packages
16112            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16113            for (int i = 0; i < childCount; i++) {
16114                PackageSetting childPs = null;
16115                synchronized (mPackages) {
16116                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16117                }
16118                if (childPs != null) {
16119                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16120                            .legacyNativeLibraryPathString);
16121                }
16122            }
16123        }
16124    }
16125
16126    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16127        // Enable the parent package
16128        mSettings.enableSystemPackageLPw(pkg.packageName);
16129        // Enable the child packages
16130        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16131        for (int i = 0; i < childCount; i++) {
16132            PackageParser.Package childPkg = pkg.childPackages.get(i);
16133            mSettings.enableSystemPackageLPw(childPkg.packageName);
16134        }
16135    }
16136
16137    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16138            PackageParser.Package newPkg) {
16139        // Disable the parent package (parent always replaced)
16140        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16141        // Disable the child packages
16142        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16143        for (int i = 0; i < childCount; i++) {
16144            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16145            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16146            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16147        }
16148        return disabled;
16149    }
16150
16151    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16152            String installerPackageName) {
16153        // Enable the parent package
16154        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16155        // Enable the child packages
16156        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16157        for (int i = 0; i < childCount; i++) {
16158            PackageParser.Package childPkg = pkg.childPackages.get(i);
16159            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16160        }
16161    }
16162
16163    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16164            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16165        // Update the parent package setting
16166        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16167                res, user, installReason);
16168        // Update the child packages setting
16169        final int childCount = (newPackage.childPackages != null)
16170                ? newPackage.childPackages.size() : 0;
16171        for (int i = 0; i < childCount; i++) {
16172            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16173            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16174            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16175                    childRes.origUsers, childRes, user, installReason);
16176        }
16177    }
16178
16179    private void updateSettingsInternalLI(PackageParser.Package pkg,
16180            String installerPackageName, int[] allUsers, int[] installedForUsers,
16181            PackageInstalledInfo res, UserHandle user, int installReason) {
16182        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16183
16184        String pkgName = pkg.packageName;
16185        synchronized (mPackages) {
16186            //write settings. the installStatus will be incomplete at this stage.
16187            //note that the new package setting would have already been
16188            //added to mPackages. It hasn't been persisted yet.
16189            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16190            // TODO: Remove this write? It's also written at the end of this method
16191            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16192            mSettings.writeLPr();
16193            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16194        }
16195
16196        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16197        synchronized (mPackages) {
16198// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16199            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16200                    mPermissionCallback);
16201            // For system-bundled packages, we assume that installing an upgraded version
16202            // of the package implies that the user actually wants to run that new code,
16203            // so we enable the package.
16204            PackageSetting ps = mSettings.mPackages.get(pkgName);
16205            final int userId = user.getIdentifier();
16206            if (ps != null) {
16207                if (isSystemApp(pkg)) {
16208                    if (DEBUG_INSTALL) {
16209                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16210                    }
16211                    // Enable system package for requested users
16212                    if (res.origUsers != null) {
16213                        for (int origUserId : res.origUsers) {
16214                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16215                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16216                                        origUserId, installerPackageName);
16217                            }
16218                        }
16219                    }
16220                    // Also convey the prior install/uninstall state
16221                    if (allUsers != null && installedForUsers != null) {
16222                        for (int currentUserId : allUsers) {
16223                            final boolean installed = ArrayUtils.contains(
16224                                    installedForUsers, currentUserId);
16225                            if (DEBUG_INSTALL) {
16226                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16227                            }
16228                            ps.setInstalled(installed, currentUserId);
16229                        }
16230                        // these install state changes will be persisted in the
16231                        // upcoming call to mSettings.writeLPr().
16232                    }
16233                }
16234                // It's implied that when a user requests installation, they want the app to be
16235                // installed and enabled.
16236                if (userId != UserHandle.USER_ALL) {
16237                    ps.setInstalled(true, userId);
16238                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16239                }
16240
16241                // When replacing an existing package, preserve the original install reason for all
16242                // users that had the package installed before.
16243                final Set<Integer> previousUserIds = new ArraySet<>();
16244                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16245                    final int installReasonCount = res.removedInfo.installReasons.size();
16246                    for (int i = 0; i < installReasonCount; i++) {
16247                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16248                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16249                        ps.setInstallReason(previousInstallReason, previousUserId);
16250                        previousUserIds.add(previousUserId);
16251                    }
16252                }
16253
16254                // Set install reason for users that are having the package newly installed.
16255                if (userId == UserHandle.USER_ALL) {
16256                    for (int currentUserId : sUserManager.getUserIds()) {
16257                        if (!previousUserIds.contains(currentUserId)) {
16258                            ps.setInstallReason(installReason, currentUserId);
16259                        }
16260                    }
16261                } else if (!previousUserIds.contains(userId)) {
16262                    ps.setInstallReason(installReason, userId);
16263                }
16264                mSettings.writeKernelMappingLPr(ps);
16265            }
16266            res.name = pkgName;
16267            res.uid = pkg.applicationInfo.uid;
16268            res.pkg = pkg;
16269            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16270            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16271            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16272            //to update install status
16273            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16274            mSettings.writeLPr();
16275            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16276        }
16277
16278        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16279    }
16280
16281    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16282        try {
16283            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16284            installPackageLI(args, res);
16285        } finally {
16286            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16287        }
16288    }
16289
16290    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16291        final int installFlags = args.installFlags;
16292        final String installerPackageName = args.installerPackageName;
16293        final String volumeUuid = args.volumeUuid;
16294        final File tmpPackageFile = new File(args.getCodePath());
16295        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16296        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16297                || (args.volumeUuid != null));
16298        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16299        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16300        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16301        final boolean virtualPreload =
16302                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16303        boolean replace = false;
16304        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16305        if (args.move != null) {
16306            // moving a complete application; perform an initial scan on the new install location
16307            scanFlags |= SCAN_INITIAL;
16308        }
16309        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16310            scanFlags |= SCAN_DONT_KILL_APP;
16311        }
16312        if (instantApp) {
16313            scanFlags |= SCAN_AS_INSTANT_APP;
16314        }
16315        if (fullApp) {
16316            scanFlags |= SCAN_AS_FULL_APP;
16317        }
16318        if (virtualPreload) {
16319            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16320        }
16321
16322        // Result object to be returned
16323        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16324        res.installerPackageName = installerPackageName;
16325
16326        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16327
16328        // Sanity check
16329        if (instantApp && (forwardLocked || onExternal)) {
16330            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16331                    + " external=" + onExternal);
16332            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16333            return;
16334        }
16335
16336        // Retrieve PackageSettings and parse package
16337        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16338                | PackageParser.PARSE_ENFORCE_CODE
16339                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16340                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16341                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16342                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16343        PackageParser pp = new PackageParser();
16344        pp.setSeparateProcesses(mSeparateProcesses);
16345        pp.setDisplayMetrics(mMetrics);
16346        pp.setCallback(mPackageParserCallback);
16347
16348        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16349        final PackageParser.Package pkg;
16350        try {
16351            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16352        } catch (PackageParserException e) {
16353            res.setError("Failed parse during installPackageLI", e);
16354            return;
16355        } finally {
16356            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16357        }
16358
16359        // App targetSdkVersion is below min supported version
16360        if (!forceSdk && pkg.applicationInfo.isTargetingDeprecatedSdkVersion()) {
16361            Slog.w(TAG, "App " + pkg.packageName + " targets deprecated sdk");
16362
16363            res.setError(INSTALL_FAILED_NEWER_SDK,
16364                    "App is targeting deprecated sdk (targetSdkVersion should be at least "
16365                    + Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT + ").");
16366            return;
16367        }
16368
16369        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16370        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16371            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
16372            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16373                    "Instant app package must target O");
16374            return;
16375        }
16376        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16377            Slog.w(TAG, "Instant app package " + pkg.packageName
16378                    + " does not target targetSandboxVersion 2");
16379            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16380                    "Instant app package must use targetSanboxVersion 2");
16381            return;
16382        }
16383
16384        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16385            // Static shared libraries have synthetic package names
16386            renameStaticSharedLibraryPackage(pkg);
16387
16388            // No static shared libs on external storage
16389            if (onExternal) {
16390                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16391                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16392                        "Packages declaring static-shared libs cannot be updated");
16393                return;
16394            }
16395        }
16396
16397        // If we are installing a clustered package add results for the children
16398        if (pkg.childPackages != null) {
16399            synchronized (mPackages) {
16400                final int childCount = pkg.childPackages.size();
16401                for (int i = 0; i < childCount; i++) {
16402                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16403                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16404                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16405                    childRes.pkg = childPkg;
16406                    childRes.name = childPkg.packageName;
16407                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16408                    if (childPs != null) {
16409                        childRes.origUsers = childPs.queryInstalledUsers(
16410                                sUserManager.getUserIds(), true);
16411                    }
16412                    if ((mPackages.containsKey(childPkg.packageName))) {
16413                        childRes.removedInfo = new PackageRemovedInfo(this);
16414                        childRes.removedInfo.removedPackage = childPkg.packageName;
16415                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16416                    }
16417                    if (res.addedChildPackages == null) {
16418                        res.addedChildPackages = new ArrayMap<>();
16419                    }
16420                    res.addedChildPackages.put(childPkg.packageName, childRes);
16421                }
16422            }
16423        }
16424
16425        // If package doesn't declare API override, mark that we have an install
16426        // time CPU ABI override.
16427        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16428            pkg.cpuAbiOverride = args.abiOverride;
16429        }
16430
16431        String pkgName = res.name = pkg.packageName;
16432        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16433            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16434                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16435                return;
16436            }
16437        }
16438
16439        try {
16440            // either use what we've been given or parse directly from the APK
16441            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16442                pkg.setSigningDetails(args.signingDetails);
16443            } else {
16444                PackageParser.collectCertificates(pkg, parseFlags);
16445            }
16446        } catch (PackageParserException e) {
16447            res.setError("Failed collect during installPackageLI", e);
16448            return;
16449        }
16450
16451        // Get rid of all references to package scan path via parser.
16452        pp = null;
16453        String oldCodePath = null;
16454        boolean systemApp = false;
16455        synchronized (mPackages) {
16456            // Check if installing already existing package
16457            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16458                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16459                if (pkg.mOriginalPackages != null
16460                        && pkg.mOriginalPackages.contains(oldName)
16461                        && mPackages.containsKey(oldName)) {
16462                    // This package is derived from an original package,
16463                    // and this device has been updating from that original
16464                    // name.  We must continue using the original name, so
16465                    // rename the new package here.
16466                    pkg.setPackageName(oldName);
16467                    pkgName = pkg.packageName;
16468                    replace = true;
16469                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16470                            + oldName + " pkgName=" + pkgName);
16471                } else if (mPackages.containsKey(pkgName)) {
16472                    // This package, under its official name, already exists
16473                    // on the device; we should replace it.
16474                    replace = true;
16475                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16476                }
16477
16478                // Child packages are installed through the parent package
16479                if (pkg.parentPackage != null) {
16480                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16481                            "Package " + pkg.packageName + " is child of package "
16482                                    + pkg.parentPackage.parentPackage + ". Child packages "
16483                                    + "can be updated only through the parent package.");
16484                    return;
16485                }
16486
16487                if (replace) {
16488                    // Prevent apps opting out from runtime permissions
16489                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16490                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16491                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16492                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16493                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16494                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16495                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16496                                        + " doesn't support runtime permissions but the old"
16497                                        + " target SDK " + oldTargetSdk + " does.");
16498                        return;
16499                    }
16500                    // Prevent persistent apps from being updated
16501                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16502                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16503                                "Package " + oldPackage.packageName + " is a persistent app. "
16504                                        + "Persistent apps are not updateable.");
16505                        return;
16506                    }
16507                    // Prevent apps from downgrading their targetSandbox.
16508                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16509                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16510                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16511                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16512                                "Package " + pkg.packageName + " new target sandbox "
16513                                + newTargetSandbox + " is incompatible with the previous value of"
16514                                + oldTargetSandbox + ".");
16515                        return;
16516                    }
16517
16518                    // Prevent installing of child packages
16519                    if (oldPackage.parentPackage != null) {
16520                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16521                                "Package " + pkg.packageName + " is child of package "
16522                                        + oldPackage.parentPackage + ". Child packages "
16523                                        + "can be updated only through the parent package.");
16524                        return;
16525                    }
16526                }
16527            }
16528
16529            PackageSetting ps = mSettings.mPackages.get(pkgName);
16530            if (ps != null) {
16531                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16532
16533                // Static shared libs have same package with different versions where
16534                // we internally use a synthetic package name to allow multiple versions
16535                // of the same package, therefore we need to compare signatures against
16536                // the package setting for the latest library version.
16537                PackageSetting signatureCheckPs = ps;
16538                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16539                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16540                    if (libraryEntry != null) {
16541                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16542                    }
16543                }
16544
16545                // Quick sanity check that we're signed correctly if updating;
16546                // we'll check this again later when scanning, but we want to
16547                // bail early here before tripping over redefined permissions.
16548                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16549                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16550                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16551                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16552                                + pkg.packageName + " upgrade keys do not match the "
16553                                + "previously installed version");
16554                        return;
16555                    }
16556                } else {
16557                    try {
16558                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16559                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16560                        final boolean compatMatch = verifySignatures(
16561                                signatureCheckPs, pkg.mSigningDetails, compareCompat,
16562                                compareRecover);
16563                        // The new KeySets will be re-added later in the scanning process.
16564                        if (compatMatch) {
16565                            synchronized (mPackages) {
16566                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16567                            }
16568                        }
16569                    } catch (PackageManagerException e) {
16570                        res.setError(e.error, e.getMessage());
16571                        return;
16572                    }
16573                }
16574
16575                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16576                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16577                    systemApp = (ps.pkg.applicationInfo.flags &
16578                            ApplicationInfo.FLAG_SYSTEM) != 0;
16579                }
16580                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16581            }
16582
16583            int N = pkg.permissions.size();
16584            for (int i = N-1; i >= 0; i--) {
16585                final PackageParser.Permission perm = pkg.permissions.get(i);
16586                final BasePermission bp =
16587                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
16588
16589                // Don't allow anyone but the system to define ephemeral permissions.
16590                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16591                        && !systemApp) {
16592                    Slog.w(TAG, "Non-System package " + pkg.packageName
16593                            + " attempting to delcare ephemeral permission "
16594                            + perm.info.name + "; Removing ephemeral.");
16595                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
16596                }
16597
16598                // Check whether the newly-scanned package wants to define an already-defined perm
16599                if (bp != null) {
16600                    // If the defining package is signed with our cert, it's okay.  This
16601                    // also includes the "updating the same package" case, of course.
16602                    // "updating same package" could also involve key-rotation.
16603                    final boolean sigsOk;
16604                    final String sourcePackageName = bp.getSourcePackageName();
16605                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16606                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16607                    if (sourcePackageName.equals(pkg.packageName)
16608                            && (ksms.shouldCheckUpgradeKeySetLocked(
16609                                    sourcePackageSetting, scanFlags))) {
16610                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
16611                    } else {
16612                        sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
16613                                pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH;
16614                    }
16615                    if (!sigsOk) {
16616                        // If the owning package is the system itself, we log but allow
16617                        // install to proceed; we fail the install on all other permission
16618                        // redefinitions.
16619                        if (!sourcePackageName.equals("android")) {
16620                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16621                                    + pkg.packageName + " attempting to redeclare permission "
16622                                    + perm.info.name + " already owned by " + sourcePackageName);
16623                            res.origPermission = perm.info.name;
16624                            res.origPackage = sourcePackageName;
16625                            return;
16626                        } else {
16627                            Slog.w(TAG, "Package " + pkg.packageName
16628                                    + " attempting to redeclare system permission "
16629                                    + perm.info.name + "; ignoring new declaration");
16630                            pkg.permissions.remove(i);
16631                        }
16632                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16633                        // Prevent apps to change protection level to dangerous from any other
16634                        // type as this would allow a privilege escalation where an app adds a
16635                        // normal/signature permission in other app's group and later redefines
16636                        // it as dangerous leading to the group auto-grant.
16637                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16638                                == PermissionInfo.PROTECTION_DANGEROUS) {
16639                            if (bp != null && !bp.isRuntime()) {
16640                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16641                                        + "non-runtime permission " + perm.info.name
16642                                        + " to runtime; keeping old protection level");
16643                                perm.info.protectionLevel = bp.getProtectionLevel();
16644                            }
16645                        }
16646                    }
16647                }
16648            }
16649        }
16650
16651        if (systemApp) {
16652            if (onExternal) {
16653                // Abort update; system app can't be replaced with app on sdcard
16654                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16655                        "Cannot install updates to system apps on sdcard");
16656                return;
16657            } else if (instantApp) {
16658                // Abort update; system app can't be replaced with an instant app
16659                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16660                        "Cannot update a system app with an instant app");
16661                return;
16662            }
16663        }
16664
16665        if (args.move != null) {
16666            // We did an in-place move, so dex is ready to roll
16667            scanFlags |= SCAN_NO_DEX;
16668            scanFlags |= SCAN_MOVE;
16669
16670            synchronized (mPackages) {
16671                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16672                if (ps == null) {
16673                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16674                            "Missing settings for moved package " + pkgName);
16675                }
16676
16677                // We moved the entire application as-is, so bring over the
16678                // previously derived ABI information.
16679                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16680                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16681            }
16682
16683        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16684            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16685            scanFlags |= SCAN_NO_DEX;
16686
16687            try {
16688                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16689                    args.abiOverride : pkg.cpuAbiOverride);
16690                final boolean extractNativeLibs = !pkg.isLibrary();
16691                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
16692            } catch (PackageManagerException pme) {
16693                Slog.e(TAG, "Error deriving application ABI", pme);
16694                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16695                return;
16696            }
16697
16698            // Shared libraries for the package need to be updated.
16699            synchronized (mPackages) {
16700                try {
16701                    updateSharedLibrariesLPr(pkg, null);
16702                } catch (PackageManagerException e) {
16703                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16704                }
16705            }
16706        }
16707
16708        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16709            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16710            return;
16711        }
16712
16713        if (!instantApp) {
16714            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16715        } else {
16716            if (DEBUG_DOMAIN_VERIFICATION) {
16717                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16718            }
16719        }
16720
16721        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16722                "installPackageLI")) {
16723            if (replace) {
16724                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16725                    // Static libs have a synthetic package name containing the version
16726                    // and cannot be updated as an update would get a new package name,
16727                    // unless this is the exact same version code which is useful for
16728                    // development.
16729                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16730                    if (existingPkg != null &&
16731                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
16732                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16733                                + "static-shared libs cannot be updated");
16734                        return;
16735                    }
16736                }
16737                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
16738                        installerPackageName, res, args.installReason);
16739            } else {
16740                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16741                        args.user, installerPackageName, volumeUuid, res, args.installReason);
16742            }
16743        }
16744
16745        // Check whether we need to dexopt the app.
16746        //
16747        // NOTE: it is IMPORTANT to call dexopt:
16748        //   - after doRename which will sync the package data from PackageParser.Package and its
16749        //     corresponding ApplicationInfo.
16750        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
16751        //     uid of the application (pkg.applicationInfo.uid).
16752        //     This update happens in place!
16753        //
16754        // We only need to dexopt if the package meets ALL of the following conditions:
16755        //   1) it is not forward locked.
16756        //   2) it is not on on an external ASEC container.
16757        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
16758        //
16759        // Note that we do not dexopt instant apps by default. dexopt can take some time to
16760        // complete, so we skip this step during installation. Instead, we'll take extra time
16761        // the first time the instant app starts. It's preferred to do it this way to provide
16762        // continuous progress to the useur instead of mysteriously blocking somewhere in the
16763        // middle of running an instant app. The default behaviour can be overridden
16764        // via gservices.
16765        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
16766                && !forwardLocked
16767                && !pkg.applicationInfo.isExternalAsec()
16768                && (!instantApp || Global.getInt(mContext.getContentResolver(),
16769                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
16770
16771        if (performDexopt) {
16772            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16773            // Do not run PackageDexOptimizer through the local performDexOpt
16774            // method because `pkg` may not be in `mPackages` yet.
16775            //
16776            // Also, don't fail application installs if the dexopt step fails.
16777            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
16778                    REASON_INSTALL,
16779                    DexoptOptions.DEXOPT_BOOT_COMPLETE);
16780            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16781                    null /* instructionSets */,
16782                    getOrCreateCompilerPackageStats(pkg),
16783                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
16784                    dexoptOptions);
16785            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16786        }
16787
16788        // Notify BackgroundDexOptService that the package has been changed.
16789        // If this is an update of a package which used to fail to compile,
16790        // BackgroundDexOptService will remove it from its blacklist.
16791        // TODO: Layering violation
16792        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
16793
16794        synchronized (mPackages) {
16795            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16796            if (ps != null) {
16797                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16798                ps.setUpdateAvailable(false /*updateAvailable*/);
16799            }
16800
16801            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16802            for (int i = 0; i < childCount; i++) {
16803                PackageParser.Package childPkg = pkg.childPackages.get(i);
16804                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16805                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16806                if (childPs != null) {
16807                    childRes.newUsers = childPs.queryInstalledUsers(
16808                            sUserManager.getUserIds(), true);
16809                }
16810            }
16811
16812            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16813                updateSequenceNumberLP(ps, res.newUsers);
16814                updateInstantAppInstallerLocked(pkgName);
16815            }
16816        }
16817    }
16818
16819    private void startIntentFilterVerifications(int userId, boolean replacing,
16820            PackageParser.Package pkg) {
16821        if (mIntentFilterVerifierComponent == null) {
16822            Slog.w(TAG, "No IntentFilter verification will not be done as "
16823                    + "there is no IntentFilterVerifier available!");
16824            return;
16825        }
16826
16827        final int verifierUid = getPackageUid(
16828                mIntentFilterVerifierComponent.getPackageName(),
16829                MATCH_DEBUG_TRIAGED_MISSING,
16830                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
16831
16832        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16833        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
16834        mHandler.sendMessage(msg);
16835
16836        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16837        for (int i = 0; i < childCount; i++) {
16838            PackageParser.Package childPkg = pkg.childPackages.get(i);
16839            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16840            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
16841            mHandler.sendMessage(msg);
16842        }
16843    }
16844
16845    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
16846            PackageParser.Package pkg) {
16847        int size = pkg.activities.size();
16848        if (size == 0) {
16849            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16850                    "No activity, so no need to verify any IntentFilter!");
16851            return;
16852        }
16853
16854        final boolean hasDomainURLs = hasDomainURLs(pkg);
16855        if (!hasDomainURLs) {
16856            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16857                    "No domain URLs, so no need to verify any IntentFilter!");
16858            return;
16859        }
16860
16861        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
16862                + " if any IntentFilter from the " + size
16863                + " Activities needs verification ...");
16864
16865        int count = 0;
16866        final String packageName = pkg.packageName;
16867
16868        synchronized (mPackages) {
16869            // If this is a new install and we see that we've already run verification for this
16870            // package, we have nothing to do: it means the state was restored from backup.
16871            if (!replacing) {
16872                IntentFilterVerificationInfo ivi =
16873                        mSettings.getIntentFilterVerificationLPr(packageName);
16874                if (ivi != null) {
16875                    if (DEBUG_DOMAIN_VERIFICATION) {
16876                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
16877                                + ivi.getStatusString());
16878                    }
16879                    return;
16880                }
16881            }
16882
16883            // If any filters need to be verified, then all need to be.
16884            boolean needToVerify = false;
16885            for (PackageParser.Activity a : pkg.activities) {
16886                for (ActivityIntentInfo filter : a.intents) {
16887                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
16888                        if (DEBUG_DOMAIN_VERIFICATION) {
16889                            Slog.d(TAG,
16890                                    "Intent filter needs verification, so processing all filters");
16891                        }
16892                        needToVerify = true;
16893                        break;
16894                    }
16895                }
16896            }
16897
16898            if (needToVerify) {
16899                final int verificationId = mIntentFilterVerificationToken++;
16900                for (PackageParser.Activity a : pkg.activities) {
16901                    for (ActivityIntentInfo filter : a.intents) {
16902                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
16903                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16904                                    "Verification needed for IntentFilter:" + filter.toString());
16905                            mIntentFilterVerifier.addOneIntentFilterVerification(
16906                                    verifierUid, userId, verificationId, filter, packageName);
16907                            count++;
16908                        }
16909                    }
16910                }
16911            }
16912        }
16913
16914        if (count > 0) {
16915            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
16916                    + " IntentFilter verification" + (count > 1 ? "s" : "")
16917                    +  " for userId:" + userId);
16918            mIntentFilterVerifier.startVerifications(userId);
16919        } else {
16920            if (DEBUG_DOMAIN_VERIFICATION) {
16921                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
16922            }
16923        }
16924    }
16925
16926    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
16927        final ComponentName cn  = filter.activity.getComponentName();
16928        final String packageName = cn.getPackageName();
16929
16930        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
16931                packageName);
16932        if (ivi == null) {
16933            return true;
16934        }
16935        int status = ivi.getStatus();
16936        switch (status) {
16937            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
16938            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
16939                return true;
16940
16941            default:
16942                // Nothing to do
16943                return false;
16944        }
16945    }
16946
16947    private static boolean isMultiArch(ApplicationInfo info) {
16948        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
16949    }
16950
16951    private static boolean isExternal(PackageParser.Package pkg) {
16952        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16953    }
16954
16955    private static boolean isExternal(PackageSetting ps) {
16956        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16957    }
16958
16959    private static boolean isSystemApp(PackageParser.Package pkg) {
16960        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
16961    }
16962
16963    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
16964        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16965    }
16966
16967    private static boolean isOemApp(PackageParser.Package pkg) {
16968        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16969    }
16970
16971    private static boolean isVendorApp(PackageParser.Package pkg) {
16972        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16973    }
16974
16975    private static boolean hasDomainURLs(PackageParser.Package pkg) {
16976        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
16977    }
16978
16979    private static boolean isSystemApp(PackageSetting ps) {
16980        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
16981    }
16982
16983    private static boolean isUpdatedSystemApp(PackageSetting ps) {
16984        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
16985    }
16986
16987    private int packageFlagsToInstallFlags(PackageSetting ps) {
16988        int installFlags = 0;
16989        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
16990            // This existing package was an external ASEC install when we have
16991            // the external flag without a UUID
16992            installFlags |= PackageManager.INSTALL_EXTERNAL;
16993        }
16994        if (ps.isForwardLocked()) {
16995            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
16996        }
16997        return installFlags;
16998    }
16999
17000    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17001        if (isExternal(pkg)) {
17002            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17003                return mSettings.getExternalVersion();
17004            } else {
17005                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17006            }
17007        } else {
17008            return mSettings.getInternalVersion();
17009        }
17010    }
17011
17012    private void deleteTempPackageFiles() {
17013        final FilenameFilter filter = new FilenameFilter() {
17014            public boolean accept(File dir, String name) {
17015                return name.startsWith("vmdl") && name.endsWith(".tmp");
17016            }
17017        };
17018        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17019            file.delete();
17020        }
17021    }
17022
17023    @Override
17024    public void deletePackageAsUser(String packageName, int versionCode,
17025            IPackageDeleteObserver observer, int userId, int flags) {
17026        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17027                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17028    }
17029
17030    @Override
17031    public void deletePackageVersioned(VersionedPackage versionedPackage,
17032            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17033        final int callingUid = Binder.getCallingUid();
17034        mContext.enforceCallingOrSelfPermission(
17035                android.Manifest.permission.DELETE_PACKAGES, null);
17036        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17037        Preconditions.checkNotNull(versionedPackage);
17038        Preconditions.checkNotNull(observer);
17039        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17040                PackageManager.VERSION_CODE_HIGHEST,
17041                Long.MAX_VALUE, "versionCode must be >= -1");
17042
17043        final String packageName = versionedPackage.getPackageName();
17044        final long versionCode = versionedPackage.getLongVersionCode();
17045        final String internalPackageName;
17046        synchronized (mPackages) {
17047            // Normalize package name to handle renamed packages and static libs
17048            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17049        }
17050
17051        final int uid = Binder.getCallingUid();
17052        if (!isOrphaned(internalPackageName)
17053                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17054            try {
17055                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17056                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17057                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17058                observer.onUserActionRequired(intent);
17059            } catch (RemoteException re) {
17060            }
17061            return;
17062        }
17063        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17064        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17065        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17066            mContext.enforceCallingOrSelfPermission(
17067                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17068                    "deletePackage for user " + userId);
17069        }
17070
17071        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17072            try {
17073                observer.onPackageDeleted(packageName,
17074                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17075            } catch (RemoteException re) {
17076            }
17077            return;
17078        }
17079
17080        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17081            try {
17082                observer.onPackageDeleted(packageName,
17083                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17084            } catch (RemoteException re) {
17085            }
17086            return;
17087        }
17088
17089        if (DEBUG_REMOVE) {
17090            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17091                    + " deleteAllUsers: " + deleteAllUsers + " version="
17092                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17093                    ? "VERSION_CODE_HIGHEST" : versionCode));
17094        }
17095        // Queue up an async operation since the package deletion may take a little while.
17096        mHandler.post(new Runnable() {
17097            public void run() {
17098                mHandler.removeCallbacks(this);
17099                int returnCode;
17100                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17101                boolean doDeletePackage = true;
17102                if (ps != null) {
17103                    final boolean targetIsInstantApp =
17104                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17105                    doDeletePackage = !targetIsInstantApp
17106                            || canViewInstantApps;
17107                }
17108                if (doDeletePackage) {
17109                    if (!deleteAllUsers) {
17110                        returnCode = deletePackageX(internalPackageName, versionCode,
17111                                userId, deleteFlags);
17112                    } else {
17113                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17114                                internalPackageName, users);
17115                        // If nobody is blocking uninstall, proceed with delete for all users
17116                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17117                            returnCode = deletePackageX(internalPackageName, versionCode,
17118                                    userId, deleteFlags);
17119                        } else {
17120                            // Otherwise uninstall individually for users with blockUninstalls=false
17121                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17122                            for (int userId : users) {
17123                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17124                                    returnCode = deletePackageX(internalPackageName, versionCode,
17125                                            userId, userFlags);
17126                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17127                                        Slog.w(TAG, "Package delete failed for user " + userId
17128                                                + ", returnCode " + returnCode);
17129                                    }
17130                                }
17131                            }
17132                            // The app has only been marked uninstalled for certain users.
17133                            // We still need to report that delete was blocked
17134                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17135                        }
17136                    }
17137                } else {
17138                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17139                }
17140                try {
17141                    observer.onPackageDeleted(packageName, returnCode, null);
17142                } catch (RemoteException e) {
17143                    Log.i(TAG, "Observer no longer exists.");
17144                } //end catch
17145            } //end run
17146        });
17147    }
17148
17149    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17150        if (pkg.staticSharedLibName != null) {
17151            return pkg.manifestPackageName;
17152        }
17153        return pkg.packageName;
17154    }
17155
17156    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17157        // Handle renamed packages
17158        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17159        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17160
17161        // Is this a static library?
17162        LongSparseArray<SharedLibraryEntry> versionedLib =
17163                mStaticLibsByDeclaringPackage.get(packageName);
17164        if (versionedLib == null || versionedLib.size() <= 0) {
17165            return packageName;
17166        }
17167
17168        // Figure out which lib versions the caller can see
17169        LongSparseLongArray versionsCallerCanSee = null;
17170        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17171        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17172                && callingAppId != Process.ROOT_UID) {
17173            versionsCallerCanSee = new LongSparseLongArray();
17174            String libName = versionedLib.valueAt(0).info.getName();
17175            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17176            if (uidPackages != null) {
17177                for (String uidPackage : uidPackages) {
17178                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17179                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17180                    if (libIdx >= 0) {
17181                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17182                        versionsCallerCanSee.append(libVersion, libVersion);
17183                    }
17184                }
17185            }
17186        }
17187
17188        // Caller can see nothing - done
17189        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17190            return packageName;
17191        }
17192
17193        // Find the version the caller can see and the app version code
17194        SharedLibraryEntry highestVersion = null;
17195        final int versionCount = versionedLib.size();
17196        for (int i = 0; i < versionCount; i++) {
17197            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17198            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17199                    libEntry.info.getLongVersion()) < 0) {
17200                continue;
17201            }
17202            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17203            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17204                if (libVersionCode == versionCode) {
17205                    return libEntry.apk;
17206                }
17207            } else if (highestVersion == null) {
17208                highestVersion = libEntry;
17209            } else if (libVersionCode  > highestVersion.info
17210                    .getDeclaringPackage().getLongVersionCode()) {
17211                highestVersion = libEntry;
17212            }
17213        }
17214
17215        if (highestVersion != null) {
17216            return highestVersion.apk;
17217        }
17218
17219        return packageName;
17220    }
17221
17222    boolean isCallerVerifier(int callingUid) {
17223        final int callingUserId = UserHandle.getUserId(callingUid);
17224        return mRequiredVerifierPackage != null &&
17225                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17226    }
17227
17228    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17229        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17230              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17231            return true;
17232        }
17233        final int callingUserId = UserHandle.getUserId(callingUid);
17234        // If the caller installed the pkgName, then allow it to silently uninstall.
17235        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17236            return true;
17237        }
17238
17239        // Allow package verifier to silently uninstall.
17240        if (mRequiredVerifierPackage != null &&
17241                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17242            return true;
17243        }
17244
17245        // Allow package uninstaller to silently uninstall.
17246        if (mRequiredUninstallerPackage != null &&
17247                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17248            return true;
17249        }
17250
17251        // Allow storage manager to silently uninstall.
17252        if (mStorageManagerPackage != null &&
17253                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17254            return true;
17255        }
17256
17257        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17258        // uninstall for device owner provisioning.
17259        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17260                == PERMISSION_GRANTED) {
17261            return true;
17262        }
17263
17264        return false;
17265    }
17266
17267    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17268        int[] result = EMPTY_INT_ARRAY;
17269        for (int userId : userIds) {
17270            if (getBlockUninstallForUser(packageName, userId)) {
17271                result = ArrayUtils.appendInt(result, userId);
17272            }
17273        }
17274        return result;
17275    }
17276
17277    @Override
17278    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17279        final int callingUid = Binder.getCallingUid();
17280        if (getInstantAppPackageName(callingUid) != null
17281                && !isCallerSameApp(packageName, callingUid)) {
17282            return false;
17283        }
17284        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17285    }
17286
17287    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17288        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17289                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17290        try {
17291            if (dpm != null) {
17292                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17293                        /* callingUserOnly =*/ false);
17294                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17295                        : deviceOwnerComponentName.getPackageName();
17296                // Does the package contains the device owner?
17297                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17298                // this check is probably not needed, since DO should be registered as a device
17299                // admin on some user too. (Original bug for this: b/17657954)
17300                if (packageName.equals(deviceOwnerPackageName)) {
17301                    return true;
17302                }
17303                // Does it contain a device admin for any user?
17304                int[] users;
17305                if (userId == UserHandle.USER_ALL) {
17306                    users = sUserManager.getUserIds();
17307                } else {
17308                    users = new int[]{userId};
17309                }
17310                for (int i = 0; i < users.length; ++i) {
17311                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17312                        return true;
17313                    }
17314                }
17315            }
17316        } catch (RemoteException e) {
17317        }
17318        return false;
17319    }
17320
17321    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17322        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17323    }
17324
17325    /**
17326     *  This method is an internal method that could be get invoked either
17327     *  to delete an installed package or to clean up a failed installation.
17328     *  After deleting an installed package, a broadcast is sent to notify any
17329     *  listeners that the package has been removed. For cleaning up a failed
17330     *  installation, the broadcast is not necessary since the package's
17331     *  installation wouldn't have sent the initial broadcast either
17332     *  The key steps in deleting a package are
17333     *  deleting the package information in internal structures like mPackages,
17334     *  deleting the packages base directories through installd
17335     *  updating mSettings to reflect current status
17336     *  persisting settings for later use
17337     *  sending a broadcast if necessary
17338     */
17339    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17340        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17341        final boolean res;
17342
17343        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17344                ? UserHandle.USER_ALL : userId;
17345
17346        if (isPackageDeviceAdmin(packageName, removeUser)) {
17347            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17348            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17349        }
17350
17351        PackageSetting uninstalledPs = null;
17352        PackageParser.Package pkg = null;
17353
17354        // for the uninstall-updates case and restricted profiles, remember the per-
17355        // user handle installed state
17356        int[] allUsers;
17357        synchronized (mPackages) {
17358            uninstalledPs = mSettings.mPackages.get(packageName);
17359            if (uninstalledPs == null) {
17360                Slog.w(TAG, "Not removing non-existent package " + packageName);
17361                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17362            }
17363
17364            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17365                    && uninstalledPs.versionCode != versionCode) {
17366                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17367                        + uninstalledPs.versionCode + " != " + versionCode);
17368                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17369            }
17370
17371            // Static shared libs can be declared by any package, so let us not
17372            // allow removing a package if it provides a lib others depend on.
17373            pkg = mPackages.get(packageName);
17374
17375            allUsers = sUserManager.getUserIds();
17376
17377            if (pkg != null && pkg.staticSharedLibName != null) {
17378                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17379                        pkg.staticSharedLibVersion);
17380                if (libEntry != null) {
17381                    for (int currUserId : allUsers) {
17382                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17383                            continue;
17384                        }
17385                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17386                                libEntry.info, 0, currUserId);
17387                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17388                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17389                                    + " hosting lib " + libEntry.info.getName() + " version "
17390                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17391                                    + " for user " + currUserId);
17392                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17393                        }
17394                    }
17395                }
17396            }
17397
17398            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17399        }
17400
17401        final int freezeUser;
17402        if (isUpdatedSystemApp(uninstalledPs)
17403                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17404            // We're downgrading a system app, which will apply to all users, so
17405            // freeze them all during the downgrade
17406            freezeUser = UserHandle.USER_ALL;
17407        } else {
17408            freezeUser = removeUser;
17409        }
17410
17411        synchronized (mInstallLock) {
17412            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17413            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17414                    deleteFlags, "deletePackageX")) {
17415                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17416                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17417            }
17418            synchronized (mPackages) {
17419                if (res) {
17420                    if (pkg != null) {
17421                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17422                    }
17423                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17424                    updateInstantAppInstallerLocked(packageName);
17425                }
17426            }
17427        }
17428
17429        if (res) {
17430            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17431            info.sendPackageRemovedBroadcasts(killApp);
17432            info.sendSystemPackageUpdatedBroadcasts();
17433            info.sendSystemPackageAppearedBroadcasts();
17434        }
17435        // Force a gc here.
17436        Runtime.getRuntime().gc();
17437        // Delete the resources here after sending the broadcast to let
17438        // other processes clean up before deleting resources.
17439        if (info.args != null) {
17440            synchronized (mInstallLock) {
17441                info.args.doPostDeleteLI(true);
17442            }
17443        }
17444
17445        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17446    }
17447
17448    static class PackageRemovedInfo {
17449        final PackageSender packageSender;
17450        String removedPackage;
17451        String installerPackageName;
17452        int uid = -1;
17453        int removedAppId = -1;
17454        int[] origUsers;
17455        int[] removedUsers = null;
17456        int[] broadcastUsers = null;
17457        int[] instantUserIds = null;
17458        SparseArray<Integer> installReasons;
17459        boolean isRemovedPackageSystemUpdate = false;
17460        boolean isUpdate;
17461        boolean dataRemoved;
17462        boolean removedForAllUsers;
17463        boolean isStaticSharedLib;
17464        // Clean up resources deleted packages.
17465        InstallArgs args = null;
17466        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17467        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17468
17469        PackageRemovedInfo(PackageSender packageSender) {
17470            this.packageSender = packageSender;
17471        }
17472
17473        void sendPackageRemovedBroadcasts(boolean killApp) {
17474            sendPackageRemovedBroadcastInternal(killApp);
17475            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17476            for (int i = 0; i < childCount; i++) {
17477                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17478                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17479            }
17480        }
17481
17482        void sendSystemPackageUpdatedBroadcasts() {
17483            if (isRemovedPackageSystemUpdate) {
17484                sendSystemPackageUpdatedBroadcastsInternal();
17485                final int childCount = (removedChildPackages != null)
17486                        ? removedChildPackages.size() : 0;
17487                for (int i = 0; i < childCount; i++) {
17488                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17489                    if (childInfo.isRemovedPackageSystemUpdate) {
17490                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17491                    }
17492                }
17493            }
17494        }
17495
17496        void sendSystemPackageAppearedBroadcasts() {
17497            final int packageCount = (appearedChildPackages != null)
17498                    ? appearedChildPackages.size() : 0;
17499            for (int i = 0; i < packageCount; i++) {
17500                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17501                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17502                    true /*sendBootCompleted*/, false /*startReceiver*/,
17503                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17504            }
17505        }
17506
17507        private void sendSystemPackageUpdatedBroadcastsInternal() {
17508            Bundle extras = new Bundle(2);
17509            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17510            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17511            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17512                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17513            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17514                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
17515            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17516                null, null, 0, removedPackage, null, null, null);
17517            if (installerPackageName != null) {
17518                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17519                        removedPackage, extras, 0 /*flags*/,
17520                        installerPackageName, null, null, null);
17521                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17522                        removedPackage, extras, 0 /*flags*/,
17523                        installerPackageName, null, null, null);
17524            }
17525        }
17526
17527        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17528            // Don't send static shared library removal broadcasts as these
17529            // libs are visible only the the apps that depend on them an one
17530            // cannot remove the library if it has a dependency.
17531            if (isStaticSharedLib) {
17532                return;
17533            }
17534            Bundle extras = new Bundle(2);
17535            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17536            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17537            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17538            if (isUpdate || isRemovedPackageSystemUpdate) {
17539                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17540            }
17541            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17542            if (removedPackage != null) {
17543                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17544                    removedPackage, extras, 0, null /*targetPackage*/, null,
17545                    broadcastUsers, instantUserIds);
17546                if (installerPackageName != null) {
17547                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17548                            removedPackage, extras, 0 /*flags*/,
17549                            installerPackageName, null, broadcastUsers, instantUserIds);
17550                }
17551                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17552                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17553                        removedPackage, extras,
17554                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17555                        null, null, broadcastUsers, instantUserIds);
17556                    packageSender.notifyPackageRemoved(removedPackage);
17557                }
17558            }
17559            if (removedAppId >= 0) {
17560                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17561                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17562                    null, null, broadcastUsers, instantUserIds);
17563            }
17564        }
17565
17566        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17567            removedUsers = userIds;
17568            if (removedUsers == null) {
17569                broadcastUsers = null;
17570                return;
17571            }
17572
17573            broadcastUsers = EMPTY_INT_ARRAY;
17574            instantUserIds = EMPTY_INT_ARRAY;
17575            for (int i = userIds.length - 1; i >= 0; --i) {
17576                final int userId = userIds[i];
17577                if (deletedPackageSetting.getInstantApp(userId)) {
17578                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
17579                } else {
17580                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17581                }
17582            }
17583        }
17584    }
17585
17586    /*
17587     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17588     * flag is not set, the data directory is removed as well.
17589     * make sure this flag is set for partially installed apps. If not its meaningless to
17590     * delete a partially installed application.
17591     */
17592    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17593            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17594        String packageName = ps.name;
17595        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17596        // Retrieve object to delete permissions for shared user later on
17597        final PackageParser.Package deletedPkg;
17598        final PackageSetting deletedPs;
17599        // reader
17600        synchronized (mPackages) {
17601            deletedPkg = mPackages.get(packageName);
17602            deletedPs = mSettings.mPackages.get(packageName);
17603            if (outInfo != null) {
17604                outInfo.removedPackage = packageName;
17605                outInfo.installerPackageName = ps.installerPackageName;
17606                outInfo.isStaticSharedLib = deletedPkg != null
17607                        && deletedPkg.staticSharedLibName != null;
17608                outInfo.populateUsers(deletedPs == null ? null
17609                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17610            }
17611        }
17612
17613        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
17614
17615        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17616            final PackageParser.Package resolvedPkg;
17617            if (deletedPkg != null) {
17618                resolvedPkg = deletedPkg;
17619            } else {
17620                // We don't have a parsed package when it lives on an ejected
17621                // adopted storage device, so fake something together
17622                resolvedPkg = new PackageParser.Package(ps.name);
17623                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17624            }
17625            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17626                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17627            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17628            if (outInfo != null) {
17629                outInfo.dataRemoved = true;
17630            }
17631            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17632        }
17633
17634        int removedAppId = -1;
17635
17636        // writer
17637        synchronized (mPackages) {
17638            boolean installedStateChanged = false;
17639            if (deletedPs != null) {
17640                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17641                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17642                    clearDefaultBrowserIfNeeded(packageName);
17643                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17644                    removedAppId = mSettings.removePackageLPw(packageName);
17645                    if (outInfo != null) {
17646                        outInfo.removedAppId = removedAppId;
17647                    }
17648                    mPermissionManager.updatePermissions(
17649                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
17650                    if (deletedPs.sharedUser != null) {
17651                        // Remove permissions associated with package. Since runtime
17652                        // permissions are per user we have to kill the removed package
17653                        // or packages running under the shared user of the removed
17654                        // package if revoking the permissions requested only by the removed
17655                        // package is successful and this causes a change in gids.
17656                        for (int userId : UserManagerService.getInstance().getUserIds()) {
17657                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17658                                    userId);
17659                            if (userIdToKill == UserHandle.USER_ALL
17660                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
17661                                // If gids changed for this user, kill all affected packages.
17662                                mHandler.post(new Runnable() {
17663                                    @Override
17664                                    public void run() {
17665                                        // This has to happen with no lock held.
17666                                        killApplication(deletedPs.name, deletedPs.appId,
17667                                                KILL_APP_REASON_GIDS_CHANGED);
17668                                    }
17669                                });
17670                                break;
17671                            }
17672                        }
17673                    }
17674                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17675                }
17676                // make sure to preserve per-user disabled state if this removal was just
17677                // a downgrade of a system app to the factory package
17678                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17679                    if (DEBUG_REMOVE) {
17680                        Slog.d(TAG, "Propagating install state across downgrade");
17681                    }
17682                    for (int userId : allUserHandles) {
17683                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17684                        if (DEBUG_REMOVE) {
17685                            Slog.d(TAG, "    user " + userId + " => " + installed);
17686                        }
17687                        if (installed != ps.getInstalled(userId)) {
17688                            installedStateChanged = true;
17689                        }
17690                        ps.setInstalled(installed, userId);
17691                    }
17692                }
17693            }
17694            // can downgrade to reader
17695            if (writeSettings) {
17696                // Save settings now
17697                mSettings.writeLPr();
17698            }
17699            if (installedStateChanged) {
17700                mSettings.writeKernelMappingLPr(ps);
17701            }
17702        }
17703        if (removedAppId != -1) {
17704            // A user ID was deleted here. Go through all users and remove it
17705            // from KeyStore.
17706            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17707        }
17708    }
17709
17710    static boolean locationIsPrivileged(String path) {
17711        try {
17712            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
17713            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
17714            return path.startsWith(privilegedAppDir.getCanonicalPath())
17715                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath());
17716        } catch (IOException e) {
17717            Slog.e(TAG, "Unable to access code path " + path);
17718        }
17719        return false;
17720    }
17721
17722    static boolean locationIsOem(String path) {
17723        try {
17724            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
17725        } catch (IOException e) {
17726            Slog.e(TAG, "Unable to access code path " + path);
17727        }
17728        return false;
17729    }
17730
17731    static boolean locationIsVendor(String path) {
17732        try {
17733            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
17734        } catch (IOException e) {
17735            Slog.e(TAG, "Unable to access code path " + path);
17736        }
17737        return false;
17738    }
17739
17740    /*
17741     * Tries to delete system package.
17742     */
17743    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17744            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17745            boolean writeSettings) {
17746        if (deletedPs.parentPackageName != null) {
17747            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17748            return false;
17749        }
17750
17751        final boolean applyUserRestrictions
17752                = (allUserHandles != null) && (outInfo.origUsers != null);
17753        final PackageSetting disabledPs;
17754        // Confirm if the system package has been updated
17755        // An updated system app can be deleted. This will also have to restore
17756        // the system pkg from system partition
17757        // reader
17758        synchronized (mPackages) {
17759            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17760        }
17761
17762        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17763                + " disabledPs=" + disabledPs);
17764
17765        if (disabledPs == null) {
17766            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17767            return false;
17768        } else if (DEBUG_REMOVE) {
17769            Slog.d(TAG, "Deleting system pkg from data partition");
17770        }
17771
17772        if (DEBUG_REMOVE) {
17773            if (applyUserRestrictions) {
17774                Slog.d(TAG, "Remembering install states:");
17775                for (int userId : allUserHandles) {
17776                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17777                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
17778                }
17779            }
17780        }
17781
17782        // Delete the updated package
17783        outInfo.isRemovedPackageSystemUpdate = true;
17784        if (outInfo.removedChildPackages != null) {
17785            final int childCount = (deletedPs.childPackageNames != null)
17786                    ? deletedPs.childPackageNames.size() : 0;
17787            for (int i = 0; i < childCount; i++) {
17788                String childPackageName = deletedPs.childPackageNames.get(i);
17789                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17790                        .contains(childPackageName)) {
17791                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17792                            childPackageName);
17793                    if (childInfo != null) {
17794                        childInfo.isRemovedPackageSystemUpdate = true;
17795                    }
17796                }
17797            }
17798        }
17799
17800        if (disabledPs.versionCode < deletedPs.versionCode) {
17801            // Delete data for downgrades
17802            flags &= ~PackageManager.DELETE_KEEP_DATA;
17803        } else {
17804            // Preserve data by setting flag
17805            flags |= PackageManager.DELETE_KEEP_DATA;
17806        }
17807
17808        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17809                outInfo, writeSettings, disabledPs.pkg);
17810        if (!ret) {
17811            return false;
17812        }
17813
17814        // writer
17815        synchronized (mPackages) {
17816            // NOTE: The system package always needs to be enabled; even if it's for
17817            // a compressed stub. If we don't, installing the system package fails
17818            // during scan [scanning checks the disabled packages]. We will reverse
17819            // this later, after we've "installed" the stub.
17820            // Reinstate the old system package
17821            enableSystemPackageLPw(disabledPs.pkg);
17822            // Remove any native libraries from the upgraded package.
17823            removeNativeBinariesLI(deletedPs);
17824        }
17825
17826        // Install the system package
17827        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
17828        try {
17829            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
17830                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
17831        } catch (PackageManagerException e) {
17832            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
17833                    + e.getMessage());
17834            return false;
17835        } finally {
17836            if (disabledPs.pkg.isStub) {
17837                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
17838            }
17839        }
17840        return true;
17841    }
17842
17843    /**
17844     * Installs a package that's already on the system partition.
17845     */
17846    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
17847            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
17848            @Nullable PermissionsState origPermissionState, boolean writeSettings)
17849                    throws PackageManagerException {
17850        @ParseFlags int parseFlags =
17851                mDefParseFlags
17852                | PackageParser.PARSE_MUST_BE_APK
17853                | PackageParser.PARSE_IS_SYSTEM_DIR;
17854        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
17855        if (isPrivileged || locationIsPrivileged(codePathString)) {
17856            scanFlags |= SCAN_AS_PRIVILEGED;
17857        }
17858        if (locationIsOem(codePathString)) {
17859            scanFlags |= SCAN_AS_OEM;
17860        }
17861        if (locationIsVendor(codePathString)) {
17862            scanFlags |= SCAN_AS_VENDOR;
17863        }
17864
17865        final File codePath = new File(codePathString);
17866        final PackageParser.Package pkg =
17867                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
17868
17869        try {
17870            // update shared libraries for the newly re-installed system package
17871            updateSharedLibrariesLPr(pkg, null);
17872        } catch (PackageManagerException e) {
17873            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17874        }
17875
17876        prepareAppDataAfterInstallLIF(pkg);
17877
17878        // writer
17879        synchronized (mPackages) {
17880            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
17881
17882            // Propagate the permissions state as we do not want to drop on the floor
17883            // runtime permissions. The update permissions method below will take
17884            // care of removing obsolete permissions and grant install permissions.
17885            if (origPermissionState != null) {
17886                ps.getPermissionsState().copyFrom(origPermissionState);
17887            }
17888            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
17889                    mPermissionCallback);
17890
17891            final boolean applyUserRestrictions
17892                    = (allUserHandles != null) && (origUserHandles != null);
17893            if (applyUserRestrictions) {
17894                boolean installedStateChanged = false;
17895                if (DEBUG_REMOVE) {
17896                    Slog.d(TAG, "Propagating install state across reinstall");
17897                }
17898                for (int userId : allUserHandles) {
17899                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
17900                    if (DEBUG_REMOVE) {
17901                        Slog.d(TAG, "    user " + userId + " => " + installed);
17902                    }
17903                    if (installed != ps.getInstalled(userId)) {
17904                        installedStateChanged = true;
17905                    }
17906                    ps.setInstalled(installed, userId);
17907
17908                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17909                }
17910                // Regardless of writeSettings we need to ensure that this restriction
17911                // state propagation is persisted
17912                mSettings.writeAllUsersPackageRestrictionsLPr();
17913                if (installedStateChanged) {
17914                    mSettings.writeKernelMappingLPr(ps);
17915                }
17916            }
17917            // can downgrade to reader here
17918            if (writeSettings) {
17919                mSettings.writeLPr();
17920            }
17921        }
17922        return pkg;
17923    }
17924
17925    private boolean deleteInstalledPackageLIF(PackageSetting ps,
17926            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
17927            PackageRemovedInfo outInfo, boolean writeSettings,
17928            PackageParser.Package replacingPackage) {
17929        synchronized (mPackages) {
17930            if (outInfo != null) {
17931                outInfo.uid = ps.appId;
17932            }
17933
17934            if (outInfo != null && outInfo.removedChildPackages != null) {
17935                final int childCount = (ps.childPackageNames != null)
17936                        ? ps.childPackageNames.size() : 0;
17937                for (int i = 0; i < childCount; i++) {
17938                    String childPackageName = ps.childPackageNames.get(i);
17939                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
17940                    if (childPs == null) {
17941                        return false;
17942                    }
17943                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17944                            childPackageName);
17945                    if (childInfo != null) {
17946                        childInfo.uid = childPs.appId;
17947                    }
17948                }
17949            }
17950        }
17951
17952        // Delete package data from internal structures and also remove data if flag is set
17953        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
17954
17955        // Delete the child packages data
17956        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17957        for (int i = 0; i < childCount; i++) {
17958            PackageSetting childPs;
17959            synchronized (mPackages) {
17960                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17961            }
17962            if (childPs != null) {
17963                PackageRemovedInfo childOutInfo = (outInfo != null
17964                        && outInfo.removedChildPackages != null)
17965                        ? outInfo.removedChildPackages.get(childPs.name) : null;
17966                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
17967                        && (replacingPackage != null
17968                        && !replacingPackage.hasChildPackage(childPs.name))
17969                        ? flags & ~DELETE_KEEP_DATA : flags;
17970                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
17971                        deleteFlags, writeSettings);
17972            }
17973        }
17974
17975        // Delete application code and resources only for parent packages
17976        if (ps.parentPackageName == null) {
17977            if (deleteCodeAndResources && (outInfo != null)) {
17978                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
17979                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
17980                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
17981            }
17982        }
17983
17984        return true;
17985    }
17986
17987    @Override
17988    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
17989            int userId) {
17990        mContext.enforceCallingOrSelfPermission(
17991                android.Manifest.permission.DELETE_PACKAGES, null);
17992        synchronized (mPackages) {
17993            // Cannot block uninstall of static shared libs as they are
17994            // considered a part of the using app (emulating static linking).
17995            // Also static libs are installed always on internal storage.
17996            PackageParser.Package pkg = mPackages.get(packageName);
17997            if (pkg != null && pkg.staticSharedLibName != null) {
17998                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
17999                        + " providing static shared library: " + pkg.staticSharedLibName);
18000                return false;
18001            }
18002            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18003            mSettings.writePackageRestrictionsLPr(userId);
18004        }
18005        return true;
18006    }
18007
18008    @Override
18009    public boolean getBlockUninstallForUser(String packageName, int userId) {
18010        synchronized (mPackages) {
18011            final PackageSetting ps = mSettings.mPackages.get(packageName);
18012            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18013                return false;
18014            }
18015            return mSettings.getBlockUninstallLPr(userId, packageName);
18016        }
18017    }
18018
18019    @Override
18020    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18021        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18022        synchronized (mPackages) {
18023            PackageSetting ps = mSettings.mPackages.get(packageName);
18024            if (ps == null) {
18025                Log.w(TAG, "Package doesn't exist: " + packageName);
18026                return false;
18027            }
18028            if (systemUserApp) {
18029                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18030            } else {
18031                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18032            }
18033            mSettings.writeLPr();
18034        }
18035        return true;
18036    }
18037
18038    /*
18039     * This method handles package deletion in general
18040     */
18041    private boolean deletePackageLIF(String packageName, UserHandle user,
18042            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18043            PackageRemovedInfo outInfo, boolean writeSettings,
18044            PackageParser.Package replacingPackage) {
18045        if (packageName == null) {
18046            Slog.w(TAG, "Attempt to delete null packageName.");
18047            return false;
18048        }
18049
18050        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18051
18052        PackageSetting ps;
18053        synchronized (mPackages) {
18054            ps = mSettings.mPackages.get(packageName);
18055            if (ps == null) {
18056                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18057                return false;
18058            }
18059
18060            if (ps.parentPackageName != null && (!isSystemApp(ps)
18061                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18062                if (DEBUG_REMOVE) {
18063                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18064                            + ((user == null) ? UserHandle.USER_ALL : user));
18065                }
18066                final int removedUserId = (user != null) ? user.getIdentifier()
18067                        : UserHandle.USER_ALL;
18068                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18069                    return false;
18070                }
18071                markPackageUninstalledForUserLPw(ps, user);
18072                scheduleWritePackageRestrictionsLocked(user);
18073                return true;
18074            }
18075        }
18076
18077        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18078                && user.getIdentifier() != UserHandle.USER_ALL)) {
18079            // The caller is asking that the package only be deleted for a single
18080            // user.  To do this, we just mark its uninstalled state and delete
18081            // its data. If this is a system app, we only allow this to happen if
18082            // they have set the special DELETE_SYSTEM_APP which requests different
18083            // semantics than normal for uninstalling system apps.
18084            markPackageUninstalledForUserLPw(ps, user);
18085
18086            if (!isSystemApp(ps)) {
18087                // Do not uninstall the APK if an app should be cached
18088                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18089                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18090                    // Other user still have this package installed, so all
18091                    // we need to do is clear this user's data and save that
18092                    // it is uninstalled.
18093                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18094                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18095                        return false;
18096                    }
18097                    scheduleWritePackageRestrictionsLocked(user);
18098                    return true;
18099                } else {
18100                    // We need to set it back to 'installed' so the uninstall
18101                    // broadcasts will be sent correctly.
18102                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18103                    ps.setInstalled(true, user.getIdentifier());
18104                    mSettings.writeKernelMappingLPr(ps);
18105                }
18106            } else {
18107                // This is a system app, so we assume that the
18108                // other users still have this package installed, so all
18109                // we need to do is clear this user's data and save that
18110                // it is uninstalled.
18111                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18112                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18113                    return false;
18114                }
18115                scheduleWritePackageRestrictionsLocked(user);
18116                return true;
18117            }
18118        }
18119
18120        // If we are deleting a composite package for all users, keep track
18121        // of result for each child.
18122        if (ps.childPackageNames != null && outInfo != null) {
18123            synchronized (mPackages) {
18124                final int childCount = ps.childPackageNames.size();
18125                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18126                for (int i = 0; i < childCount; i++) {
18127                    String childPackageName = ps.childPackageNames.get(i);
18128                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18129                    childInfo.removedPackage = childPackageName;
18130                    childInfo.installerPackageName = ps.installerPackageName;
18131                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18132                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18133                    if (childPs != null) {
18134                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18135                    }
18136                }
18137            }
18138        }
18139
18140        boolean ret = false;
18141        if (isSystemApp(ps)) {
18142            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18143            // When an updated system application is deleted we delete the existing resources
18144            // as well and fall back to existing code in system partition
18145            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18146        } else {
18147            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18148            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18149                    outInfo, writeSettings, replacingPackage);
18150        }
18151
18152        // Take a note whether we deleted the package for all users
18153        if (outInfo != null) {
18154            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18155            if (outInfo.removedChildPackages != null) {
18156                synchronized (mPackages) {
18157                    final int childCount = outInfo.removedChildPackages.size();
18158                    for (int i = 0; i < childCount; i++) {
18159                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18160                        if (childInfo != null) {
18161                            childInfo.removedForAllUsers = mPackages.get(
18162                                    childInfo.removedPackage) == null;
18163                        }
18164                    }
18165                }
18166            }
18167            // If we uninstalled an update to a system app there may be some
18168            // child packages that appeared as they are declared in the system
18169            // app but were not declared in the update.
18170            if (isSystemApp(ps)) {
18171                synchronized (mPackages) {
18172                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18173                    final int childCount = (updatedPs.childPackageNames != null)
18174                            ? updatedPs.childPackageNames.size() : 0;
18175                    for (int i = 0; i < childCount; i++) {
18176                        String childPackageName = updatedPs.childPackageNames.get(i);
18177                        if (outInfo.removedChildPackages == null
18178                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18179                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18180                            if (childPs == null) {
18181                                continue;
18182                            }
18183                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18184                            installRes.name = childPackageName;
18185                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18186                            installRes.pkg = mPackages.get(childPackageName);
18187                            installRes.uid = childPs.pkg.applicationInfo.uid;
18188                            if (outInfo.appearedChildPackages == null) {
18189                                outInfo.appearedChildPackages = new ArrayMap<>();
18190                            }
18191                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18192                        }
18193                    }
18194                }
18195            }
18196        }
18197
18198        return ret;
18199    }
18200
18201    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18202        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18203                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18204        for (int nextUserId : userIds) {
18205            if (DEBUG_REMOVE) {
18206                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18207            }
18208            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18209                    false /*installed*/,
18210                    true /*stopped*/,
18211                    true /*notLaunched*/,
18212                    false /*hidden*/,
18213                    false /*suspended*/,
18214                    false /*instantApp*/,
18215                    false /*virtualPreload*/,
18216                    null /*lastDisableAppCaller*/,
18217                    null /*enabledComponents*/,
18218                    null /*disabledComponents*/,
18219                    ps.readUserState(nextUserId).domainVerificationStatus,
18220                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18221        }
18222        mSettings.writeKernelMappingLPr(ps);
18223    }
18224
18225    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18226            PackageRemovedInfo outInfo) {
18227        final PackageParser.Package pkg;
18228        synchronized (mPackages) {
18229            pkg = mPackages.get(ps.name);
18230        }
18231
18232        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18233                : new int[] {userId};
18234        for (int nextUserId : userIds) {
18235            if (DEBUG_REMOVE) {
18236                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18237                        + nextUserId);
18238            }
18239
18240            destroyAppDataLIF(pkg, userId,
18241                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18242            destroyAppProfilesLIF(pkg, userId);
18243            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18244            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18245            schedulePackageCleaning(ps.name, nextUserId, false);
18246            synchronized (mPackages) {
18247                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18248                    scheduleWritePackageRestrictionsLocked(nextUserId);
18249                }
18250                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18251            }
18252        }
18253
18254        if (outInfo != null) {
18255            outInfo.removedPackage = ps.name;
18256            outInfo.installerPackageName = ps.installerPackageName;
18257            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18258            outInfo.removedAppId = ps.appId;
18259            outInfo.removedUsers = userIds;
18260            outInfo.broadcastUsers = userIds;
18261        }
18262
18263        return true;
18264    }
18265
18266    private final class ClearStorageConnection implements ServiceConnection {
18267        IMediaContainerService mContainerService;
18268
18269        @Override
18270        public void onServiceConnected(ComponentName name, IBinder service) {
18271            synchronized (this) {
18272                mContainerService = IMediaContainerService.Stub
18273                        .asInterface(Binder.allowBlocking(service));
18274                notifyAll();
18275            }
18276        }
18277
18278        @Override
18279        public void onServiceDisconnected(ComponentName name) {
18280        }
18281    }
18282
18283    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18284        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18285
18286        final boolean mounted;
18287        if (Environment.isExternalStorageEmulated()) {
18288            mounted = true;
18289        } else {
18290            final String status = Environment.getExternalStorageState();
18291
18292            mounted = status.equals(Environment.MEDIA_MOUNTED)
18293                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18294        }
18295
18296        if (!mounted) {
18297            return;
18298        }
18299
18300        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18301        int[] users;
18302        if (userId == UserHandle.USER_ALL) {
18303            users = sUserManager.getUserIds();
18304        } else {
18305            users = new int[] { userId };
18306        }
18307        final ClearStorageConnection conn = new ClearStorageConnection();
18308        if (mContext.bindServiceAsUser(
18309                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18310            try {
18311                for (int curUser : users) {
18312                    long timeout = SystemClock.uptimeMillis() + 5000;
18313                    synchronized (conn) {
18314                        long now;
18315                        while (conn.mContainerService == null &&
18316                                (now = SystemClock.uptimeMillis()) < timeout) {
18317                            try {
18318                                conn.wait(timeout - now);
18319                            } catch (InterruptedException e) {
18320                            }
18321                        }
18322                    }
18323                    if (conn.mContainerService == null) {
18324                        return;
18325                    }
18326
18327                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18328                    clearDirectory(conn.mContainerService,
18329                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18330                    if (allData) {
18331                        clearDirectory(conn.mContainerService,
18332                                userEnv.buildExternalStorageAppDataDirs(packageName));
18333                        clearDirectory(conn.mContainerService,
18334                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18335                    }
18336                }
18337            } finally {
18338                mContext.unbindService(conn);
18339            }
18340        }
18341    }
18342
18343    @Override
18344    public void clearApplicationProfileData(String packageName) {
18345        enforceSystemOrRoot("Only the system can clear all profile data");
18346
18347        final PackageParser.Package pkg;
18348        synchronized (mPackages) {
18349            pkg = mPackages.get(packageName);
18350        }
18351
18352        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18353            synchronized (mInstallLock) {
18354                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18355            }
18356        }
18357    }
18358
18359    @Override
18360    public void clearApplicationUserData(final String packageName,
18361            final IPackageDataObserver observer, final int userId) {
18362        mContext.enforceCallingOrSelfPermission(
18363                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18364
18365        final int callingUid = Binder.getCallingUid();
18366        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18367                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18368
18369        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18370        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18371        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18372            throw new SecurityException("Cannot clear data for a protected package: "
18373                    + packageName);
18374        }
18375        // Queue up an async operation since the package deletion may take a little while.
18376        mHandler.post(new Runnable() {
18377            public void run() {
18378                mHandler.removeCallbacks(this);
18379                final boolean succeeded;
18380                if (!filterApp) {
18381                    try (PackageFreezer freezer = freezePackage(packageName,
18382                            "clearApplicationUserData")) {
18383                        synchronized (mInstallLock) {
18384                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18385                        }
18386                        clearExternalStorageDataSync(packageName, userId, true);
18387                        synchronized (mPackages) {
18388                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18389                                    packageName, userId);
18390                        }
18391                    }
18392                    if (succeeded) {
18393                        // invoke DeviceStorageMonitor's update method to clear any notifications
18394                        DeviceStorageMonitorInternal dsm = LocalServices
18395                                .getService(DeviceStorageMonitorInternal.class);
18396                        if (dsm != null) {
18397                            dsm.checkMemory();
18398                        }
18399                    }
18400                } else {
18401                    succeeded = false;
18402                }
18403                if (observer != null) {
18404                    try {
18405                        observer.onRemoveCompleted(packageName, succeeded);
18406                    } catch (RemoteException e) {
18407                        Log.i(TAG, "Observer no longer exists.");
18408                    }
18409                } //end if observer
18410            } //end run
18411        });
18412    }
18413
18414    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18415        if (packageName == null) {
18416            Slog.w(TAG, "Attempt to delete null packageName.");
18417            return false;
18418        }
18419
18420        // Try finding details about the requested package
18421        PackageParser.Package pkg;
18422        synchronized (mPackages) {
18423            pkg = mPackages.get(packageName);
18424            if (pkg == null) {
18425                final PackageSetting ps = mSettings.mPackages.get(packageName);
18426                if (ps != null) {
18427                    pkg = ps.pkg;
18428                }
18429            }
18430
18431            if (pkg == null) {
18432                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18433                return false;
18434            }
18435
18436            PackageSetting ps = (PackageSetting) pkg.mExtras;
18437            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18438        }
18439
18440        clearAppDataLIF(pkg, userId,
18441                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18442
18443        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18444        removeKeystoreDataIfNeeded(userId, appId);
18445
18446        UserManagerInternal umInternal = getUserManagerInternal();
18447        final int flags;
18448        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18449            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18450        } else if (umInternal.isUserRunning(userId)) {
18451            flags = StorageManager.FLAG_STORAGE_DE;
18452        } else {
18453            flags = 0;
18454        }
18455        prepareAppDataContentsLIF(pkg, userId, flags);
18456
18457        return true;
18458    }
18459
18460    /**
18461     * Reverts user permission state changes (permissions and flags) in
18462     * all packages for a given user.
18463     *
18464     * @param userId The device user for which to do a reset.
18465     */
18466    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18467        final int packageCount = mPackages.size();
18468        for (int i = 0; i < packageCount; i++) {
18469            PackageParser.Package pkg = mPackages.valueAt(i);
18470            PackageSetting ps = (PackageSetting) pkg.mExtras;
18471            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18472        }
18473    }
18474
18475    private void resetNetworkPolicies(int userId) {
18476        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18477    }
18478
18479    /**
18480     * Reverts user permission state changes (permissions and flags).
18481     *
18482     * @param ps The package for which to reset.
18483     * @param userId The device user for which to do a reset.
18484     */
18485    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18486            final PackageSetting ps, final int userId) {
18487        if (ps.pkg == null) {
18488            return;
18489        }
18490
18491        // These are flags that can change base on user actions.
18492        final int userSettableMask = FLAG_PERMISSION_USER_SET
18493                | FLAG_PERMISSION_USER_FIXED
18494                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18495                | FLAG_PERMISSION_REVIEW_REQUIRED;
18496
18497        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18498                | FLAG_PERMISSION_POLICY_FIXED;
18499
18500        boolean writeInstallPermissions = false;
18501        boolean writeRuntimePermissions = false;
18502
18503        final int permissionCount = ps.pkg.requestedPermissions.size();
18504        for (int i = 0; i < permissionCount; i++) {
18505            final String permName = ps.pkg.requestedPermissions.get(i);
18506            final BasePermission bp =
18507                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
18508            if (bp == null) {
18509                continue;
18510            }
18511
18512            // If shared user we just reset the state to which only this app contributed.
18513            if (ps.sharedUser != null) {
18514                boolean used = false;
18515                final int packageCount = ps.sharedUser.packages.size();
18516                for (int j = 0; j < packageCount; j++) {
18517                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18518                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18519                            && pkg.pkg.requestedPermissions.contains(permName)) {
18520                        used = true;
18521                        break;
18522                    }
18523                }
18524                if (used) {
18525                    continue;
18526                }
18527            }
18528
18529            final PermissionsState permissionsState = ps.getPermissionsState();
18530
18531            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
18532
18533            // Always clear the user settable flags.
18534            final boolean hasInstallState =
18535                    permissionsState.getInstallPermissionState(permName) != null;
18536            // If permission review is enabled and this is a legacy app, mark the
18537            // permission as requiring a review as this is the initial state.
18538            int flags = 0;
18539            if (mSettings.mPermissions.mPermissionReviewRequired
18540                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18541                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18542            }
18543            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18544                if (hasInstallState) {
18545                    writeInstallPermissions = true;
18546                } else {
18547                    writeRuntimePermissions = true;
18548                }
18549            }
18550
18551            // Below is only runtime permission handling.
18552            if (!bp.isRuntime()) {
18553                continue;
18554            }
18555
18556            // Never clobber system or policy.
18557            if ((oldFlags & policyOrSystemFlags) != 0) {
18558                continue;
18559            }
18560
18561            // If this permission was granted by default, make sure it is.
18562            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18563                if (permissionsState.grantRuntimePermission(bp, userId)
18564                        != PERMISSION_OPERATION_FAILURE) {
18565                    writeRuntimePermissions = true;
18566                }
18567            // If permission review is enabled the permissions for a legacy apps
18568            // are represented as constantly granted runtime ones, so don't revoke.
18569            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18570                // Otherwise, reset the permission.
18571                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18572                switch (revokeResult) {
18573                    case PERMISSION_OPERATION_SUCCESS:
18574                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18575                        writeRuntimePermissions = true;
18576                        final int appId = ps.appId;
18577                        mHandler.post(new Runnable() {
18578                            @Override
18579                            public void run() {
18580                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18581                            }
18582                        });
18583                    } break;
18584                }
18585            }
18586        }
18587
18588        // Synchronously write as we are taking permissions away.
18589        if (writeRuntimePermissions) {
18590            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18591        }
18592
18593        // Synchronously write as we are taking permissions away.
18594        if (writeInstallPermissions) {
18595            mSettings.writeLPr();
18596        }
18597    }
18598
18599    /**
18600     * Remove entries from the keystore daemon. Will only remove it if the
18601     * {@code appId} is valid.
18602     */
18603    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18604        if (appId < 0) {
18605            return;
18606        }
18607
18608        final KeyStore keyStore = KeyStore.getInstance();
18609        if (keyStore != null) {
18610            if (userId == UserHandle.USER_ALL) {
18611                for (final int individual : sUserManager.getUserIds()) {
18612                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18613                }
18614            } else {
18615                keyStore.clearUid(UserHandle.getUid(userId, appId));
18616            }
18617        } else {
18618            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18619        }
18620    }
18621
18622    @Override
18623    public void deleteApplicationCacheFiles(final String packageName,
18624            final IPackageDataObserver observer) {
18625        final int userId = UserHandle.getCallingUserId();
18626        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18627    }
18628
18629    @Override
18630    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18631            final IPackageDataObserver observer) {
18632        final int callingUid = Binder.getCallingUid();
18633        mContext.enforceCallingOrSelfPermission(
18634                android.Manifest.permission.DELETE_CACHE_FILES, null);
18635        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18636                /* requireFullPermission= */ true, /* checkShell= */ false,
18637                "delete application cache files");
18638        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18639                android.Manifest.permission.ACCESS_INSTANT_APPS);
18640
18641        final PackageParser.Package pkg;
18642        synchronized (mPackages) {
18643            pkg = mPackages.get(packageName);
18644        }
18645
18646        // Queue up an async operation since the package deletion may take a little while.
18647        mHandler.post(new Runnable() {
18648            public void run() {
18649                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
18650                boolean doClearData = true;
18651                if (ps != null) {
18652                    final boolean targetIsInstantApp =
18653                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18654                    doClearData = !targetIsInstantApp
18655                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18656                }
18657                if (doClearData) {
18658                    synchronized (mInstallLock) {
18659                        final int flags = StorageManager.FLAG_STORAGE_DE
18660                                | StorageManager.FLAG_STORAGE_CE;
18661                        // We're only clearing cache files, so we don't care if the
18662                        // app is unfrozen and still able to run
18663                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18664                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18665                    }
18666                    clearExternalStorageDataSync(packageName, userId, false);
18667                }
18668                if (observer != null) {
18669                    try {
18670                        observer.onRemoveCompleted(packageName, true);
18671                    } catch (RemoteException e) {
18672                        Log.i(TAG, "Observer no longer exists.");
18673                    }
18674                }
18675            }
18676        });
18677    }
18678
18679    @Override
18680    public void getPackageSizeInfo(final String packageName, int userHandle,
18681            final IPackageStatsObserver observer) {
18682        throw new UnsupportedOperationException(
18683                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18684    }
18685
18686    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18687        final PackageSetting ps;
18688        synchronized (mPackages) {
18689            ps = mSettings.mPackages.get(packageName);
18690            if (ps == null) {
18691                Slog.w(TAG, "Failed to find settings for " + packageName);
18692                return false;
18693            }
18694        }
18695
18696        final String[] packageNames = { packageName };
18697        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18698        final String[] codePaths = { ps.codePathString };
18699
18700        try {
18701            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18702                    ps.appId, ceDataInodes, codePaths, stats);
18703
18704            // For now, ignore code size of packages on system partition
18705            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18706                stats.codeSize = 0;
18707            }
18708
18709            // External clients expect these to be tracked separately
18710            stats.dataSize -= stats.cacheSize;
18711
18712        } catch (InstallerException e) {
18713            Slog.w(TAG, String.valueOf(e));
18714            return false;
18715        }
18716
18717        return true;
18718    }
18719
18720    private int getUidTargetSdkVersionLockedLPr(int uid) {
18721        Object obj = mSettings.getUserIdLPr(uid);
18722        if (obj instanceof SharedUserSetting) {
18723            final SharedUserSetting sus = (SharedUserSetting) obj;
18724            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18725            final Iterator<PackageSetting> it = sus.packages.iterator();
18726            while (it.hasNext()) {
18727                final PackageSetting ps = it.next();
18728                if (ps.pkg != null) {
18729                    int v = ps.pkg.applicationInfo.targetSdkVersion;
18730                    if (v < vers) vers = v;
18731                }
18732            }
18733            return vers;
18734        } else if (obj instanceof PackageSetting) {
18735            final PackageSetting ps = (PackageSetting) obj;
18736            if (ps.pkg != null) {
18737                return ps.pkg.applicationInfo.targetSdkVersion;
18738            }
18739        }
18740        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18741    }
18742
18743    @Override
18744    public void addPreferredActivity(IntentFilter filter, int match,
18745            ComponentName[] set, ComponentName activity, int userId) {
18746        addPreferredActivityInternal(filter, match, set, activity, true, userId,
18747                "Adding preferred");
18748    }
18749
18750    private void addPreferredActivityInternal(IntentFilter filter, int match,
18751            ComponentName[] set, ComponentName activity, boolean always, int userId,
18752            String opname) {
18753        // writer
18754        int callingUid = Binder.getCallingUid();
18755        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18756                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18757        if (filter.countActions() == 0) {
18758            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18759            return;
18760        }
18761        synchronized (mPackages) {
18762            if (mContext.checkCallingOrSelfPermission(
18763                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18764                    != PackageManager.PERMISSION_GRANTED) {
18765                if (getUidTargetSdkVersionLockedLPr(callingUid)
18766                        < Build.VERSION_CODES.FROYO) {
18767                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18768                            + callingUid);
18769                    return;
18770                }
18771                mContext.enforceCallingOrSelfPermission(
18772                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18773            }
18774
18775            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18776            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18777                    + userId + ":");
18778            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18779            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18780            scheduleWritePackageRestrictionsLocked(userId);
18781            postPreferredActivityChangedBroadcast(userId);
18782        }
18783    }
18784
18785    private void postPreferredActivityChangedBroadcast(int userId) {
18786        mHandler.post(() -> {
18787            final IActivityManager am = ActivityManager.getService();
18788            if (am == null) {
18789                return;
18790            }
18791
18792            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18793            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18794            try {
18795                am.broadcastIntent(null, intent, null, null,
18796                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
18797                        null, false, false, userId);
18798            } catch (RemoteException e) {
18799            }
18800        });
18801    }
18802
18803    @Override
18804    public void replacePreferredActivity(IntentFilter filter, int match,
18805            ComponentName[] set, ComponentName activity, int userId) {
18806        if (filter.countActions() != 1) {
18807            throw new IllegalArgumentException(
18808                    "replacePreferredActivity expects filter to have only 1 action.");
18809        }
18810        if (filter.countDataAuthorities() != 0
18811                || filter.countDataPaths() != 0
18812                || filter.countDataSchemes() > 1
18813                || filter.countDataTypes() != 0) {
18814            throw new IllegalArgumentException(
18815                    "replacePreferredActivity expects filter to have no data authorities, " +
18816                    "paths, or types; and at most one scheme.");
18817        }
18818
18819        final int callingUid = Binder.getCallingUid();
18820        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18821                true /* requireFullPermission */, false /* checkShell */,
18822                "replace preferred activity");
18823        synchronized (mPackages) {
18824            if (mContext.checkCallingOrSelfPermission(
18825                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18826                    != PackageManager.PERMISSION_GRANTED) {
18827                if (getUidTargetSdkVersionLockedLPr(callingUid)
18828                        < Build.VERSION_CODES.FROYO) {
18829                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18830                            + Binder.getCallingUid());
18831                    return;
18832                }
18833                mContext.enforceCallingOrSelfPermission(
18834                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18835            }
18836
18837            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18838            if (pir != null) {
18839                // Get all of the existing entries that exactly match this filter.
18840                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18841                if (existing != null && existing.size() == 1) {
18842                    PreferredActivity cur = existing.get(0);
18843                    if (DEBUG_PREFERRED) {
18844                        Slog.i(TAG, "Checking replace of preferred:");
18845                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18846                        if (!cur.mPref.mAlways) {
18847                            Slog.i(TAG, "  -- CUR; not mAlways!");
18848                        } else {
18849                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
18850                            Slog.i(TAG, "  -- CUR: mSet="
18851                                    + Arrays.toString(cur.mPref.mSetComponents));
18852                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
18853                            Slog.i(TAG, "  -- NEW: mMatch="
18854                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
18855                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
18856                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
18857                        }
18858                    }
18859                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18860                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18861                            && cur.mPref.sameSet(set)) {
18862                        // Setting the preferred activity to what it happens to be already
18863                        if (DEBUG_PREFERRED) {
18864                            Slog.i(TAG, "Replacing with same preferred activity "
18865                                    + cur.mPref.mShortComponent + " for user "
18866                                    + userId + ":");
18867                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18868                        }
18869                        return;
18870                    }
18871                }
18872
18873                if (existing != null) {
18874                    if (DEBUG_PREFERRED) {
18875                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
18876                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18877                    }
18878                    for (int i = 0; i < existing.size(); i++) {
18879                        PreferredActivity pa = existing.get(i);
18880                        if (DEBUG_PREFERRED) {
18881                            Slog.i(TAG, "Removing existing preferred activity "
18882                                    + pa.mPref.mComponent + ":");
18883                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
18884                        }
18885                        pir.removeFilter(pa);
18886                    }
18887                }
18888            }
18889            addPreferredActivityInternal(filter, match, set, activity, true, userId,
18890                    "Replacing preferred");
18891        }
18892    }
18893
18894    @Override
18895    public void clearPackagePreferredActivities(String packageName) {
18896        final int callingUid = Binder.getCallingUid();
18897        if (getInstantAppPackageName(callingUid) != null) {
18898            return;
18899        }
18900        // writer
18901        synchronized (mPackages) {
18902            PackageParser.Package pkg = mPackages.get(packageName);
18903            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
18904                if (mContext.checkCallingOrSelfPermission(
18905                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18906                        != PackageManager.PERMISSION_GRANTED) {
18907                    if (getUidTargetSdkVersionLockedLPr(callingUid)
18908                            < Build.VERSION_CODES.FROYO) {
18909                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18910                                + callingUid);
18911                        return;
18912                    }
18913                    mContext.enforceCallingOrSelfPermission(
18914                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18915                }
18916            }
18917            final PackageSetting ps = mSettings.getPackageLPr(packageName);
18918            if (ps != null
18919                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
18920                return;
18921            }
18922            int user = UserHandle.getCallingUserId();
18923            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
18924                scheduleWritePackageRestrictionsLocked(user);
18925            }
18926        }
18927    }
18928
18929    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18930    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
18931        ArrayList<PreferredActivity> removed = null;
18932        boolean changed = false;
18933        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18934            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
18935            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18936            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
18937                continue;
18938            }
18939            Iterator<PreferredActivity> it = pir.filterIterator();
18940            while (it.hasNext()) {
18941                PreferredActivity pa = it.next();
18942                // Mark entry for removal only if it matches the package name
18943                // and the entry is of type "always".
18944                if (packageName == null ||
18945                        (pa.mPref.mComponent.getPackageName().equals(packageName)
18946                                && pa.mPref.mAlways)) {
18947                    if (removed == null) {
18948                        removed = new ArrayList<PreferredActivity>();
18949                    }
18950                    removed.add(pa);
18951                }
18952            }
18953            if (removed != null) {
18954                for (int j=0; j<removed.size(); j++) {
18955                    PreferredActivity pa = removed.get(j);
18956                    pir.removeFilter(pa);
18957                }
18958                changed = true;
18959            }
18960        }
18961        if (changed) {
18962            postPreferredActivityChangedBroadcast(userId);
18963        }
18964        return changed;
18965    }
18966
18967    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18968    private void clearIntentFilterVerificationsLPw(int userId) {
18969        final int packageCount = mPackages.size();
18970        for (int i = 0; i < packageCount; i++) {
18971            PackageParser.Package pkg = mPackages.valueAt(i);
18972            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
18973        }
18974    }
18975
18976    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18977    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
18978        if (userId == UserHandle.USER_ALL) {
18979            if (mSettings.removeIntentFilterVerificationLPw(packageName,
18980                    sUserManager.getUserIds())) {
18981                for (int oneUserId : sUserManager.getUserIds()) {
18982                    scheduleWritePackageRestrictionsLocked(oneUserId);
18983                }
18984            }
18985        } else {
18986            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
18987                scheduleWritePackageRestrictionsLocked(userId);
18988            }
18989        }
18990    }
18991
18992    /** Clears state for all users, and touches intent filter verification policy */
18993    void clearDefaultBrowserIfNeeded(String packageName) {
18994        for (int oneUserId : sUserManager.getUserIds()) {
18995            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
18996        }
18997    }
18998
18999    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19000        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19001        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19002            if (packageName.equals(defaultBrowserPackageName)) {
19003                setDefaultBrowserPackageName(null, userId);
19004            }
19005        }
19006    }
19007
19008    @Override
19009    public void resetApplicationPreferences(int userId) {
19010        mContext.enforceCallingOrSelfPermission(
19011                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19012        final long identity = Binder.clearCallingIdentity();
19013        // writer
19014        try {
19015            synchronized (mPackages) {
19016                clearPackagePreferredActivitiesLPw(null, userId);
19017                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19018                // TODO: We have to reset the default SMS and Phone. This requires
19019                // significant refactoring to keep all default apps in the package
19020                // manager (cleaner but more work) or have the services provide
19021                // callbacks to the package manager to request a default app reset.
19022                applyFactoryDefaultBrowserLPw(userId);
19023                clearIntentFilterVerificationsLPw(userId);
19024                primeDomainVerificationsLPw(userId);
19025                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19026                scheduleWritePackageRestrictionsLocked(userId);
19027            }
19028            resetNetworkPolicies(userId);
19029        } finally {
19030            Binder.restoreCallingIdentity(identity);
19031        }
19032    }
19033
19034    @Override
19035    public int getPreferredActivities(List<IntentFilter> outFilters,
19036            List<ComponentName> outActivities, String packageName) {
19037        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19038            return 0;
19039        }
19040        int num = 0;
19041        final int userId = UserHandle.getCallingUserId();
19042        // reader
19043        synchronized (mPackages) {
19044            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19045            if (pir != null) {
19046                final Iterator<PreferredActivity> it = pir.filterIterator();
19047                while (it.hasNext()) {
19048                    final PreferredActivity pa = it.next();
19049                    if (packageName == null
19050                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19051                                    && pa.mPref.mAlways)) {
19052                        if (outFilters != null) {
19053                            outFilters.add(new IntentFilter(pa));
19054                        }
19055                        if (outActivities != null) {
19056                            outActivities.add(pa.mPref.mComponent);
19057                        }
19058                    }
19059                }
19060            }
19061        }
19062
19063        return num;
19064    }
19065
19066    @Override
19067    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19068            int userId) {
19069        int callingUid = Binder.getCallingUid();
19070        if (callingUid != Process.SYSTEM_UID) {
19071            throw new SecurityException(
19072                    "addPersistentPreferredActivity can only be run by the system");
19073        }
19074        if (filter.countActions() == 0) {
19075            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19076            return;
19077        }
19078        synchronized (mPackages) {
19079            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19080                    ":");
19081            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19082            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19083                    new PersistentPreferredActivity(filter, activity));
19084            scheduleWritePackageRestrictionsLocked(userId);
19085            postPreferredActivityChangedBroadcast(userId);
19086        }
19087    }
19088
19089    @Override
19090    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19091        int callingUid = Binder.getCallingUid();
19092        if (callingUid != Process.SYSTEM_UID) {
19093            throw new SecurityException(
19094                    "clearPackagePersistentPreferredActivities can only be run by the system");
19095        }
19096        ArrayList<PersistentPreferredActivity> removed = null;
19097        boolean changed = false;
19098        synchronized (mPackages) {
19099            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19100                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19101                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19102                        .valueAt(i);
19103                if (userId != thisUserId) {
19104                    continue;
19105                }
19106                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19107                while (it.hasNext()) {
19108                    PersistentPreferredActivity ppa = it.next();
19109                    // Mark entry for removal only if it matches the package name.
19110                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19111                        if (removed == null) {
19112                            removed = new ArrayList<PersistentPreferredActivity>();
19113                        }
19114                        removed.add(ppa);
19115                    }
19116                }
19117                if (removed != null) {
19118                    for (int j=0; j<removed.size(); j++) {
19119                        PersistentPreferredActivity ppa = removed.get(j);
19120                        ppir.removeFilter(ppa);
19121                    }
19122                    changed = true;
19123                }
19124            }
19125
19126            if (changed) {
19127                scheduleWritePackageRestrictionsLocked(userId);
19128                postPreferredActivityChangedBroadcast(userId);
19129            }
19130        }
19131    }
19132
19133    /**
19134     * Common machinery for picking apart a restored XML blob and passing
19135     * it to a caller-supplied functor to be applied to the running system.
19136     */
19137    private void restoreFromXml(XmlPullParser parser, int userId,
19138            String expectedStartTag, BlobXmlRestorer functor)
19139            throws IOException, XmlPullParserException {
19140        int type;
19141        while ((type = parser.next()) != XmlPullParser.START_TAG
19142                && type != XmlPullParser.END_DOCUMENT) {
19143        }
19144        if (type != XmlPullParser.START_TAG) {
19145            // oops didn't find a start tag?!
19146            if (DEBUG_BACKUP) {
19147                Slog.e(TAG, "Didn't find start tag during restore");
19148            }
19149            return;
19150        }
19151Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19152        // this is supposed to be TAG_PREFERRED_BACKUP
19153        if (!expectedStartTag.equals(parser.getName())) {
19154            if (DEBUG_BACKUP) {
19155                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19156            }
19157            return;
19158        }
19159
19160        // skip interfering stuff, then we're aligned with the backing implementation
19161        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19162Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19163        functor.apply(parser, userId);
19164    }
19165
19166    private interface BlobXmlRestorer {
19167        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19168    }
19169
19170    /**
19171     * Non-Binder method, support for the backup/restore mechanism: write the
19172     * full set of preferred activities in its canonical XML format.  Returns the
19173     * XML output as a byte array, or null if there is none.
19174     */
19175    @Override
19176    public byte[] getPreferredActivityBackup(int userId) {
19177        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19178            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19179        }
19180
19181        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19182        try {
19183            final XmlSerializer serializer = new FastXmlSerializer();
19184            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19185            serializer.startDocument(null, true);
19186            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19187
19188            synchronized (mPackages) {
19189                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19190            }
19191
19192            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19193            serializer.endDocument();
19194            serializer.flush();
19195        } catch (Exception e) {
19196            if (DEBUG_BACKUP) {
19197                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19198            }
19199            return null;
19200        }
19201
19202        return dataStream.toByteArray();
19203    }
19204
19205    @Override
19206    public void restorePreferredActivities(byte[] backup, int userId) {
19207        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19208            throw new SecurityException("Only the system may call restorePreferredActivities()");
19209        }
19210
19211        try {
19212            final XmlPullParser parser = Xml.newPullParser();
19213            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19214            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19215                    new BlobXmlRestorer() {
19216                        @Override
19217                        public void apply(XmlPullParser parser, int userId)
19218                                throws XmlPullParserException, IOException {
19219                            synchronized (mPackages) {
19220                                mSettings.readPreferredActivitiesLPw(parser, userId);
19221                            }
19222                        }
19223                    } );
19224        } catch (Exception e) {
19225            if (DEBUG_BACKUP) {
19226                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19227            }
19228        }
19229    }
19230
19231    /**
19232     * Non-Binder method, support for the backup/restore mechanism: write the
19233     * default browser (etc) settings in its canonical XML format.  Returns the default
19234     * browser XML representation as a byte array, or null if there is none.
19235     */
19236    @Override
19237    public byte[] getDefaultAppsBackup(int userId) {
19238        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19239            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19240        }
19241
19242        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19243        try {
19244            final XmlSerializer serializer = new FastXmlSerializer();
19245            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19246            serializer.startDocument(null, true);
19247            serializer.startTag(null, TAG_DEFAULT_APPS);
19248
19249            synchronized (mPackages) {
19250                mSettings.writeDefaultAppsLPr(serializer, userId);
19251            }
19252
19253            serializer.endTag(null, TAG_DEFAULT_APPS);
19254            serializer.endDocument();
19255            serializer.flush();
19256        } catch (Exception e) {
19257            if (DEBUG_BACKUP) {
19258                Slog.e(TAG, "Unable to write default apps for backup", e);
19259            }
19260            return null;
19261        }
19262
19263        return dataStream.toByteArray();
19264    }
19265
19266    @Override
19267    public void restoreDefaultApps(byte[] backup, int userId) {
19268        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19269            throw new SecurityException("Only the system may call restoreDefaultApps()");
19270        }
19271
19272        try {
19273            final XmlPullParser parser = Xml.newPullParser();
19274            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19275            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19276                    new BlobXmlRestorer() {
19277                        @Override
19278                        public void apply(XmlPullParser parser, int userId)
19279                                throws XmlPullParserException, IOException {
19280                            synchronized (mPackages) {
19281                                mSettings.readDefaultAppsLPw(parser, userId);
19282                            }
19283                        }
19284                    } );
19285        } catch (Exception e) {
19286            if (DEBUG_BACKUP) {
19287                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19288            }
19289        }
19290    }
19291
19292    @Override
19293    public byte[] getIntentFilterVerificationBackup(int userId) {
19294        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19295            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19296        }
19297
19298        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19299        try {
19300            final XmlSerializer serializer = new FastXmlSerializer();
19301            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19302            serializer.startDocument(null, true);
19303            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19304
19305            synchronized (mPackages) {
19306                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19307            }
19308
19309            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19310            serializer.endDocument();
19311            serializer.flush();
19312        } catch (Exception e) {
19313            if (DEBUG_BACKUP) {
19314                Slog.e(TAG, "Unable to write default apps for backup", e);
19315            }
19316            return null;
19317        }
19318
19319        return dataStream.toByteArray();
19320    }
19321
19322    @Override
19323    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19324        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19325            throw new SecurityException("Only the system may call restorePreferredActivities()");
19326        }
19327
19328        try {
19329            final XmlPullParser parser = Xml.newPullParser();
19330            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19331            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19332                    new BlobXmlRestorer() {
19333                        @Override
19334                        public void apply(XmlPullParser parser, int userId)
19335                                throws XmlPullParserException, IOException {
19336                            synchronized (mPackages) {
19337                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19338                                mSettings.writeLPr();
19339                            }
19340                        }
19341                    } );
19342        } catch (Exception e) {
19343            if (DEBUG_BACKUP) {
19344                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19345            }
19346        }
19347    }
19348
19349    @Override
19350    public byte[] getPermissionGrantBackup(int userId) {
19351        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19352            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19353        }
19354
19355        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19356        try {
19357            final XmlSerializer serializer = new FastXmlSerializer();
19358            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19359            serializer.startDocument(null, true);
19360            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19361
19362            synchronized (mPackages) {
19363                serializeRuntimePermissionGrantsLPr(serializer, userId);
19364            }
19365
19366            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19367            serializer.endDocument();
19368            serializer.flush();
19369        } catch (Exception e) {
19370            if (DEBUG_BACKUP) {
19371                Slog.e(TAG, "Unable to write default apps for backup", e);
19372            }
19373            return null;
19374        }
19375
19376        return dataStream.toByteArray();
19377    }
19378
19379    @Override
19380    public void restorePermissionGrants(byte[] backup, int userId) {
19381        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19382            throw new SecurityException("Only the system may call restorePermissionGrants()");
19383        }
19384
19385        try {
19386            final XmlPullParser parser = Xml.newPullParser();
19387            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19388            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19389                    new BlobXmlRestorer() {
19390                        @Override
19391                        public void apply(XmlPullParser parser, int userId)
19392                                throws XmlPullParserException, IOException {
19393                            synchronized (mPackages) {
19394                                processRestoredPermissionGrantsLPr(parser, userId);
19395                            }
19396                        }
19397                    } );
19398        } catch (Exception e) {
19399            if (DEBUG_BACKUP) {
19400                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19401            }
19402        }
19403    }
19404
19405    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19406            throws IOException {
19407        serializer.startTag(null, TAG_ALL_GRANTS);
19408
19409        final int N = mSettings.mPackages.size();
19410        for (int i = 0; i < N; i++) {
19411            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19412            boolean pkgGrantsKnown = false;
19413
19414            PermissionsState packagePerms = ps.getPermissionsState();
19415
19416            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19417                final int grantFlags = state.getFlags();
19418                // only look at grants that are not system/policy fixed
19419                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19420                    final boolean isGranted = state.isGranted();
19421                    // And only back up the user-twiddled state bits
19422                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19423                        final String packageName = mSettings.mPackages.keyAt(i);
19424                        if (!pkgGrantsKnown) {
19425                            serializer.startTag(null, TAG_GRANT);
19426                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19427                            pkgGrantsKnown = true;
19428                        }
19429
19430                        final boolean userSet =
19431                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19432                        final boolean userFixed =
19433                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19434                        final boolean revoke =
19435                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19436
19437                        serializer.startTag(null, TAG_PERMISSION);
19438                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19439                        if (isGranted) {
19440                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19441                        }
19442                        if (userSet) {
19443                            serializer.attribute(null, ATTR_USER_SET, "true");
19444                        }
19445                        if (userFixed) {
19446                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19447                        }
19448                        if (revoke) {
19449                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19450                        }
19451                        serializer.endTag(null, TAG_PERMISSION);
19452                    }
19453                }
19454            }
19455
19456            if (pkgGrantsKnown) {
19457                serializer.endTag(null, TAG_GRANT);
19458            }
19459        }
19460
19461        serializer.endTag(null, TAG_ALL_GRANTS);
19462    }
19463
19464    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19465            throws XmlPullParserException, IOException {
19466        String pkgName = null;
19467        int outerDepth = parser.getDepth();
19468        int type;
19469        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19470                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19471            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19472                continue;
19473            }
19474
19475            final String tagName = parser.getName();
19476            if (tagName.equals(TAG_GRANT)) {
19477                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19478                if (DEBUG_BACKUP) {
19479                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19480                }
19481            } else if (tagName.equals(TAG_PERMISSION)) {
19482
19483                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19484                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19485
19486                int newFlagSet = 0;
19487                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19488                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19489                }
19490                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19491                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19492                }
19493                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19494                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19495                }
19496                if (DEBUG_BACKUP) {
19497                    Slog.v(TAG, "  + Restoring grant:"
19498                            + " pkg=" + pkgName
19499                            + " perm=" + permName
19500                            + " granted=" + isGranted
19501                            + " bits=0x" + Integer.toHexString(newFlagSet));
19502                }
19503                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19504                if (ps != null) {
19505                    // Already installed so we apply the grant immediately
19506                    if (DEBUG_BACKUP) {
19507                        Slog.v(TAG, "        + already installed; applying");
19508                    }
19509                    PermissionsState perms = ps.getPermissionsState();
19510                    BasePermission bp =
19511                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19512                    if (bp != null) {
19513                        if (isGranted) {
19514                            perms.grantRuntimePermission(bp, userId);
19515                        }
19516                        if (newFlagSet != 0) {
19517                            perms.updatePermissionFlags(
19518                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19519                        }
19520                    }
19521                } else {
19522                    // Need to wait for post-restore install to apply the grant
19523                    if (DEBUG_BACKUP) {
19524                        Slog.v(TAG, "        - not yet installed; saving for later");
19525                    }
19526                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19527                            isGranted, newFlagSet, userId);
19528                }
19529            } else {
19530                PackageManagerService.reportSettingsProblem(Log.WARN,
19531                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19532                XmlUtils.skipCurrentTag(parser);
19533            }
19534        }
19535
19536        scheduleWriteSettingsLocked();
19537        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19538    }
19539
19540    @Override
19541    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19542            int sourceUserId, int targetUserId, int flags) {
19543        mContext.enforceCallingOrSelfPermission(
19544                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19545        int callingUid = Binder.getCallingUid();
19546        enforceOwnerRights(ownerPackage, callingUid);
19547        PackageManagerServiceUtils.enforceShellRestriction(
19548                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19549        if (intentFilter.countActions() == 0) {
19550            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19551            return;
19552        }
19553        synchronized (mPackages) {
19554            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19555                    ownerPackage, targetUserId, flags);
19556            CrossProfileIntentResolver resolver =
19557                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19558            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19559            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19560            if (existing != null) {
19561                int size = existing.size();
19562                for (int i = 0; i < size; i++) {
19563                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19564                        return;
19565                    }
19566                }
19567            }
19568            resolver.addFilter(newFilter);
19569            scheduleWritePackageRestrictionsLocked(sourceUserId);
19570        }
19571    }
19572
19573    @Override
19574    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19575        mContext.enforceCallingOrSelfPermission(
19576                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19577        final int callingUid = Binder.getCallingUid();
19578        enforceOwnerRights(ownerPackage, callingUid);
19579        PackageManagerServiceUtils.enforceShellRestriction(
19580                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19581        synchronized (mPackages) {
19582            CrossProfileIntentResolver resolver =
19583                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19584            ArraySet<CrossProfileIntentFilter> set =
19585                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19586            for (CrossProfileIntentFilter filter : set) {
19587                if (filter.getOwnerPackage().equals(ownerPackage)) {
19588                    resolver.removeFilter(filter);
19589                }
19590            }
19591            scheduleWritePackageRestrictionsLocked(sourceUserId);
19592        }
19593    }
19594
19595    // Enforcing that callingUid is owning pkg on userId
19596    private void enforceOwnerRights(String pkg, int callingUid) {
19597        // The system owns everything.
19598        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19599            return;
19600        }
19601        final int callingUserId = UserHandle.getUserId(callingUid);
19602        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19603        if (pi == null) {
19604            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19605                    + callingUserId);
19606        }
19607        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19608            throw new SecurityException("Calling uid " + callingUid
19609                    + " does not own package " + pkg);
19610        }
19611    }
19612
19613    @Override
19614    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19615        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19616            return null;
19617        }
19618        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19619    }
19620
19621    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19622        UserManagerService ums = UserManagerService.getInstance();
19623        if (ums != null) {
19624            final UserInfo parent = ums.getProfileParent(userId);
19625            final int launcherUid = (parent != null) ? parent.id : userId;
19626            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19627            if (launcherComponent != null) {
19628                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19629                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19630                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19631                        .setPackage(launcherComponent.getPackageName());
19632                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19633            }
19634        }
19635    }
19636
19637    /**
19638     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19639     * then reports the most likely home activity or null if there are more than one.
19640     */
19641    private ComponentName getDefaultHomeActivity(int userId) {
19642        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19643        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19644        if (cn != null) {
19645            return cn;
19646        }
19647
19648        // Find the launcher with the highest priority and return that component if there are no
19649        // other home activity with the same priority.
19650        int lastPriority = Integer.MIN_VALUE;
19651        ComponentName lastComponent = null;
19652        final int size = allHomeCandidates.size();
19653        for (int i = 0; i < size; i++) {
19654            final ResolveInfo ri = allHomeCandidates.get(i);
19655            if (ri.priority > lastPriority) {
19656                lastComponent = ri.activityInfo.getComponentName();
19657                lastPriority = ri.priority;
19658            } else if (ri.priority == lastPriority) {
19659                // Two components found with same priority.
19660                lastComponent = null;
19661            }
19662        }
19663        return lastComponent;
19664    }
19665
19666    private Intent getHomeIntent() {
19667        Intent intent = new Intent(Intent.ACTION_MAIN);
19668        intent.addCategory(Intent.CATEGORY_HOME);
19669        intent.addCategory(Intent.CATEGORY_DEFAULT);
19670        return intent;
19671    }
19672
19673    private IntentFilter getHomeFilter() {
19674        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19675        filter.addCategory(Intent.CATEGORY_HOME);
19676        filter.addCategory(Intent.CATEGORY_DEFAULT);
19677        return filter;
19678    }
19679
19680    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19681            int userId) {
19682        Intent intent  = getHomeIntent();
19683        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19684                PackageManager.GET_META_DATA, userId);
19685        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19686                true, false, false, userId);
19687
19688        allHomeCandidates.clear();
19689        if (list != null) {
19690            for (ResolveInfo ri : list) {
19691                allHomeCandidates.add(ri);
19692            }
19693        }
19694        return (preferred == null || preferred.activityInfo == null)
19695                ? null
19696                : new ComponentName(preferred.activityInfo.packageName,
19697                        preferred.activityInfo.name);
19698    }
19699
19700    @Override
19701    public void setHomeActivity(ComponentName comp, int userId) {
19702        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19703            return;
19704        }
19705        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19706        getHomeActivitiesAsUser(homeActivities, userId);
19707
19708        boolean found = false;
19709
19710        final int size = homeActivities.size();
19711        final ComponentName[] set = new ComponentName[size];
19712        for (int i = 0; i < size; i++) {
19713            final ResolveInfo candidate = homeActivities.get(i);
19714            final ActivityInfo info = candidate.activityInfo;
19715            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19716            set[i] = activityName;
19717            if (!found && activityName.equals(comp)) {
19718                found = true;
19719            }
19720        }
19721        if (!found) {
19722            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19723                    + userId);
19724        }
19725        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19726                set, comp, userId);
19727    }
19728
19729    private @Nullable String getSetupWizardPackageName() {
19730        final Intent intent = new Intent(Intent.ACTION_MAIN);
19731        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19732
19733        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19734                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19735                        | MATCH_DISABLED_COMPONENTS,
19736                UserHandle.myUserId());
19737        if (matches.size() == 1) {
19738            return matches.get(0).getComponentInfo().packageName;
19739        } else {
19740            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19741                    + ": matches=" + matches);
19742            return null;
19743        }
19744    }
19745
19746    private @Nullable String getStorageManagerPackageName() {
19747        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19748
19749        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19750                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19751                        | MATCH_DISABLED_COMPONENTS,
19752                UserHandle.myUserId());
19753        if (matches.size() == 1) {
19754            return matches.get(0).getComponentInfo().packageName;
19755        } else {
19756            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19757                    + matches.size() + ": matches=" + matches);
19758            return null;
19759        }
19760    }
19761
19762    @Override
19763    public void setApplicationEnabledSetting(String appPackageName,
19764            int newState, int flags, int userId, String callingPackage) {
19765        if (!sUserManager.exists(userId)) return;
19766        if (callingPackage == null) {
19767            callingPackage = Integer.toString(Binder.getCallingUid());
19768        }
19769        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19770    }
19771
19772    @Override
19773    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19774        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19775        synchronized (mPackages) {
19776            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19777            if (pkgSetting != null) {
19778                pkgSetting.setUpdateAvailable(updateAvailable);
19779            }
19780        }
19781    }
19782
19783    @Override
19784    public void setComponentEnabledSetting(ComponentName componentName,
19785            int newState, int flags, int userId) {
19786        if (!sUserManager.exists(userId)) return;
19787        setEnabledSetting(componentName.getPackageName(),
19788                componentName.getClassName(), newState, flags, userId, null);
19789    }
19790
19791    private void setEnabledSetting(final String packageName, String className, int newState,
19792            final int flags, int userId, String callingPackage) {
19793        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19794              || newState == COMPONENT_ENABLED_STATE_ENABLED
19795              || newState == COMPONENT_ENABLED_STATE_DISABLED
19796              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19797              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19798            throw new IllegalArgumentException("Invalid new component state: "
19799                    + newState);
19800        }
19801        PackageSetting pkgSetting;
19802        final int callingUid = Binder.getCallingUid();
19803        final int permission;
19804        if (callingUid == Process.SYSTEM_UID) {
19805            permission = PackageManager.PERMISSION_GRANTED;
19806        } else {
19807            permission = mContext.checkCallingOrSelfPermission(
19808                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19809        }
19810        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19811                false /* requireFullPermission */, true /* checkShell */, "set enabled");
19812        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19813        boolean sendNow = false;
19814        boolean isApp = (className == null);
19815        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
19816        String componentName = isApp ? packageName : className;
19817        int packageUid = -1;
19818        ArrayList<String> components;
19819
19820        // reader
19821        synchronized (mPackages) {
19822            pkgSetting = mSettings.mPackages.get(packageName);
19823            if (pkgSetting == null) {
19824                if (!isCallerInstantApp) {
19825                    if (className == null) {
19826                        throw new IllegalArgumentException("Unknown package: " + packageName);
19827                    }
19828                    throw new IllegalArgumentException(
19829                            "Unknown component: " + packageName + "/" + className);
19830                } else {
19831                    // throw SecurityException to prevent leaking package information
19832                    throw new SecurityException(
19833                            "Attempt to change component state; "
19834                            + "pid=" + Binder.getCallingPid()
19835                            + ", uid=" + callingUid
19836                            + (className == null
19837                                    ? ", package=" + packageName
19838                                    : ", component=" + packageName + "/" + className));
19839                }
19840            }
19841        }
19842
19843        // Limit who can change which apps
19844        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
19845            // Don't allow apps that don't have permission to modify other apps
19846            if (!allowedByPermission
19847                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
19848                throw new SecurityException(
19849                        "Attempt to change component state; "
19850                        + "pid=" + Binder.getCallingPid()
19851                        + ", uid=" + callingUid
19852                        + (className == null
19853                                ? ", package=" + packageName
19854                                : ", component=" + packageName + "/" + className));
19855            }
19856            // Don't allow changing protected packages.
19857            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
19858                throw new SecurityException("Cannot disable a protected package: " + packageName);
19859            }
19860        }
19861
19862        synchronized (mPackages) {
19863            if (callingUid == Process.SHELL_UID
19864                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
19865                // Shell can only change whole packages between ENABLED and DISABLED_USER states
19866                // unless it is a test package.
19867                int oldState = pkgSetting.getEnabled(userId);
19868                if (className == null
19869                        &&
19870                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
19871                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
19872                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
19873                        &&
19874                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19875                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
19876                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
19877                    // ok
19878                } else {
19879                    throw new SecurityException(
19880                            "Shell cannot change component state for " + packageName + "/"
19881                                    + className + " to " + newState);
19882                }
19883            }
19884        }
19885        if (className == null) {
19886            // We're dealing with an application/package level state change
19887            synchronized (mPackages) {
19888                if (pkgSetting.getEnabled(userId) == newState) {
19889                    // Nothing to do
19890                    return;
19891                }
19892            }
19893            // If we're enabling a system stub, there's a little more work to do.
19894            // Prior to enabling the package, we need to decompress the APK(s) to the
19895            // data partition and then replace the version on the system partition.
19896            final PackageParser.Package deletedPkg = pkgSetting.pkg;
19897            final boolean isSystemStub = deletedPkg.isStub
19898                    && deletedPkg.isSystem();
19899            if (isSystemStub
19900                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19901                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
19902                final File codePath = decompressPackage(deletedPkg);
19903                if (codePath == null) {
19904                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
19905                    return;
19906                }
19907                // TODO remove direct parsing of the package object during internal cleanup
19908                // of scan package
19909                // We need to call parse directly here for no other reason than we need
19910                // the new package in order to disable the old one [we use the information
19911                // for some internal optimization to optionally create a new package setting
19912                // object on replace]. However, we can't get the package from the scan
19913                // because the scan modifies live structures and we need to remove the
19914                // old [system] package from the system before a scan can be attempted.
19915                // Once scan is indempotent we can remove this parse and use the package
19916                // object we scanned, prior to adding it to package settings.
19917                final PackageParser pp = new PackageParser();
19918                pp.setSeparateProcesses(mSeparateProcesses);
19919                pp.setDisplayMetrics(mMetrics);
19920                pp.setCallback(mPackageParserCallback);
19921                final PackageParser.Package tmpPkg;
19922                try {
19923                    final @ParseFlags int parseFlags = mDefParseFlags
19924                            | PackageParser.PARSE_MUST_BE_APK
19925                            | PackageParser.PARSE_IS_SYSTEM_DIR;
19926                    tmpPkg = pp.parsePackage(codePath, parseFlags);
19927                } catch (PackageParserException e) {
19928                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
19929                    return;
19930                }
19931                synchronized (mInstallLock) {
19932                    // Disable the stub and remove any package entries
19933                    removePackageLI(deletedPkg, true);
19934                    synchronized (mPackages) {
19935                        disableSystemPackageLPw(deletedPkg, tmpPkg);
19936                    }
19937                    final PackageParser.Package pkg;
19938                    try (PackageFreezer freezer =
19939                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
19940                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
19941                                | PackageParser.PARSE_ENFORCE_CODE;
19942                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
19943                                0 /*currentTime*/, null /*user*/);
19944                        prepareAppDataAfterInstallLIF(pkg);
19945                        synchronized (mPackages) {
19946                            try {
19947                                updateSharedLibrariesLPr(pkg, null);
19948                            } catch (PackageManagerException e) {
19949                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
19950                            }
19951                            mPermissionManager.updatePermissions(
19952                                    pkg.packageName, pkg, true, mPackages.values(),
19953                                    mPermissionCallback);
19954                            mSettings.writeLPr();
19955                        }
19956                    } catch (PackageManagerException e) {
19957                        // Whoops! Something went wrong; try to roll back to the stub
19958                        Slog.w(TAG, "Failed to install compressed system package:"
19959                                + pkgSetting.name, e);
19960                        // Remove the failed install
19961                        removeCodePathLI(codePath);
19962
19963                        // Install the system package
19964                        try (PackageFreezer freezer =
19965                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
19966                            synchronized (mPackages) {
19967                                // NOTE: The system package always needs to be enabled; even
19968                                // if it's for a compressed stub. If we don't, installing the
19969                                // system package fails during scan [scanning checks the disabled
19970                                // packages]. We will reverse this later, after we've "installed"
19971                                // the stub.
19972                                // This leaves us in a fragile state; the stub should never be
19973                                // enabled, so, cross your fingers and hope nothing goes wrong
19974                                // until we can disable the package later.
19975                                enableSystemPackageLPw(deletedPkg);
19976                            }
19977                            installPackageFromSystemLIF(deletedPkg.codePath,
19978                                    false /*isPrivileged*/, null /*allUserHandles*/,
19979                                    null /*origUserHandles*/, null /*origPermissionsState*/,
19980                                    true /*writeSettings*/);
19981                        } catch (PackageManagerException pme) {
19982                            Slog.w(TAG, "Failed to restore system package:"
19983                                    + deletedPkg.packageName, pme);
19984                        } finally {
19985                            synchronized (mPackages) {
19986                                mSettings.disableSystemPackageLPw(
19987                                        deletedPkg.packageName, true /*replaced*/);
19988                                mSettings.writeLPr();
19989                            }
19990                        }
19991                        return;
19992                    }
19993                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
19994                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19995                    clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19996                    mDexManager.notifyPackageUpdated(pkg.packageName,
19997                            pkg.baseCodePath, pkg.splitCodePaths);
19998                }
19999            }
20000            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20001                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20002                // Don't care about who enables an app.
20003                callingPackage = null;
20004            }
20005            synchronized (mPackages) {
20006                pkgSetting.setEnabled(newState, userId, callingPackage);
20007            }
20008        } else {
20009            synchronized (mPackages) {
20010                // We're dealing with a component level state change
20011                // First, verify that this is a valid class name.
20012                PackageParser.Package pkg = pkgSetting.pkg;
20013                if (pkg == null || !pkg.hasComponentClassName(className)) {
20014                    if (pkg != null &&
20015                            pkg.applicationInfo.targetSdkVersion >=
20016                                    Build.VERSION_CODES.JELLY_BEAN) {
20017                        throw new IllegalArgumentException("Component class " + className
20018                                + " does not exist in " + packageName);
20019                    } else {
20020                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20021                                + className + " does not exist in " + packageName);
20022                    }
20023                }
20024                switch (newState) {
20025                    case COMPONENT_ENABLED_STATE_ENABLED:
20026                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20027                            return;
20028                        }
20029                        break;
20030                    case COMPONENT_ENABLED_STATE_DISABLED:
20031                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20032                            return;
20033                        }
20034                        break;
20035                    case COMPONENT_ENABLED_STATE_DEFAULT:
20036                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20037                            return;
20038                        }
20039                        break;
20040                    default:
20041                        Slog.e(TAG, "Invalid new component state: " + newState);
20042                        return;
20043                }
20044            }
20045        }
20046        synchronized (mPackages) {
20047            scheduleWritePackageRestrictionsLocked(userId);
20048            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20049            final long callingId = Binder.clearCallingIdentity();
20050            try {
20051                updateInstantAppInstallerLocked(packageName);
20052            } finally {
20053                Binder.restoreCallingIdentity(callingId);
20054            }
20055            components = mPendingBroadcasts.get(userId, packageName);
20056            final boolean newPackage = components == null;
20057            if (newPackage) {
20058                components = new ArrayList<String>();
20059            }
20060            if (!components.contains(componentName)) {
20061                components.add(componentName);
20062            }
20063            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20064                sendNow = true;
20065                // Purge entry from pending broadcast list if another one exists already
20066                // since we are sending one right away.
20067                mPendingBroadcasts.remove(userId, packageName);
20068            } else {
20069                if (newPackage) {
20070                    mPendingBroadcasts.put(userId, packageName, components);
20071                }
20072                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20073                    // Schedule a message
20074                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20075                }
20076            }
20077        }
20078
20079        long callingId = Binder.clearCallingIdentity();
20080        try {
20081            if (sendNow) {
20082                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20083                sendPackageChangedBroadcast(packageName,
20084                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20085            }
20086        } finally {
20087            Binder.restoreCallingIdentity(callingId);
20088        }
20089    }
20090
20091    @Override
20092    public void flushPackageRestrictionsAsUser(int userId) {
20093        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20094            return;
20095        }
20096        if (!sUserManager.exists(userId)) {
20097            return;
20098        }
20099        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20100                false /* checkShell */, "flushPackageRestrictions");
20101        synchronized (mPackages) {
20102            mSettings.writePackageRestrictionsLPr(userId);
20103            mDirtyUsers.remove(userId);
20104            if (mDirtyUsers.isEmpty()) {
20105                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20106            }
20107        }
20108    }
20109
20110    private void sendPackageChangedBroadcast(String packageName,
20111            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20112        if (DEBUG_INSTALL)
20113            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20114                    + componentNames);
20115        Bundle extras = new Bundle(4);
20116        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20117        String nameList[] = new String[componentNames.size()];
20118        componentNames.toArray(nameList);
20119        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20120        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20121        extras.putInt(Intent.EXTRA_UID, packageUid);
20122        // If this is not reporting a change of the overall package, then only send it
20123        // to registered receivers.  We don't want to launch a swath of apps for every
20124        // little component state change.
20125        final int flags = !componentNames.contains(packageName)
20126                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20127        final int userId = UserHandle.getUserId(packageUid);
20128        final boolean isInstantApp = isInstantApp(packageName, userId);
20129        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20130        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20131        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20132                userIds, instantUserIds);
20133    }
20134
20135    @Override
20136    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20137        if (!sUserManager.exists(userId)) return;
20138        final int callingUid = Binder.getCallingUid();
20139        if (getInstantAppPackageName(callingUid) != null) {
20140            return;
20141        }
20142        final int permission = mContext.checkCallingOrSelfPermission(
20143                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20144        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20145        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20146                true /* requireFullPermission */, true /* checkShell */, "stop package");
20147        // writer
20148        synchronized (mPackages) {
20149            final PackageSetting ps = mSettings.mPackages.get(packageName);
20150            if (!filterAppAccessLPr(ps, callingUid, userId)
20151                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20152                            allowedByPermission, callingUid, userId)) {
20153                scheduleWritePackageRestrictionsLocked(userId);
20154            }
20155        }
20156    }
20157
20158    @Override
20159    public String getInstallerPackageName(String packageName) {
20160        final int callingUid = Binder.getCallingUid();
20161        if (getInstantAppPackageName(callingUid) != null) {
20162            return null;
20163        }
20164        // reader
20165        synchronized (mPackages) {
20166            final PackageSetting ps = mSettings.mPackages.get(packageName);
20167            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20168                return null;
20169            }
20170            return mSettings.getInstallerPackageNameLPr(packageName);
20171        }
20172    }
20173
20174    public boolean isOrphaned(String packageName) {
20175        // reader
20176        synchronized (mPackages) {
20177            return mSettings.isOrphaned(packageName);
20178        }
20179    }
20180
20181    @Override
20182    public int getApplicationEnabledSetting(String packageName, int userId) {
20183        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20184        int callingUid = Binder.getCallingUid();
20185        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20186                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20187        // reader
20188        synchronized (mPackages) {
20189            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20190                return COMPONENT_ENABLED_STATE_DISABLED;
20191            }
20192            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20193        }
20194    }
20195
20196    @Override
20197    public int getComponentEnabledSetting(ComponentName component, int userId) {
20198        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20199        int callingUid = Binder.getCallingUid();
20200        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20201                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20202        synchronized (mPackages) {
20203            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20204                    component, TYPE_UNKNOWN, userId)) {
20205                return COMPONENT_ENABLED_STATE_DISABLED;
20206            }
20207            return mSettings.getComponentEnabledSettingLPr(component, userId);
20208        }
20209    }
20210
20211    @Override
20212    public void enterSafeMode() {
20213        enforceSystemOrRoot("Only the system can request entering safe mode");
20214
20215        if (!mSystemReady) {
20216            mSafeMode = true;
20217        }
20218    }
20219
20220    @Override
20221    public void systemReady() {
20222        enforceSystemOrRoot("Only the system can claim the system is ready");
20223
20224        mSystemReady = true;
20225        final ContentResolver resolver = mContext.getContentResolver();
20226        ContentObserver co = new ContentObserver(mHandler) {
20227            @Override
20228            public void onChange(boolean selfChange) {
20229                mEphemeralAppsDisabled =
20230                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20231                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20232            }
20233        };
20234        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20235                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20236                false, co, UserHandle.USER_SYSTEM);
20237        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20238                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20239        co.onChange(true);
20240
20241        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20242        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20243        // it is done.
20244        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20245            @Override
20246            public void onChange(boolean selfChange) {
20247                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20248                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20249                        oobEnabled == 1 ? "true" : "false");
20250            }
20251        };
20252        mContext.getContentResolver().registerContentObserver(
20253                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20254                UserHandle.USER_SYSTEM);
20255        // At boot, restore the value from the setting, which persists across reboot.
20256        privAppOobObserver.onChange(true);
20257
20258        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20259        // disabled after already being started.
20260        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20261                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20262
20263        // Read the compatibilty setting when the system is ready.
20264        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20265                mContext.getContentResolver(),
20266                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20267        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20268        if (DEBUG_SETTINGS) {
20269            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20270        }
20271
20272        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20273
20274        synchronized (mPackages) {
20275            // Verify that all of the preferred activity components actually
20276            // exist.  It is possible for applications to be updated and at
20277            // that point remove a previously declared activity component that
20278            // had been set as a preferred activity.  We try to clean this up
20279            // the next time we encounter that preferred activity, but it is
20280            // possible for the user flow to never be able to return to that
20281            // situation so here we do a sanity check to make sure we haven't
20282            // left any junk around.
20283            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20284            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20285                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20286                removed.clear();
20287                for (PreferredActivity pa : pir.filterSet()) {
20288                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20289                        removed.add(pa);
20290                    }
20291                }
20292                if (removed.size() > 0) {
20293                    for (int r=0; r<removed.size(); r++) {
20294                        PreferredActivity pa = removed.get(r);
20295                        Slog.w(TAG, "Removing dangling preferred activity: "
20296                                + pa.mPref.mComponent);
20297                        pir.removeFilter(pa);
20298                    }
20299                    mSettings.writePackageRestrictionsLPr(
20300                            mSettings.mPreferredActivities.keyAt(i));
20301                }
20302            }
20303
20304            for (int userId : UserManagerService.getInstance().getUserIds()) {
20305                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20306                    grantPermissionsUserIds = ArrayUtils.appendInt(
20307                            grantPermissionsUserIds, userId);
20308                }
20309            }
20310        }
20311        sUserManager.systemReady();
20312        // If we upgraded grant all default permissions before kicking off.
20313        for (int userId : grantPermissionsUserIds) {
20314            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20315        }
20316
20317        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20318            // If we did not grant default permissions, we preload from this the
20319            // default permission exceptions lazily to ensure we don't hit the
20320            // disk on a new user creation.
20321            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20322        }
20323
20324        // Now that we've scanned all packages, and granted any default
20325        // permissions, ensure permissions are updated. Beware of dragons if you
20326        // try optimizing this.
20327        synchronized (mPackages) {
20328            mPermissionManager.updateAllPermissions(
20329                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20330                    mPermissionCallback);
20331        }
20332
20333        // Kick off any messages waiting for system ready
20334        if (mPostSystemReadyMessages != null) {
20335            for (Message msg : mPostSystemReadyMessages) {
20336                msg.sendToTarget();
20337            }
20338            mPostSystemReadyMessages = null;
20339        }
20340
20341        // Watch for external volumes that come and go over time
20342        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20343        storage.registerListener(mStorageListener);
20344
20345        mInstallerService.systemReady();
20346        mPackageDexOptimizer.systemReady();
20347
20348        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20349                StorageManagerInternal.class);
20350        StorageManagerInternal.addExternalStoragePolicy(
20351                new StorageManagerInternal.ExternalStorageMountPolicy() {
20352            @Override
20353            public int getMountMode(int uid, String packageName) {
20354                if (Process.isIsolated(uid)) {
20355                    return Zygote.MOUNT_EXTERNAL_NONE;
20356                }
20357                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20358                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20359                }
20360                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20361                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20362                }
20363                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20364                    return Zygote.MOUNT_EXTERNAL_READ;
20365                }
20366                return Zygote.MOUNT_EXTERNAL_WRITE;
20367            }
20368
20369            @Override
20370            public boolean hasExternalStorage(int uid, String packageName) {
20371                return true;
20372            }
20373        });
20374
20375        // Now that we're mostly running, clean up stale users and apps
20376        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20377        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20378
20379        mPermissionManager.systemReady();
20380    }
20381
20382    public void waitForAppDataPrepared() {
20383        if (mPrepareAppDataFuture == null) {
20384            return;
20385        }
20386        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20387        mPrepareAppDataFuture = null;
20388    }
20389
20390    @Override
20391    public boolean isSafeMode() {
20392        // allow instant applications
20393        return mSafeMode;
20394    }
20395
20396    @Override
20397    public boolean hasSystemUidErrors() {
20398        // allow instant applications
20399        return mHasSystemUidErrors;
20400    }
20401
20402    static String arrayToString(int[] array) {
20403        StringBuffer buf = new StringBuffer(128);
20404        buf.append('[');
20405        if (array != null) {
20406            for (int i=0; i<array.length; i++) {
20407                if (i > 0) buf.append(", ");
20408                buf.append(array[i]);
20409            }
20410        }
20411        buf.append(']');
20412        return buf.toString();
20413    }
20414
20415    @Override
20416    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20417            FileDescriptor err, String[] args, ShellCallback callback,
20418            ResultReceiver resultReceiver) {
20419        (new PackageManagerShellCommand(this)).exec(
20420                this, in, out, err, args, callback, resultReceiver);
20421    }
20422
20423    @Override
20424    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20425        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20426
20427        DumpState dumpState = new DumpState();
20428        boolean fullPreferred = false;
20429        boolean checkin = false;
20430
20431        String packageName = null;
20432        ArraySet<String> permissionNames = null;
20433
20434        int opti = 0;
20435        while (opti < args.length) {
20436            String opt = args[opti];
20437            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20438                break;
20439            }
20440            opti++;
20441
20442            if ("-a".equals(opt)) {
20443                // Right now we only know how to print all.
20444            } else if ("-h".equals(opt)) {
20445                pw.println("Package manager dump options:");
20446                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20447                pw.println("    --checkin: dump for a checkin");
20448                pw.println("    -f: print details of intent filters");
20449                pw.println("    -h: print this help");
20450                pw.println("  cmd may be one of:");
20451                pw.println("    l[ibraries]: list known shared libraries");
20452                pw.println("    f[eatures]: list device features");
20453                pw.println("    k[eysets]: print known keysets");
20454                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20455                pw.println("    perm[issions]: dump permissions");
20456                pw.println("    permission [name ...]: dump declaration and use of given permission");
20457                pw.println("    pref[erred]: print preferred package settings");
20458                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20459                pw.println("    prov[iders]: dump content providers");
20460                pw.println("    p[ackages]: dump installed packages");
20461                pw.println("    s[hared-users]: dump shared user IDs");
20462                pw.println("    m[essages]: print collected runtime messages");
20463                pw.println("    v[erifiers]: print package verifier info");
20464                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20465                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20466                pw.println("    version: print database version info");
20467                pw.println("    write: write current settings now");
20468                pw.println("    installs: details about install sessions");
20469                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20470                pw.println("    dexopt: dump dexopt state");
20471                pw.println("    compiler-stats: dump compiler statistics");
20472                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20473                pw.println("    service-permissions: dump permissions required by services");
20474                pw.println("    <package.name>: info about given package");
20475                return;
20476            } else if ("--checkin".equals(opt)) {
20477                checkin = true;
20478            } else if ("-f".equals(opt)) {
20479                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20480            } else if ("--proto".equals(opt)) {
20481                dumpProto(fd);
20482                return;
20483            } else {
20484                pw.println("Unknown argument: " + opt + "; use -h for help");
20485            }
20486        }
20487
20488        // Is the caller requesting to dump a particular piece of data?
20489        if (opti < args.length) {
20490            String cmd = args[opti];
20491            opti++;
20492            // Is this a package name?
20493            if ("android".equals(cmd) || cmd.contains(".")) {
20494                packageName = cmd;
20495                // When dumping a single package, we always dump all of its
20496                // filter information since the amount of data will be reasonable.
20497                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20498            } else if ("check-permission".equals(cmd)) {
20499                if (opti >= args.length) {
20500                    pw.println("Error: check-permission missing permission argument");
20501                    return;
20502                }
20503                String perm = args[opti];
20504                opti++;
20505                if (opti >= args.length) {
20506                    pw.println("Error: check-permission missing package argument");
20507                    return;
20508                }
20509
20510                String pkg = args[opti];
20511                opti++;
20512                int user = UserHandle.getUserId(Binder.getCallingUid());
20513                if (opti < args.length) {
20514                    try {
20515                        user = Integer.parseInt(args[opti]);
20516                    } catch (NumberFormatException e) {
20517                        pw.println("Error: check-permission user argument is not a number: "
20518                                + args[opti]);
20519                        return;
20520                    }
20521                }
20522
20523                // Normalize package name to handle renamed packages and static libs
20524                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20525
20526                pw.println(checkPermission(perm, pkg, user));
20527                return;
20528            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20529                dumpState.setDump(DumpState.DUMP_LIBS);
20530            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20531                dumpState.setDump(DumpState.DUMP_FEATURES);
20532            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20533                if (opti >= args.length) {
20534                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20535                            | DumpState.DUMP_SERVICE_RESOLVERS
20536                            | DumpState.DUMP_RECEIVER_RESOLVERS
20537                            | DumpState.DUMP_CONTENT_RESOLVERS);
20538                } else {
20539                    while (opti < args.length) {
20540                        String name = args[opti];
20541                        if ("a".equals(name) || "activity".equals(name)) {
20542                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20543                        } else if ("s".equals(name) || "service".equals(name)) {
20544                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20545                        } else if ("r".equals(name) || "receiver".equals(name)) {
20546                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20547                        } else if ("c".equals(name) || "content".equals(name)) {
20548                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20549                        } else {
20550                            pw.println("Error: unknown resolver table type: " + name);
20551                            return;
20552                        }
20553                        opti++;
20554                    }
20555                }
20556            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20557                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20558            } else if ("permission".equals(cmd)) {
20559                if (opti >= args.length) {
20560                    pw.println("Error: permission requires permission name");
20561                    return;
20562                }
20563                permissionNames = new ArraySet<>();
20564                while (opti < args.length) {
20565                    permissionNames.add(args[opti]);
20566                    opti++;
20567                }
20568                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20569                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20570            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20571                dumpState.setDump(DumpState.DUMP_PREFERRED);
20572            } else if ("preferred-xml".equals(cmd)) {
20573                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20574                if (opti < args.length && "--full".equals(args[opti])) {
20575                    fullPreferred = true;
20576                    opti++;
20577                }
20578            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20579                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20580            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20581                dumpState.setDump(DumpState.DUMP_PACKAGES);
20582            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20583                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20584            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20585                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20586            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20587                dumpState.setDump(DumpState.DUMP_MESSAGES);
20588            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20589                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20590            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20591                    || "intent-filter-verifiers".equals(cmd)) {
20592                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20593            } else if ("version".equals(cmd)) {
20594                dumpState.setDump(DumpState.DUMP_VERSION);
20595            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20596                dumpState.setDump(DumpState.DUMP_KEYSETS);
20597            } else if ("installs".equals(cmd)) {
20598                dumpState.setDump(DumpState.DUMP_INSTALLS);
20599            } else if ("frozen".equals(cmd)) {
20600                dumpState.setDump(DumpState.DUMP_FROZEN);
20601            } else if ("volumes".equals(cmd)) {
20602                dumpState.setDump(DumpState.DUMP_VOLUMES);
20603            } else if ("dexopt".equals(cmd)) {
20604                dumpState.setDump(DumpState.DUMP_DEXOPT);
20605            } else if ("compiler-stats".equals(cmd)) {
20606                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20607            } else if ("changes".equals(cmd)) {
20608                dumpState.setDump(DumpState.DUMP_CHANGES);
20609            } else if ("service-permissions".equals(cmd)) {
20610                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
20611            } else if ("write".equals(cmd)) {
20612                synchronized (mPackages) {
20613                    mSettings.writeLPr();
20614                    pw.println("Settings written.");
20615                    return;
20616                }
20617            }
20618        }
20619
20620        if (checkin) {
20621            pw.println("vers,1");
20622        }
20623
20624        // reader
20625        synchronized (mPackages) {
20626            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20627                if (!checkin) {
20628                    if (dumpState.onTitlePrinted())
20629                        pw.println();
20630                    pw.println("Database versions:");
20631                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20632                }
20633            }
20634
20635            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20636                if (!checkin) {
20637                    if (dumpState.onTitlePrinted())
20638                        pw.println();
20639                    pw.println("Verifiers:");
20640                    pw.print("  Required: ");
20641                    pw.print(mRequiredVerifierPackage);
20642                    pw.print(" (uid=");
20643                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20644                            UserHandle.USER_SYSTEM));
20645                    pw.println(")");
20646                } else if (mRequiredVerifierPackage != null) {
20647                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20648                    pw.print(",");
20649                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20650                            UserHandle.USER_SYSTEM));
20651                }
20652            }
20653
20654            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20655                    packageName == null) {
20656                if (mIntentFilterVerifierComponent != null) {
20657                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20658                    if (!checkin) {
20659                        if (dumpState.onTitlePrinted())
20660                            pw.println();
20661                        pw.println("Intent Filter Verifier:");
20662                        pw.print("  Using: ");
20663                        pw.print(verifierPackageName);
20664                        pw.print(" (uid=");
20665                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20666                                UserHandle.USER_SYSTEM));
20667                        pw.println(")");
20668                    } else if (verifierPackageName != null) {
20669                        pw.print("ifv,"); pw.print(verifierPackageName);
20670                        pw.print(",");
20671                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20672                                UserHandle.USER_SYSTEM));
20673                    }
20674                } else {
20675                    pw.println();
20676                    pw.println("No Intent Filter Verifier available!");
20677                }
20678            }
20679
20680            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20681                boolean printedHeader = false;
20682                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20683                while (it.hasNext()) {
20684                    String libName = it.next();
20685                    LongSparseArray<SharedLibraryEntry> versionedLib
20686                            = mSharedLibraries.get(libName);
20687                    if (versionedLib == null) {
20688                        continue;
20689                    }
20690                    final int versionCount = versionedLib.size();
20691                    for (int i = 0; i < versionCount; i++) {
20692                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20693                        if (!checkin) {
20694                            if (!printedHeader) {
20695                                if (dumpState.onTitlePrinted())
20696                                    pw.println();
20697                                pw.println("Libraries:");
20698                                printedHeader = true;
20699                            }
20700                            pw.print("  ");
20701                        } else {
20702                            pw.print("lib,");
20703                        }
20704                        pw.print(libEntry.info.getName());
20705                        if (libEntry.info.isStatic()) {
20706                            pw.print(" version=" + libEntry.info.getLongVersion());
20707                        }
20708                        if (!checkin) {
20709                            pw.print(" -> ");
20710                        }
20711                        if (libEntry.path != null) {
20712                            pw.print(" (jar) ");
20713                            pw.print(libEntry.path);
20714                        } else {
20715                            pw.print(" (apk) ");
20716                            pw.print(libEntry.apk);
20717                        }
20718                        pw.println();
20719                    }
20720                }
20721            }
20722
20723            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20724                if (dumpState.onTitlePrinted())
20725                    pw.println();
20726                if (!checkin) {
20727                    pw.println("Features:");
20728                }
20729
20730                synchronized (mAvailableFeatures) {
20731                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20732                        if (checkin) {
20733                            pw.print("feat,");
20734                            pw.print(feat.name);
20735                            pw.print(",");
20736                            pw.println(feat.version);
20737                        } else {
20738                            pw.print("  ");
20739                            pw.print(feat.name);
20740                            if (feat.version > 0) {
20741                                pw.print(" version=");
20742                                pw.print(feat.version);
20743                            }
20744                            pw.println();
20745                        }
20746                    }
20747                }
20748            }
20749
20750            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20751                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20752                        : "Activity Resolver Table:", "  ", packageName,
20753                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20754                    dumpState.setTitlePrinted(true);
20755                }
20756            }
20757            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20758                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20759                        : "Receiver Resolver Table:", "  ", packageName,
20760                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20761                    dumpState.setTitlePrinted(true);
20762                }
20763            }
20764            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20765                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20766                        : "Service Resolver Table:", "  ", packageName,
20767                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20768                    dumpState.setTitlePrinted(true);
20769                }
20770            }
20771            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20772                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20773                        : "Provider Resolver Table:", "  ", packageName,
20774                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20775                    dumpState.setTitlePrinted(true);
20776                }
20777            }
20778
20779            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20780                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20781                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20782                    int user = mSettings.mPreferredActivities.keyAt(i);
20783                    if (pir.dump(pw,
20784                            dumpState.getTitlePrinted()
20785                                ? "\nPreferred Activities User " + user + ":"
20786                                : "Preferred Activities User " + user + ":", "  ",
20787                            packageName, true, false)) {
20788                        dumpState.setTitlePrinted(true);
20789                    }
20790                }
20791            }
20792
20793            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20794                pw.flush();
20795                FileOutputStream fout = new FileOutputStream(fd);
20796                BufferedOutputStream str = new BufferedOutputStream(fout);
20797                XmlSerializer serializer = new FastXmlSerializer();
20798                try {
20799                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20800                    serializer.startDocument(null, true);
20801                    serializer.setFeature(
20802                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20803                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20804                    serializer.endDocument();
20805                    serializer.flush();
20806                } catch (IllegalArgumentException e) {
20807                    pw.println("Failed writing: " + e);
20808                } catch (IllegalStateException e) {
20809                    pw.println("Failed writing: " + e);
20810                } catch (IOException e) {
20811                    pw.println("Failed writing: " + e);
20812                }
20813            }
20814
20815            if (!checkin
20816                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20817                    && packageName == null) {
20818                pw.println();
20819                int count = mSettings.mPackages.size();
20820                if (count == 0) {
20821                    pw.println("No applications!");
20822                    pw.println();
20823                } else {
20824                    final String prefix = "  ";
20825                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20826                    if (allPackageSettings.size() == 0) {
20827                        pw.println("No domain preferred apps!");
20828                        pw.println();
20829                    } else {
20830                        pw.println("App verification status:");
20831                        pw.println();
20832                        count = 0;
20833                        for (PackageSetting ps : allPackageSettings) {
20834                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20835                            if (ivi == null || ivi.getPackageName() == null) continue;
20836                            pw.println(prefix + "Package: " + ivi.getPackageName());
20837                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
20838                            pw.println(prefix + "Status:  " + ivi.getStatusString());
20839                            pw.println();
20840                            count++;
20841                        }
20842                        if (count == 0) {
20843                            pw.println(prefix + "No app verification established.");
20844                            pw.println();
20845                        }
20846                        for (int userId : sUserManager.getUserIds()) {
20847                            pw.println("App linkages for user " + userId + ":");
20848                            pw.println();
20849                            count = 0;
20850                            for (PackageSetting ps : allPackageSettings) {
20851                                final long status = ps.getDomainVerificationStatusForUser(userId);
20852                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20853                                        && !DEBUG_DOMAIN_VERIFICATION) {
20854                                    continue;
20855                                }
20856                                pw.println(prefix + "Package: " + ps.name);
20857                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20858                                String statusStr = IntentFilterVerificationInfo.
20859                                        getStatusStringFromValue(status);
20860                                pw.println(prefix + "Status:  " + statusStr);
20861                                pw.println();
20862                                count++;
20863                            }
20864                            if (count == 0) {
20865                                pw.println(prefix + "No configured app linkages.");
20866                                pw.println();
20867                            }
20868                        }
20869                    }
20870                }
20871            }
20872
20873            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
20874                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
20875            }
20876
20877            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
20878                boolean printedSomething = false;
20879                for (PackageParser.Provider p : mProviders.mProviders.values()) {
20880                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20881                        continue;
20882                    }
20883                    if (!printedSomething) {
20884                        if (dumpState.onTitlePrinted())
20885                            pw.println();
20886                        pw.println("Registered ContentProviders:");
20887                        printedSomething = true;
20888                    }
20889                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
20890                    pw.print("    "); pw.println(p.toString());
20891                }
20892                printedSomething = false;
20893                for (Map.Entry<String, PackageParser.Provider> entry :
20894                        mProvidersByAuthority.entrySet()) {
20895                    PackageParser.Provider p = entry.getValue();
20896                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20897                        continue;
20898                    }
20899                    if (!printedSomething) {
20900                        if (dumpState.onTitlePrinted())
20901                            pw.println();
20902                        pw.println("ContentProvider Authorities:");
20903                        printedSomething = true;
20904                    }
20905                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
20906                    pw.print("    "); pw.println(p.toString());
20907                    if (p.info != null && p.info.applicationInfo != null) {
20908                        final String appInfo = p.info.applicationInfo.toString();
20909                        pw.print("      applicationInfo="); pw.println(appInfo);
20910                    }
20911                }
20912            }
20913
20914            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
20915                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
20916            }
20917
20918            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
20919                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
20920            }
20921
20922            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
20923                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
20924            }
20925
20926            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
20927                if (dumpState.onTitlePrinted()) pw.println();
20928                pw.println("Package Changes:");
20929                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
20930                final int K = mChangedPackages.size();
20931                for (int i = 0; i < K; i++) {
20932                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
20933                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
20934                    final int N = changes.size();
20935                    if (N == 0) {
20936                        pw.print("    "); pw.println("No packages changed");
20937                    } else {
20938                        for (int j = 0; j < N; j++) {
20939                            final String pkgName = changes.valueAt(j);
20940                            final int sequenceNumber = changes.keyAt(j);
20941                            pw.print("    ");
20942                            pw.print("seq=");
20943                            pw.print(sequenceNumber);
20944                            pw.print(", package=");
20945                            pw.println(pkgName);
20946                        }
20947                    }
20948                }
20949            }
20950
20951            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
20952                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
20953            }
20954
20955            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
20956                // XXX should handle packageName != null by dumping only install data that
20957                // the given package is involved with.
20958                if (dumpState.onTitlePrinted()) pw.println();
20959
20960                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20961                ipw.println();
20962                ipw.println("Frozen packages:");
20963                ipw.increaseIndent();
20964                if (mFrozenPackages.size() == 0) {
20965                    ipw.println("(none)");
20966                } else {
20967                    for (int i = 0; i < mFrozenPackages.size(); i++) {
20968                        ipw.println(mFrozenPackages.valueAt(i));
20969                    }
20970                }
20971                ipw.decreaseIndent();
20972            }
20973
20974            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
20975                if (dumpState.onTitlePrinted()) pw.println();
20976
20977                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20978                ipw.println();
20979                ipw.println("Loaded volumes:");
20980                ipw.increaseIndent();
20981                if (mLoadedVolumes.size() == 0) {
20982                    ipw.println("(none)");
20983                } else {
20984                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
20985                        ipw.println(mLoadedVolumes.valueAt(i));
20986                    }
20987                }
20988                ipw.decreaseIndent();
20989            }
20990
20991            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
20992                    && packageName == null) {
20993                if (dumpState.onTitlePrinted()) pw.println();
20994                pw.println("Service permissions:");
20995
20996                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
20997                while (filterIterator.hasNext()) {
20998                    final ServiceIntentInfo info = filterIterator.next();
20999                    final ServiceInfo serviceInfo = info.service.info;
21000                    final String permission = serviceInfo.permission;
21001                    if (permission != null) {
21002                        pw.print("    ");
21003                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21004                        pw.print(": ");
21005                        pw.println(permission);
21006                    }
21007                }
21008            }
21009
21010            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21011                if (dumpState.onTitlePrinted()) pw.println();
21012                dumpDexoptStateLPr(pw, packageName);
21013            }
21014
21015            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21016                if (dumpState.onTitlePrinted()) pw.println();
21017                dumpCompilerStatsLPr(pw, packageName);
21018            }
21019
21020            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21021                if (dumpState.onTitlePrinted()) pw.println();
21022                mSettings.dumpReadMessagesLPr(pw, dumpState);
21023
21024                pw.println();
21025                pw.println("Package warning messages:");
21026                dumpCriticalInfo(pw, null);
21027            }
21028
21029            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21030                dumpCriticalInfo(pw, "msg,");
21031            }
21032        }
21033
21034        // PackageInstaller should be called outside of mPackages lock
21035        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21036            // XXX should handle packageName != null by dumping only install data that
21037            // the given package is involved with.
21038            if (dumpState.onTitlePrinted()) pw.println();
21039            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21040        }
21041    }
21042
21043    private void dumpProto(FileDescriptor fd) {
21044        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21045
21046        synchronized (mPackages) {
21047            final long requiredVerifierPackageToken =
21048                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21049            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21050            proto.write(
21051                    PackageServiceDumpProto.PackageShortProto.UID,
21052                    getPackageUid(
21053                            mRequiredVerifierPackage,
21054                            MATCH_DEBUG_TRIAGED_MISSING,
21055                            UserHandle.USER_SYSTEM));
21056            proto.end(requiredVerifierPackageToken);
21057
21058            if (mIntentFilterVerifierComponent != null) {
21059                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21060                final long verifierPackageToken =
21061                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21062                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21063                proto.write(
21064                        PackageServiceDumpProto.PackageShortProto.UID,
21065                        getPackageUid(
21066                                verifierPackageName,
21067                                MATCH_DEBUG_TRIAGED_MISSING,
21068                                UserHandle.USER_SYSTEM));
21069                proto.end(verifierPackageToken);
21070            }
21071
21072            dumpSharedLibrariesProto(proto);
21073            dumpFeaturesProto(proto);
21074            mSettings.dumpPackagesProto(proto);
21075            mSettings.dumpSharedUsersProto(proto);
21076            dumpCriticalInfo(proto);
21077        }
21078        proto.flush();
21079    }
21080
21081    private void dumpFeaturesProto(ProtoOutputStream proto) {
21082        synchronized (mAvailableFeatures) {
21083            final int count = mAvailableFeatures.size();
21084            for (int i = 0; i < count; i++) {
21085                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21086            }
21087        }
21088    }
21089
21090    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21091        final int count = mSharedLibraries.size();
21092        for (int i = 0; i < count; i++) {
21093            final String libName = mSharedLibraries.keyAt(i);
21094            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21095            if (versionedLib == null) {
21096                continue;
21097            }
21098            final int versionCount = versionedLib.size();
21099            for (int j = 0; j < versionCount; j++) {
21100                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21101                final long sharedLibraryToken =
21102                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21103                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21104                final boolean isJar = (libEntry.path != null);
21105                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21106                if (isJar) {
21107                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21108                } else {
21109                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21110                }
21111                proto.end(sharedLibraryToken);
21112            }
21113        }
21114    }
21115
21116    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21117        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21118        ipw.println();
21119        ipw.println("Dexopt state:");
21120        ipw.increaseIndent();
21121        Collection<PackageParser.Package> packages = null;
21122        if (packageName != null) {
21123            PackageParser.Package targetPackage = mPackages.get(packageName);
21124            if (targetPackage != null) {
21125                packages = Collections.singletonList(targetPackage);
21126            } else {
21127                ipw.println("Unable to find package: " + packageName);
21128                return;
21129            }
21130        } else {
21131            packages = mPackages.values();
21132        }
21133
21134        for (PackageParser.Package pkg : packages) {
21135            ipw.println("[" + pkg.packageName + "]");
21136            ipw.increaseIndent();
21137            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21138                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21139            ipw.decreaseIndent();
21140        }
21141    }
21142
21143    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21144        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21145        ipw.println();
21146        ipw.println("Compiler stats:");
21147        ipw.increaseIndent();
21148        Collection<PackageParser.Package> packages = null;
21149        if (packageName != null) {
21150            PackageParser.Package targetPackage = mPackages.get(packageName);
21151            if (targetPackage != null) {
21152                packages = Collections.singletonList(targetPackage);
21153            } else {
21154                ipw.println("Unable to find package: " + packageName);
21155                return;
21156            }
21157        } else {
21158            packages = mPackages.values();
21159        }
21160
21161        for (PackageParser.Package pkg : packages) {
21162            ipw.println("[" + pkg.packageName + "]");
21163            ipw.increaseIndent();
21164
21165            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21166            if (stats == null) {
21167                ipw.println("(No recorded stats)");
21168            } else {
21169                stats.dump(ipw);
21170            }
21171            ipw.decreaseIndent();
21172        }
21173    }
21174
21175    private String dumpDomainString(String packageName) {
21176        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21177                .getList();
21178        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21179
21180        ArraySet<String> result = new ArraySet<>();
21181        if (iviList.size() > 0) {
21182            for (IntentFilterVerificationInfo ivi : iviList) {
21183                for (String host : ivi.getDomains()) {
21184                    result.add(host);
21185                }
21186            }
21187        }
21188        if (filters != null && filters.size() > 0) {
21189            for (IntentFilter filter : filters) {
21190                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21191                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21192                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21193                    result.addAll(filter.getHostsList());
21194                }
21195            }
21196        }
21197
21198        StringBuilder sb = new StringBuilder(result.size() * 16);
21199        for (String domain : result) {
21200            if (sb.length() > 0) sb.append(" ");
21201            sb.append(domain);
21202        }
21203        return sb.toString();
21204    }
21205
21206    // ------- apps on sdcard specific code -------
21207    static final boolean DEBUG_SD_INSTALL = false;
21208
21209    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21210
21211    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21212
21213    private boolean mMediaMounted = false;
21214
21215    static String getEncryptKey() {
21216        try {
21217            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21218                    SD_ENCRYPTION_KEYSTORE_NAME);
21219            if (sdEncKey == null) {
21220                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21221                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21222                if (sdEncKey == null) {
21223                    Slog.e(TAG, "Failed to create encryption keys");
21224                    return null;
21225                }
21226            }
21227            return sdEncKey;
21228        } catch (NoSuchAlgorithmException nsae) {
21229            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21230            return null;
21231        } catch (IOException ioe) {
21232            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21233            return null;
21234        }
21235    }
21236
21237    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21238            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21239        final int size = infos.size();
21240        final String[] packageNames = new String[size];
21241        final int[] packageUids = new int[size];
21242        for (int i = 0; i < size; i++) {
21243            final ApplicationInfo info = infos.get(i);
21244            packageNames[i] = info.packageName;
21245            packageUids[i] = info.uid;
21246        }
21247        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21248                finishedReceiver);
21249    }
21250
21251    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21252            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21253        sendResourcesChangedBroadcast(mediaStatus, replacing,
21254                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21255    }
21256
21257    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21258            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21259        int size = pkgList.length;
21260        if (size > 0) {
21261            // Send broadcasts here
21262            Bundle extras = new Bundle();
21263            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21264            if (uidArr != null) {
21265                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21266            }
21267            if (replacing) {
21268                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21269            }
21270            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21271                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21272            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21273        }
21274    }
21275
21276    private void loadPrivatePackages(final VolumeInfo vol) {
21277        mHandler.post(new Runnable() {
21278            @Override
21279            public void run() {
21280                loadPrivatePackagesInner(vol);
21281            }
21282        });
21283    }
21284
21285    private void loadPrivatePackagesInner(VolumeInfo vol) {
21286        final String volumeUuid = vol.fsUuid;
21287        if (TextUtils.isEmpty(volumeUuid)) {
21288            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21289            return;
21290        }
21291
21292        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21293        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21294        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21295
21296        final VersionInfo ver;
21297        final List<PackageSetting> packages;
21298        synchronized (mPackages) {
21299            ver = mSettings.findOrCreateVersion(volumeUuid);
21300            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21301        }
21302
21303        for (PackageSetting ps : packages) {
21304            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21305            synchronized (mInstallLock) {
21306                final PackageParser.Package pkg;
21307                try {
21308                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21309                    loaded.add(pkg.applicationInfo);
21310
21311                } catch (PackageManagerException e) {
21312                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21313                }
21314
21315                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21316                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21317                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21318                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21319                }
21320            }
21321        }
21322
21323        // Reconcile app data for all started/unlocked users
21324        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21325        final UserManager um = mContext.getSystemService(UserManager.class);
21326        UserManagerInternal umInternal = getUserManagerInternal();
21327        for (UserInfo user : um.getUsers()) {
21328            final int flags;
21329            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21330                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21331            } else if (umInternal.isUserRunning(user.id)) {
21332                flags = StorageManager.FLAG_STORAGE_DE;
21333            } else {
21334                continue;
21335            }
21336
21337            try {
21338                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21339                synchronized (mInstallLock) {
21340                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21341                }
21342            } catch (IllegalStateException e) {
21343                // Device was probably ejected, and we'll process that event momentarily
21344                Slog.w(TAG, "Failed to prepare storage: " + e);
21345            }
21346        }
21347
21348        synchronized (mPackages) {
21349            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21350            if (sdkUpdated) {
21351                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21352                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21353            }
21354            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21355                    mPermissionCallback);
21356
21357            // Yay, everything is now upgraded
21358            ver.forceCurrent();
21359
21360            mSettings.writeLPr();
21361        }
21362
21363        for (PackageFreezer freezer : freezers) {
21364            freezer.close();
21365        }
21366
21367        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21368        sendResourcesChangedBroadcast(true, false, loaded, null);
21369        mLoadedVolumes.add(vol.getId());
21370    }
21371
21372    private void unloadPrivatePackages(final VolumeInfo vol) {
21373        mHandler.post(new Runnable() {
21374            @Override
21375            public void run() {
21376                unloadPrivatePackagesInner(vol);
21377            }
21378        });
21379    }
21380
21381    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21382        final String volumeUuid = vol.fsUuid;
21383        if (TextUtils.isEmpty(volumeUuid)) {
21384            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21385            return;
21386        }
21387
21388        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21389        synchronized (mInstallLock) {
21390        synchronized (mPackages) {
21391            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21392            for (PackageSetting ps : packages) {
21393                if (ps.pkg == null) continue;
21394
21395                final ApplicationInfo info = ps.pkg.applicationInfo;
21396                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21397                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21398
21399                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21400                        "unloadPrivatePackagesInner")) {
21401                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21402                            false, null)) {
21403                        unloaded.add(info);
21404                    } else {
21405                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21406                    }
21407                }
21408
21409                // Try very hard to release any references to this package
21410                // so we don't risk the system server being killed due to
21411                // open FDs
21412                AttributeCache.instance().removePackage(ps.name);
21413            }
21414
21415            mSettings.writeLPr();
21416        }
21417        }
21418
21419        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21420        sendResourcesChangedBroadcast(false, false, unloaded, null);
21421        mLoadedVolumes.remove(vol.getId());
21422
21423        // Try very hard to release any references to this path so we don't risk
21424        // the system server being killed due to open FDs
21425        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21426
21427        for (int i = 0; i < 3; i++) {
21428            System.gc();
21429            System.runFinalization();
21430        }
21431    }
21432
21433    private void assertPackageKnown(String volumeUuid, String packageName)
21434            throws PackageManagerException {
21435        synchronized (mPackages) {
21436            // Normalize package name to handle renamed packages
21437            packageName = normalizePackageNameLPr(packageName);
21438
21439            final PackageSetting ps = mSettings.mPackages.get(packageName);
21440            if (ps == null) {
21441                throw new PackageManagerException("Package " + packageName + " is unknown");
21442            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21443                throw new PackageManagerException(
21444                        "Package " + packageName + " found on unknown volume " + volumeUuid
21445                                + "; expected volume " + ps.volumeUuid);
21446            }
21447        }
21448    }
21449
21450    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21451            throws PackageManagerException {
21452        synchronized (mPackages) {
21453            // Normalize package name to handle renamed packages
21454            packageName = normalizePackageNameLPr(packageName);
21455
21456            final PackageSetting ps = mSettings.mPackages.get(packageName);
21457            if (ps == null) {
21458                throw new PackageManagerException("Package " + packageName + " is unknown");
21459            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21460                throw new PackageManagerException(
21461                        "Package " + packageName + " found on unknown volume " + volumeUuid
21462                                + "; expected volume " + ps.volumeUuid);
21463            } else if (!ps.getInstalled(userId)) {
21464                throw new PackageManagerException(
21465                        "Package " + packageName + " not installed for user " + userId);
21466            }
21467        }
21468    }
21469
21470    private List<String> collectAbsoluteCodePaths() {
21471        synchronized (mPackages) {
21472            List<String> codePaths = new ArrayList<>();
21473            final int packageCount = mSettings.mPackages.size();
21474            for (int i = 0; i < packageCount; i++) {
21475                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21476                codePaths.add(ps.codePath.getAbsolutePath());
21477            }
21478            return codePaths;
21479        }
21480    }
21481
21482    /**
21483     * Examine all apps present on given mounted volume, and destroy apps that
21484     * aren't expected, either due to uninstallation or reinstallation on
21485     * another volume.
21486     */
21487    private void reconcileApps(String volumeUuid) {
21488        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21489        List<File> filesToDelete = null;
21490
21491        final File[] files = FileUtils.listFilesOrEmpty(
21492                Environment.getDataAppDirectory(volumeUuid));
21493        for (File file : files) {
21494            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21495                    && !PackageInstallerService.isStageName(file.getName());
21496            if (!isPackage) {
21497                // Ignore entries which are not packages
21498                continue;
21499            }
21500
21501            String absolutePath = file.getAbsolutePath();
21502
21503            boolean pathValid = false;
21504            final int absoluteCodePathCount = absoluteCodePaths.size();
21505            for (int i = 0; i < absoluteCodePathCount; i++) {
21506                String absoluteCodePath = absoluteCodePaths.get(i);
21507                if (absolutePath.startsWith(absoluteCodePath)) {
21508                    pathValid = true;
21509                    break;
21510                }
21511            }
21512
21513            if (!pathValid) {
21514                if (filesToDelete == null) {
21515                    filesToDelete = new ArrayList<>();
21516                }
21517                filesToDelete.add(file);
21518            }
21519        }
21520
21521        if (filesToDelete != null) {
21522            final int fileToDeleteCount = filesToDelete.size();
21523            for (int i = 0; i < fileToDeleteCount; i++) {
21524                File fileToDelete = filesToDelete.get(i);
21525                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21526                synchronized (mInstallLock) {
21527                    removeCodePathLI(fileToDelete);
21528                }
21529            }
21530        }
21531    }
21532
21533    /**
21534     * Reconcile all app data for the given user.
21535     * <p>
21536     * Verifies that directories exist and that ownership and labeling is
21537     * correct for all installed apps on all mounted volumes.
21538     */
21539    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21540        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21541        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21542            final String volumeUuid = vol.getFsUuid();
21543            synchronized (mInstallLock) {
21544                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21545            }
21546        }
21547    }
21548
21549    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21550            boolean migrateAppData) {
21551        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21552    }
21553
21554    /**
21555     * Reconcile all app data on given mounted volume.
21556     * <p>
21557     * Destroys app data that isn't expected, either due to uninstallation or
21558     * reinstallation on another volume.
21559     * <p>
21560     * Verifies that directories exist and that ownership and labeling is
21561     * correct for all installed apps.
21562     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
21563     */
21564    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21565            boolean migrateAppData, boolean onlyCoreApps) {
21566        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21567                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21568        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21569
21570        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21571        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21572
21573        // First look for stale data that doesn't belong, and check if things
21574        // have changed since we did our last restorecon
21575        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21576            if (StorageManager.isFileEncryptedNativeOrEmulated()
21577                    && !StorageManager.isUserKeyUnlocked(userId)) {
21578                throw new RuntimeException(
21579                        "Yikes, someone asked us to reconcile CE storage while " + userId
21580                                + " was still locked; this would have caused massive data loss!");
21581            }
21582
21583            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21584            for (File file : files) {
21585                final String packageName = file.getName();
21586                try {
21587                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21588                } catch (PackageManagerException e) {
21589                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21590                    try {
21591                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21592                                StorageManager.FLAG_STORAGE_CE, 0);
21593                    } catch (InstallerException e2) {
21594                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21595                    }
21596                }
21597            }
21598        }
21599        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21600            final File[] files = FileUtils.listFilesOrEmpty(deDir);
21601            for (File file : files) {
21602                final String packageName = file.getName();
21603                try {
21604                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21605                } catch (PackageManagerException e) {
21606                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21607                    try {
21608                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21609                                StorageManager.FLAG_STORAGE_DE, 0);
21610                    } catch (InstallerException e2) {
21611                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21612                    }
21613                }
21614            }
21615        }
21616
21617        // Ensure that data directories are ready to roll for all packages
21618        // installed for this volume and user
21619        final List<PackageSetting> packages;
21620        synchronized (mPackages) {
21621            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21622        }
21623        int preparedCount = 0;
21624        for (PackageSetting ps : packages) {
21625            final String packageName = ps.name;
21626            if (ps.pkg == null) {
21627                Slog.w(TAG, "Odd, missing scanned package " + packageName);
21628                // TODO: might be due to legacy ASEC apps; we should circle back
21629                // and reconcile again once they're scanned
21630                continue;
21631            }
21632            // Skip non-core apps if requested
21633            if (onlyCoreApps && !ps.pkg.coreApp) {
21634                result.add(packageName);
21635                continue;
21636            }
21637
21638            if (ps.getInstalled(userId)) {
21639                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21640                preparedCount++;
21641            }
21642        }
21643
21644        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21645        return result;
21646    }
21647
21648    /**
21649     * Prepare app data for the given app just after it was installed or
21650     * upgraded. This method carefully only touches users that it's installed
21651     * for, and it forces a restorecon to handle any seinfo changes.
21652     * <p>
21653     * Verifies that directories exist and that ownership and labeling is
21654     * correct for all installed apps. If there is an ownership mismatch, it
21655     * will try recovering system apps by wiping data; third-party app data is
21656     * left intact.
21657     * <p>
21658     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21659     */
21660    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21661        final PackageSetting ps;
21662        synchronized (mPackages) {
21663            ps = mSettings.mPackages.get(pkg.packageName);
21664            mSettings.writeKernelMappingLPr(ps);
21665        }
21666
21667        final UserManager um = mContext.getSystemService(UserManager.class);
21668        UserManagerInternal umInternal = getUserManagerInternal();
21669        for (UserInfo user : um.getUsers()) {
21670            final int flags;
21671            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21672                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21673            } else if (umInternal.isUserRunning(user.id)) {
21674                flags = StorageManager.FLAG_STORAGE_DE;
21675            } else {
21676                continue;
21677            }
21678
21679            if (ps.getInstalled(user.id)) {
21680                // TODO: when user data is locked, mark that we're still dirty
21681                prepareAppDataLIF(pkg, user.id, flags);
21682            }
21683        }
21684    }
21685
21686    /**
21687     * Prepare app data for the given app.
21688     * <p>
21689     * Verifies that directories exist and that ownership and labeling is
21690     * correct for all installed apps. If there is an ownership mismatch, this
21691     * will try recovering system apps by wiping data; third-party app data is
21692     * left intact.
21693     */
21694    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21695        if (pkg == null) {
21696            Slog.wtf(TAG, "Package was null!", new Throwable());
21697            return;
21698        }
21699        prepareAppDataLeafLIF(pkg, userId, flags);
21700        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21701        for (int i = 0; i < childCount; i++) {
21702            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21703        }
21704    }
21705
21706    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
21707            boolean maybeMigrateAppData) {
21708        prepareAppDataLIF(pkg, userId, flags);
21709
21710        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21711            // We may have just shuffled around app data directories, so
21712            // prepare them one more time
21713            prepareAppDataLIF(pkg, userId, flags);
21714        }
21715    }
21716
21717    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21718        if (DEBUG_APP_DATA) {
21719            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21720                    + Integer.toHexString(flags));
21721        }
21722
21723        final String volumeUuid = pkg.volumeUuid;
21724        final String packageName = pkg.packageName;
21725        final ApplicationInfo app = pkg.applicationInfo;
21726        final int appId = UserHandle.getAppId(app.uid);
21727
21728        Preconditions.checkNotNull(app.seInfo);
21729
21730        long ceDataInode = -1;
21731        try {
21732            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21733                    appId, app.seInfo, app.targetSdkVersion);
21734        } catch (InstallerException e) {
21735            if (app.isSystemApp()) {
21736                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21737                        + ", but trying to recover: " + e);
21738                destroyAppDataLeafLIF(pkg, userId, flags);
21739                try {
21740                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21741                            appId, app.seInfo, app.targetSdkVersion);
21742                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21743                } catch (InstallerException e2) {
21744                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
21745                }
21746            } else {
21747                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21748            }
21749        }
21750
21751        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21752            // TODO: mark this structure as dirty so we persist it!
21753            synchronized (mPackages) {
21754                final PackageSetting ps = mSettings.mPackages.get(packageName);
21755                if (ps != null) {
21756                    ps.setCeDataInode(ceDataInode, userId);
21757                }
21758            }
21759        }
21760
21761        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21762    }
21763
21764    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21765        if (pkg == null) {
21766            Slog.wtf(TAG, "Package was null!", new Throwable());
21767            return;
21768        }
21769        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21770        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21771        for (int i = 0; i < childCount; i++) {
21772            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21773        }
21774    }
21775
21776    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21777        final String volumeUuid = pkg.volumeUuid;
21778        final String packageName = pkg.packageName;
21779        final ApplicationInfo app = pkg.applicationInfo;
21780
21781        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21782            // Create a native library symlink only if we have native libraries
21783            // and if the native libraries are 32 bit libraries. We do not provide
21784            // this symlink for 64 bit libraries.
21785            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21786                final String nativeLibPath = app.nativeLibraryDir;
21787                try {
21788                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21789                            nativeLibPath, userId);
21790                } catch (InstallerException e) {
21791                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21792                }
21793            }
21794        }
21795    }
21796
21797    /**
21798     * For system apps on non-FBE devices, this method migrates any existing
21799     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21800     * requested by the app.
21801     */
21802    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
21803        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
21804                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
21805            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
21806                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
21807            try {
21808                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
21809                        storageTarget);
21810            } catch (InstallerException e) {
21811                logCriticalInfo(Log.WARN,
21812                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
21813            }
21814            return true;
21815        } else {
21816            return false;
21817        }
21818    }
21819
21820    public PackageFreezer freezePackage(String packageName, String killReason) {
21821        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
21822    }
21823
21824    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
21825        return new PackageFreezer(packageName, userId, killReason);
21826    }
21827
21828    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
21829            String killReason) {
21830        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
21831    }
21832
21833    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
21834            String killReason) {
21835        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
21836            return new PackageFreezer();
21837        } else {
21838            return freezePackage(packageName, userId, killReason);
21839        }
21840    }
21841
21842    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
21843            String killReason) {
21844        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
21845    }
21846
21847    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
21848            String killReason) {
21849        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
21850            return new PackageFreezer();
21851        } else {
21852            return freezePackage(packageName, userId, killReason);
21853        }
21854    }
21855
21856    /**
21857     * Class that freezes and kills the given package upon creation, and
21858     * unfreezes it upon closing. This is typically used when doing surgery on
21859     * app code/data to prevent the app from running while you're working.
21860     */
21861    private class PackageFreezer implements AutoCloseable {
21862        private final String mPackageName;
21863        private final PackageFreezer[] mChildren;
21864
21865        private final boolean mWeFroze;
21866
21867        private final AtomicBoolean mClosed = new AtomicBoolean();
21868        private final CloseGuard mCloseGuard = CloseGuard.get();
21869
21870        /**
21871         * Create and return a stub freezer that doesn't actually do anything,
21872         * typically used when someone requested
21873         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
21874         * {@link PackageManager#DELETE_DONT_KILL_APP}.
21875         */
21876        public PackageFreezer() {
21877            mPackageName = null;
21878            mChildren = null;
21879            mWeFroze = false;
21880            mCloseGuard.open("close");
21881        }
21882
21883        public PackageFreezer(String packageName, int userId, String killReason) {
21884            synchronized (mPackages) {
21885                mPackageName = packageName;
21886                mWeFroze = mFrozenPackages.add(mPackageName);
21887
21888                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
21889                if (ps != null) {
21890                    killApplication(ps.name, ps.appId, userId, killReason);
21891                }
21892
21893                final PackageParser.Package p = mPackages.get(packageName);
21894                if (p != null && p.childPackages != null) {
21895                    final int N = p.childPackages.size();
21896                    mChildren = new PackageFreezer[N];
21897                    for (int i = 0; i < N; i++) {
21898                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
21899                                userId, killReason);
21900                    }
21901                } else {
21902                    mChildren = null;
21903                }
21904            }
21905            mCloseGuard.open("close");
21906        }
21907
21908        @Override
21909        protected void finalize() throws Throwable {
21910            try {
21911                if (mCloseGuard != null) {
21912                    mCloseGuard.warnIfOpen();
21913                }
21914
21915                close();
21916            } finally {
21917                super.finalize();
21918            }
21919        }
21920
21921        @Override
21922        public void close() {
21923            mCloseGuard.close();
21924            if (mClosed.compareAndSet(false, true)) {
21925                synchronized (mPackages) {
21926                    if (mWeFroze) {
21927                        mFrozenPackages.remove(mPackageName);
21928                    }
21929
21930                    if (mChildren != null) {
21931                        for (PackageFreezer freezer : mChildren) {
21932                            freezer.close();
21933                        }
21934                    }
21935                }
21936            }
21937        }
21938    }
21939
21940    /**
21941     * Verify that given package is currently frozen.
21942     */
21943    private void checkPackageFrozen(String packageName) {
21944        synchronized (mPackages) {
21945            if (!mFrozenPackages.contains(packageName)) {
21946                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
21947            }
21948        }
21949    }
21950
21951    @Override
21952    public int movePackage(final String packageName, final String volumeUuid) {
21953        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
21954
21955        final int callingUid = Binder.getCallingUid();
21956        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
21957        final int moveId = mNextMoveId.getAndIncrement();
21958        mHandler.post(new Runnable() {
21959            @Override
21960            public void run() {
21961                try {
21962                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
21963                } catch (PackageManagerException e) {
21964                    Slog.w(TAG, "Failed to move " + packageName, e);
21965                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
21966                }
21967            }
21968        });
21969        return moveId;
21970    }
21971
21972    private void movePackageInternal(final String packageName, final String volumeUuid,
21973            final int moveId, final int callingUid, UserHandle user)
21974                    throws PackageManagerException {
21975        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21976        final PackageManager pm = mContext.getPackageManager();
21977
21978        final boolean currentAsec;
21979        final String currentVolumeUuid;
21980        final File codeFile;
21981        final String installerPackageName;
21982        final String packageAbiOverride;
21983        final int appId;
21984        final String seinfo;
21985        final String label;
21986        final int targetSdkVersion;
21987        final PackageFreezer freezer;
21988        final int[] installedUserIds;
21989
21990        // reader
21991        synchronized (mPackages) {
21992            final PackageParser.Package pkg = mPackages.get(packageName);
21993            final PackageSetting ps = mSettings.mPackages.get(packageName);
21994            if (pkg == null
21995                    || ps == null
21996                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
21997                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
21998            }
21999            if (pkg.applicationInfo.isSystemApp()) {
22000                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22001                        "Cannot move system application");
22002            }
22003
22004            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22005            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22006                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22007            if (isInternalStorage && !allow3rdPartyOnInternal) {
22008                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22009                        "3rd party apps are not allowed on internal storage");
22010            }
22011
22012            if (pkg.applicationInfo.isExternalAsec()) {
22013                currentAsec = true;
22014                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22015            } else if (pkg.applicationInfo.isForwardLocked()) {
22016                currentAsec = true;
22017                currentVolumeUuid = "forward_locked";
22018            } else {
22019                currentAsec = false;
22020                currentVolumeUuid = ps.volumeUuid;
22021
22022                final File probe = new File(pkg.codePath);
22023                final File probeOat = new File(probe, "oat");
22024                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22025                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22026                            "Move only supported for modern cluster style installs");
22027                }
22028            }
22029
22030            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22031                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22032                        "Package already moved to " + volumeUuid);
22033            }
22034            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22035                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22036                        "Device admin cannot be moved");
22037            }
22038
22039            if (mFrozenPackages.contains(packageName)) {
22040                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22041                        "Failed to move already frozen package");
22042            }
22043
22044            codeFile = new File(pkg.codePath);
22045            installerPackageName = ps.installerPackageName;
22046            packageAbiOverride = ps.cpuAbiOverrideString;
22047            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22048            seinfo = pkg.applicationInfo.seInfo;
22049            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22050            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22051            freezer = freezePackage(packageName, "movePackageInternal");
22052            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22053        }
22054
22055        final Bundle extras = new Bundle();
22056        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22057        extras.putString(Intent.EXTRA_TITLE, label);
22058        mMoveCallbacks.notifyCreated(moveId, extras);
22059
22060        int installFlags;
22061        final boolean moveCompleteApp;
22062        final File measurePath;
22063
22064        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22065            installFlags = INSTALL_INTERNAL;
22066            moveCompleteApp = !currentAsec;
22067            measurePath = Environment.getDataAppDirectory(volumeUuid);
22068        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22069            installFlags = INSTALL_EXTERNAL;
22070            moveCompleteApp = false;
22071            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22072        } else {
22073            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22074            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22075                    || !volume.isMountedWritable()) {
22076                freezer.close();
22077                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22078                        "Move location not mounted private volume");
22079            }
22080
22081            Preconditions.checkState(!currentAsec);
22082
22083            installFlags = INSTALL_INTERNAL;
22084            moveCompleteApp = true;
22085            measurePath = Environment.getDataAppDirectory(volumeUuid);
22086        }
22087
22088        // If we're moving app data around, we need all the users unlocked
22089        if (moveCompleteApp) {
22090            for (int userId : installedUserIds) {
22091                if (StorageManager.isFileEncryptedNativeOrEmulated()
22092                        && !StorageManager.isUserKeyUnlocked(userId)) {
22093                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22094                            "User " + userId + " must be unlocked");
22095                }
22096            }
22097        }
22098
22099        final PackageStats stats = new PackageStats(null, -1);
22100        synchronized (mInstaller) {
22101            for (int userId : installedUserIds) {
22102                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22103                    freezer.close();
22104                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22105                            "Failed to measure package size");
22106                }
22107            }
22108        }
22109
22110        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22111                + stats.dataSize);
22112
22113        final long startFreeBytes = measurePath.getUsableSpace();
22114        final long sizeBytes;
22115        if (moveCompleteApp) {
22116            sizeBytes = stats.codeSize + stats.dataSize;
22117        } else {
22118            sizeBytes = stats.codeSize;
22119        }
22120
22121        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22122            freezer.close();
22123            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22124                    "Not enough free space to move");
22125        }
22126
22127        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22128
22129        final CountDownLatch installedLatch = new CountDownLatch(1);
22130        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22131            @Override
22132            public void onUserActionRequired(Intent intent) throws RemoteException {
22133                throw new IllegalStateException();
22134            }
22135
22136            @Override
22137            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22138                    Bundle extras) throws RemoteException {
22139                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22140                        + PackageManager.installStatusToString(returnCode, msg));
22141
22142                installedLatch.countDown();
22143                freezer.close();
22144
22145                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22146                switch (status) {
22147                    case PackageInstaller.STATUS_SUCCESS:
22148                        mMoveCallbacks.notifyStatusChanged(moveId,
22149                                PackageManager.MOVE_SUCCEEDED);
22150                        break;
22151                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22152                        mMoveCallbacks.notifyStatusChanged(moveId,
22153                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22154                        break;
22155                    default:
22156                        mMoveCallbacks.notifyStatusChanged(moveId,
22157                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22158                        break;
22159                }
22160            }
22161        };
22162
22163        final MoveInfo move;
22164        if (moveCompleteApp) {
22165            // Kick off a thread to report progress estimates
22166            new Thread() {
22167                @Override
22168                public void run() {
22169                    while (true) {
22170                        try {
22171                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22172                                break;
22173                            }
22174                        } catch (InterruptedException ignored) {
22175                        }
22176
22177                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22178                        final int progress = 10 + (int) MathUtils.constrain(
22179                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22180                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22181                    }
22182                }
22183            }.start();
22184
22185            final String dataAppName = codeFile.getName();
22186            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22187                    dataAppName, appId, seinfo, targetSdkVersion);
22188        } else {
22189            move = null;
22190        }
22191
22192        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22193
22194        final Message msg = mHandler.obtainMessage(INIT_COPY);
22195        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22196        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22197                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22198                packageAbiOverride, null /*grantedPermissions*/,
22199                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
22200        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22201        msg.obj = params;
22202
22203        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22204                System.identityHashCode(msg.obj));
22205        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22206                System.identityHashCode(msg.obj));
22207
22208        mHandler.sendMessage(msg);
22209    }
22210
22211    @Override
22212    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22213        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22214
22215        final int realMoveId = mNextMoveId.getAndIncrement();
22216        final Bundle extras = new Bundle();
22217        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22218        mMoveCallbacks.notifyCreated(realMoveId, extras);
22219
22220        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22221            @Override
22222            public void onCreated(int moveId, Bundle extras) {
22223                // Ignored
22224            }
22225
22226            @Override
22227            public void onStatusChanged(int moveId, int status, long estMillis) {
22228                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22229            }
22230        };
22231
22232        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22233        storage.setPrimaryStorageUuid(volumeUuid, callback);
22234        return realMoveId;
22235    }
22236
22237    @Override
22238    public int getMoveStatus(int moveId) {
22239        mContext.enforceCallingOrSelfPermission(
22240                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22241        return mMoveCallbacks.mLastStatus.get(moveId);
22242    }
22243
22244    @Override
22245    public void registerMoveCallback(IPackageMoveObserver callback) {
22246        mContext.enforceCallingOrSelfPermission(
22247                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22248        mMoveCallbacks.register(callback);
22249    }
22250
22251    @Override
22252    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22253        mContext.enforceCallingOrSelfPermission(
22254                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22255        mMoveCallbacks.unregister(callback);
22256    }
22257
22258    @Override
22259    public boolean setInstallLocation(int loc) {
22260        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22261                null);
22262        if (getInstallLocation() == loc) {
22263            return true;
22264        }
22265        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22266                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22267            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22268                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22269            return true;
22270        }
22271        return false;
22272   }
22273
22274    @Override
22275    public int getInstallLocation() {
22276        // allow instant app access
22277        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22278                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22279                PackageHelper.APP_INSTALL_AUTO);
22280    }
22281
22282    /** Called by UserManagerService */
22283    void cleanUpUser(UserManagerService userManager, int userHandle) {
22284        synchronized (mPackages) {
22285            mDirtyUsers.remove(userHandle);
22286            mUserNeedsBadging.delete(userHandle);
22287            mSettings.removeUserLPw(userHandle);
22288            mPendingBroadcasts.remove(userHandle);
22289            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22290            removeUnusedPackagesLPw(userManager, userHandle);
22291        }
22292    }
22293
22294    /**
22295     * We're removing userHandle and would like to remove any downloaded packages
22296     * that are no longer in use by any other user.
22297     * @param userHandle the user being removed
22298     */
22299    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22300        final boolean DEBUG_CLEAN_APKS = false;
22301        int [] users = userManager.getUserIds();
22302        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22303        while (psit.hasNext()) {
22304            PackageSetting ps = psit.next();
22305            if (ps.pkg == null) {
22306                continue;
22307            }
22308            final String packageName = ps.pkg.packageName;
22309            // Skip over if system app
22310            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22311                continue;
22312            }
22313            if (DEBUG_CLEAN_APKS) {
22314                Slog.i(TAG, "Checking package " + packageName);
22315            }
22316            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22317            if (keep) {
22318                if (DEBUG_CLEAN_APKS) {
22319                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22320                }
22321            } else {
22322                for (int i = 0; i < users.length; i++) {
22323                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22324                        keep = true;
22325                        if (DEBUG_CLEAN_APKS) {
22326                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22327                                    + users[i]);
22328                        }
22329                        break;
22330                    }
22331                }
22332            }
22333            if (!keep) {
22334                if (DEBUG_CLEAN_APKS) {
22335                    Slog.i(TAG, "  Removing package " + packageName);
22336                }
22337                mHandler.post(new Runnable() {
22338                    public void run() {
22339                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22340                                userHandle, 0);
22341                    } //end run
22342                });
22343            }
22344        }
22345    }
22346
22347    /** Called by UserManagerService */
22348    void createNewUser(int userId, String[] disallowedPackages) {
22349        synchronized (mInstallLock) {
22350            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22351        }
22352        synchronized (mPackages) {
22353            scheduleWritePackageRestrictionsLocked(userId);
22354            scheduleWritePackageListLocked(userId);
22355            applyFactoryDefaultBrowserLPw(userId);
22356            primeDomainVerificationsLPw(userId);
22357        }
22358    }
22359
22360    void onNewUserCreated(final int userId) {
22361        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22362        synchronized(mPackages) {
22363            // If permission review for legacy apps is required, we represent
22364            // dagerous permissions for such apps as always granted runtime
22365            // permissions to keep per user flag state whether review is needed.
22366            // Hence, if a new user is added we have to propagate dangerous
22367            // permission grants for these legacy apps.
22368            if (mSettings.mPermissions.mPermissionReviewRequired) {
22369// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22370                mPermissionManager.updateAllPermissions(
22371                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22372                        mPermissionCallback);
22373            }
22374        }
22375    }
22376
22377    @Override
22378    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22379        mContext.enforceCallingOrSelfPermission(
22380                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22381                "Only package verification agents can read the verifier device identity");
22382
22383        synchronized (mPackages) {
22384            return mSettings.getVerifierDeviceIdentityLPw();
22385        }
22386    }
22387
22388    @Override
22389    public void setPermissionEnforced(String permission, boolean enforced) {
22390        // TODO: Now that we no longer change GID for storage, this should to away.
22391        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22392                "setPermissionEnforced");
22393        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22394            synchronized (mPackages) {
22395                if (mSettings.mReadExternalStorageEnforced == null
22396                        || mSettings.mReadExternalStorageEnforced != enforced) {
22397                    mSettings.mReadExternalStorageEnforced =
22398                            enforced ? Boolean.TRUE : Boolean.FALSE;
22399                    mSettings.writeLPr();
22400                }
22401            }
22402            // kill any non-foreground processes so we restart them and
22403            // grant/revoke the GID.
22404            final IActivityManager am = ActivityManager.getService();
22405            if (am != null) {
22406                final long token = Binder.clearCallingIdentity();
22407                try {
22408                    am.killProcessesBelowForeground("setPermissionEnforcement");
22409                } catch (RemoteException e) {
22410                } finally {
22411                    Binder.restoreCallingIdentity(token);
22412                }
22413            }
22414        } else {
22415            throw new IllegalArgumentException("No selective enforcement for " + permission);
22416        }
22417    }
22418
22419    @Override
22420    @Deprecated
22421    public boolean isPermissionEnforced(String permission) {
22422        // allow instant applications
22423        return true;
22424    }
22425
22426    @Override
22427    public boolean isStorageLow() {
22428        // allow instant applications
22429        final long token = Binder.clearCallingIdentity();
22430        try {
22431            final DeviceStorageMonitorInternal
22432                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22433            if (dsm != null) {
22434                return dsm.isMemoryLow();
22435            } else {
22436                return false;
22437            }
22438        } finally {
22439            Binder.restoreCallingIdentity(token);
22440        }
22441    }
22442
22443    @Override
22444    public IPackageInstaller getPackageInstaller() {
22445        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22446            return null;
22447        }
22448        return mInstallerService;
22449    }
22450
22451    @Override
22452    public IArtManager getArtManager() {
22453        return mArtManagerService;
22454    }
22455
22456    private boolean userNeedsBadging(int userId) {
22457        int index = mUserNeedsBadging.indexOfKey(userId);
22458        if (index < 0) {
22459            final UserInfo userInfo;
22460            final long token = Binder.clearCallingIdentity();
22461            try {
22462                userInfo = sUserManager.getUserInfo(userId);
22463            } finally {
22464                Binder.restoreCallingIdentity(token);
22465            }
22466            final boolean b;
22467            if (userInfo != null && userInfo.isManagedProfile()) {
22468                b = true;
22469            } else {
22470                b = false;
22471            }
22472            mUserNeedsBadging.put(userId, b);
22473            return b;
22474        }
22475        return mUserNeedsBadging.valueAt(index);
22476    }
22477
22478    @Override
22479    public KeySet getKeySetByAlias(String packageName, String alias) {
22480        if (packageName == null || alias == null) {
22481            return null;
22482        }
22483        synchronized(mPackages) {
22484            final PackageParser.Package pkg = mPackages.get(packageName);
22485            if (pkg == null) {
22486                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22487                throw new IllegalArgumentException("Unknown package: " + packageName);
22488            }
22489            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22490            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22491                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22492                throw new IllegalArgumentException("Unknown package: " + packageName);
22493            }
22494            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22495            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22496        }
22497    }
22498
22499    @Override
22500    public KeySet getSigningKeySet(String packageName) {
22501        if (packageName == null) {
22502            return null;
22503        }
22504        synchronized(mPackages) {
22505            final int callingUid = Binder.getCallingUid();
22506            final int callingUserId = UserHandle.getUserId(callingUid);
22507            final PackageParser.Package pkg = mPackages.get(packageName);
22508            if (pkg == null) {
22509                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22510                throw new IllegalArgumentException("Unknown package: " + packageName);
22511            }
22512            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22513            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
22514                // filter and pretend the package doesn't exist
22515                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22516                        + ", uid:" + callingUid);
22517                throw new IllegalArgumentException("Unknown package: " + packageName);
22518            }
22519            if (pkg.applicationInfo.uid != callingUid
22520                    && Process.SYSTEM_UID != callingUid) {
22521                throw new SecurityException("May not access signing KeySet of other apps.");
22522            }
22523            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22524            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22525        }
22526    }
22527
22528    @Override
22529    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22530        final int callingUid = Binder.getCallingUid();
22531        if (getInstantAppPackageName(callingUid) != null) {
22532            return false;
22533        }
22534        if (packageName == null || ks == null) {
22535            return false;
22536        }
22537        synchronized(mPackages) {
22538            final PackageParser.Package pkg = mPackages.get(packageName);
22539            if (pkg == null
22540                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22541                            UserHandle.getUserId(callingUid))) {
22542                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22543                throw new IllegalArgumentException("Unknown package: " + packageName);
22544            }
22545            IBinder ksh = ks.getToken();
22546            if (ksh instanceof KeySetHandle) {
22547                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22548                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22549            }
22550            return false;
22551        }
22552    }
22553
22554    @Override
22555    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22556        final int callingUid = Binder.getCallingUid();
22557        if (getInstantAppPackageName(callingUid) != null) {
22558            return false;
22559        }
22560        if (packageName == null || ks == null) {
22561            return false;
22562        }
22563        synchronized(mPackages) {
22564            final PackageParser.Package pkg = mPackages.get(packageName);
22565            if (pkg == null
22566                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22567                            UserHandle.getUserId(callingUid))) {
22568                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22569                throw new IllegalArgumentException("Unknown package: " + packageName);
22570            }
22571            IBinder ksh = ks.getToken();
22572            if (ksh instanceof KeySetHandle) {
22573                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22574                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22575            }
22576            return false;
22577        }
22578    }
22579
22580    private void deletePackageIfUnusedLPr(final String packageName) {
22581        PackageSetting ps = mSettings.mPackages.get(packageName);
22582        if (ps == null) {
22583            return;
22584        }
22585        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22586            // TODO Implement atomic delete if package is unused
22587            // It is currently possible that the package will be deleted even if it is installed
22588            // after this method returns.
22589            mHandler.post(new Runnable() {
22590                public void run() {
22591                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22592                            0, PackageManager.DELETE_ALL_USERS);
22593                }
22594            });
22595        }
22596    }
22597
22598    /**
22599     * Check and throw if the given before/after packages would be considered a
22600     * downgrade.
22601     */
22602    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22603            throws PackageManagerException {
22604        if (after.getLongVersionCode() < before.getLongVersionCode()) {
22605            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22606                    "Update version code " + after.versionCode + " is older than current "
22607                    + before.getLongVersionCode());
22608        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22609            if (after.baseRevisionCode < before.baseRevisionCode) {
22610                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22611                        "Update base revision code " + after.baseRevisionCode
22612                        + " is older than current " + before.baseRevisionCode);
22613            }
22614
22615            if (!ArrayUtils.isEmpty(after.splitNames)) {
22616                for (int i = 0; i < after.splitNames.length; i++) {
22617                    final String splitName = after.splitNames[i];
22618                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22619                    if (j != -1) {
22620                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22621                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22622                                    "Update split " + splitName + " revision code "
22623                                    + after.splitRevisionCodes[i] + " is older than current "
22624                                    + before.splitRevisionCodes[j]);
22625                        }
22626                    }
22627                }
22628            }
22629        }
22630    }
22631
22632    private static class MoveCallbacks extends Handler {
22633        private static final int MSG_CREATED = 1;
22634        private static final int MSG_STATUS_CHANGED = 2;
22635
22636        private final RemoteCallbackList<IPackageMoveObserver>
22637                mCallbacks = new RemoteCallbackList<>();
22638
22639        private final SparseIntArray mLastStatus = new SparseIntArray();
22640
22641        public MoveCallbacks(Looper looper) {
22642            super(looper);
22643        }
22644
22645        public void register(IPackageMoveObserver callback) {
22646            mCallbacks.register(callback);
22647        }
22648
22649        public void unregister(IPackageMoveObserver callback) {
22650            mCallbacks.unregister(callback);
22651        }
22652
22653        @Override
22654        public void handleMessage(Message msg) {
22655            final SomeArgs args = (SomeArgs) msg.obj;
22656            final int n = mCallbacks.beginBroadcast();
22657            for (int i = 0; i < n; i++) {
22658                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22659                try {
22660                    invokeCallback(callback, msg.what, args);
22661                } catch (RemoteException ignored) {
22662                }
22663            }
22664            mCallbacks.finishBroadcast();
22665            args.recycle();
22666        }
22667
22668        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22669                throws RemoteException {
22670            switch (what) {
22671                case MSG_CREATED: {
22672                    callback.onCreated(args.argi1, (Bundle) args.arg2);
22673                    break;
22674                }
22675                case MSG_STATUS_CHANGED: {
22676                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22677                    break;
22678                }
22679            }
22680        }
22681
22682        private void notifyCreated(int moveId, Bundle extras) {
22683            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22684
22685            final SomeArgs args = SomeArgs.obtain();
22686            args.argi1 = moveId;
22687            args.arg2 = extras;
22688            obtainMessage(MSG_CREATED, args).sendToTarget();
22689        }
22690
22691        private void notifyStatusChanged(int moveId, int status) {
22692            notifyStatusChanged(moveId, status, -1);
22693        }
22694
22695        private void notifyStatusChanged(int moveId, int status, long estMillis) {
22696            Slog.v(TAG, "Move " + moveId + " status " + status);
22697
22698            final SomeArgs args = SomeArgs.obtain();
22699            args.argi1 = moveId;
22700            args.argi2 = status;
22701            args.arg3 = estMillis;
22702            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22703
22704            synchronized (mLastStatus) {
22705                mLastStatus.put(moveId, status);
22706            }
22707        }
22708    }
22709
22710    private final static class OnPermissionChangeListeners extends Handler {
22711        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22712
22713        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22714                new RemoteCallbackList<>();
22715
22716        public OnPermissionChangeListeners(Looper looper) {
22717            super(looper);
22718        }
22719
22720        @Override
22721        public void handleMessage(Message msg) {
22722            switch (msg.what) {
22723                case MSG_ON_PERMISSIONS_CHANGED: {
22724                    final int uid = msg.arg1;
22725                    handleOnPermissionsChanged(uid);
22726                } break;
22727            }
22728        }
22729
22730        public void addListenerLocked(IOnPermissionsChangeListener listener) {
22731            mPermissionListeners.register(listener);
22732
22733        }
22734
22735        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22736            mPermissionListeners.unregister(listener);
22737        }
22738
22739        public void onPermissionsChanged(int uid) {
22740            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22741                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22742            }
22743        }
22744
22745        private void handleOnPermissionsChanged(int uid) {
22746            final int count = mPermissionListeners.beginBroadcast();
22747            try {
22748                for (int i = 0; i < count; i++) {
22749                    IOnPermissionsChangeListener callback = mPermissionListeners
22750                            .getBroadcastItem(i);
22751                    try {
22752                        callback.onPermissionsChanged(uid);
22753                    } catch (RemoteException e) {
22754                        Log.e(TAG, "Permission listener is dead", e);
22755                    }
22756                }
22757            } finally {
22758                mPermissionListeners.finishBroadcast();
22759            }
22760        }
22761    }
22762
22763    private class PackageManagerNative extends IPackageManagerNative.Stub {
22764        @Override
22765        public String[] getNamesForUids(int[] uids) throws RemoteException {
22766            final String[] results = PackageManagerService.this.getNamesForUids(uids);
22767            // massage results so they can be parsed by the native binder
22768            for (int i = results.length - 1; i >= 0; --i) {
22769                if (results[i] == null) {
22770                    results[i] = "";
22771                }
22772            }
22773            return results;
22774        }
22775
22776        // NB: this differentiates between preloads and sideloads
22777        @Override
22778        public String getInstallerForPackage(String packageName) throws RemoteException {
22779            final String installerName = getInstallerPackageName(packageName);
22780            if (!TextUtils.isEmpty(installerName)) {
22781                return installerName;
22782            }
22783            // differentiate between preload and sideload
22784            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22785            ApplicationInfo appInfo = getApplicationInfo(packageName,
22786                                    /*flags*/ 0,
22787                                    /*userId*/ callingUser);
22788            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22789                return "preload";
22790            }
22791            return "";
22792        }
22793
22794        @Override
22795        public long getVersionCodeForPackage(String packageName) throws RemoteException {
22796            try {
22797                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22798                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22799                if (pInfo != null) {
22800                    return pInfo.getLongVersionCode();
22801                }
22802            } catch (Exception e) {
22803            }
22804            return 0;
22805        }
22806    }
22807
22808    private class PackageManagerInternalImpl extends PackageManagerInternal {
22809        @Override
22810        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
22811                int flagValues, int userId) {
22812            PackageManagerService.this.updatePermissionFlags(
22813                    permName, packageName, flagMask, flagValues, userId);
22814        }
22815
22816        @Override
22817        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
22818            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
22819        }
22820
22821        @Override
22822        public boolean isInstantApp(String packageName, int userId) {
22823            return PackageManagerService.this.isInstantApp(packageName, userId);
22824        }
22825
22826        @Override
22827        public String getInstantAppPackageName(int uid) {
22828            return PackageManagerService.this.getInstantAppPackageName(uid);
22829        }
22830
22831        @Override
22832        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
22833            synchronized (mPackages) {
22834                return PackageManagerService.this.filterAppAccessLPr(
22835                        (PackageSetting) pkg.mExtras, callingUid, userId);
22836            }
22837        }
22838
22839        @Override
22840        public PackageParser.Package getPackage(String packageName) {
22841            synchronized (mPackages) {
22842                packageName = resolveInternalPackageNameLPr(
22843                        packageName, PackageManager.VERSION_CODE_HIGHEST);
22844                return mPackages.get(packageName);
22845            }
22846        }
22847
22848        @Override
22849        public PackageList getPackageList(PackageListObserver observer) {
22850            synchronized (mPackages) {
22851                final int N = mPackages.size();
22852                final ArrayList<String> list = new ArrayList<>(N);
22853                for (int i = 0; i < N; i++) {
22854                    list.add(mPackages.keyAt(i));
22855                }
22856                final PackageList packageList = new PackageList(list, observer);
22857                if (observer != null) {
22858                    mPackageListObservers.add(packageList);
22859                }
22860                return packageList;
22861            }
22862        }
22863
22864        @Override
22865        public void removePackageListObserver(PackageListObserver observer) {
22866            synchronized (mPackages) {
22867                mPackageListObservers.remove(observer);
22868            }
22869        }
22870
22871        @Override
22872        public PackageParser.Package getDisabledPackage(String packageName) {
22873            synchronized (mPackages) {
22874                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
22875                return (ps != null) ? ps.pkg : null;
22876            }
22877        }
22878
22879        @Override
22880        public String getKnownPackageName(int knownPackage, int userId) {
22881            switch(knownPackage) {
22882                case PackageManagerInternal.PACKAGE_BROWSER:
22883                    return getDefaultBrowserPackageName(userId);
22884                case PackageManagerInternal.PACKAGE_INSTALLER:
22885                    return mRequiredInstallerPackage;
22886                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
22887                    return mSetupWizardPackage;
22888                case PackageManagerInternal.PACKAGE_SYSTEM:
22889                    return "android";
22890                case PackageManagerInternal.PACKAGE_VERIFIER:
22891                    return mRequiredVerifierPackage;
22892            }
22893            return null;
22894        }
22895
22896        @Override
22897        public boolean isResolveActivityComponent(ComponentInfo component) {
22898            return mResolveActivity.packageName.equals(component.packageName)
22899                    && mResolveActivity.name.equals(component.name);
22900        }
22901
22902        @Override
22903        public void setLocationPackagesProvider(PackagesProvider provider) {
22904            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
22905        }
22906
22907        @Override
22908        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
22909            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
22910        }
22911
22912        @Override
22913        public void setSmsAppPackagesProvider(PackagesProvider provider) {
22914            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
22915        }
22916
22917        @Override
22918        public void setDialerAppPackagesProvider(PackagesProvider provider) {
22919            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
22920        }
22921
22922        @Override
22923        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
22924            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
22925        }
22926
22927        @Override
22928        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
22929            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
22930        }
22931
22932        @Override
22933        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
22934            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
22935        }
22936
22937        @Override
22938        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
22939            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
22940        }
22941
22942        @Override
22943        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
22944            synchronized (mPackages) {
22945                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
22946            }
22947            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
22948        }
22949
22950        @Override
22951        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
22952            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
22953                    packageName, userId);
22954        }
22955
22956        @Override
22957        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
22958            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
22959                    packageName, userId);
22960        }
22961
22962        @Override
22963        public void setKeepUninstalledPackages(final List<String> packageList) {
22964            Preconditions.checkNotNull(packageList);
22965            List<String> removedFromList = null;
22966            synchronized (mPackages) {
22967                if (mKeepUninstalledPackages != null) {
22968                    final int packagesCount = mKeepUninstalledPackages.size();
22969                    for (int i = 0; i < packagesCount; i++) {
22970                        String oldPackage = mKeepUninstalledPackages.get(i);
22971                        if (packageList != null && packageList.contains(oldPackage)) {
22972                            continue;
22973                        }
22974                        if (removedFromList == null) {
22975                            removedFromList = new ArrayList<>();
22976                        }
22977                        removedFromList.add(oldPackage);
22978                    }
22979                }
22980                mKeepUninstalledPackages = new ArrayList<>(packageList);
22981                if (removedFromList != null) {
22982                    final int removedCount = removedFromList.size();
22983                    for (int i = 0; i < removedCount; i++) {
22984                        deletePackageIfUnusedLPr(removedFromList.get(i));
22985                    }
22986                }
22987            }
22988        }
22989
22990        @Override
22991        public boolean isPermissionsReviewRequired(String packageName, int userId) {
22992            synchronized (mPackages) {
22993                return mPermissionManager.isPermissionsReviewRequired(
22994                        mPackages.get(packageName), userId);
22995            }
22996        }
22997
22998        @Override
22999        public PackageInfo getPackageInfo(
23000                String packageName, int flags, int filterCallingUid, int userId) {
23001            return PackageManagerService.this
23002                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23003                            flags, filterCallingUid, userId);
23004        }
23005
23006        @Override
23007        public int getPackageUid(String packageName, int flags, int userId) {
23008            return PackageManagerService.this
23009                    .getPackageUid(packageName, flags, userId);
23010        }
23011
23012        @Override
23013        public ApplicationInfo getApplicationInfo(
23014                String packageName, int flags, int filterCallingUid, int userId) {
23015            return PackageManagerService.this
23016                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23017        }
23018
23019        @Override
23020        public ActivityInfo getActivityInfo(
23021                ComponentName component, int flags, int filterCallingUid, int userId) {
23022            return PackageManagerService.this
23023                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23024        }
23025
23026        @Override
23027        public List<ResolveInfo> queryIntentActivities(
23028                Intent intent, int flags, int filterCallingUid, int userId) {
23029            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23030            return PackageManagerService.this
23031                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23032                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23033        }
23034
23035        @Override
23036        public List<ResolveInfo> queryIntentServices(
23037                Intent intent, int flags, int callingUid, int userId) {
23038            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23039            return PackageManagerService.this
23040                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23041                            false);
23042        }
23043
23044        @Override
23045        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23046                int userId) {
23047            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23048        }
23049
23050        @Override
23051        public void setDeviceAndProfileOwnerPackages(
23052                int deviceOwnerUserId, String deviceOwnerPackage,
23053                SparseArray<String> profileOwnerPackages) {
23054            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23055                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23056        }
23057
23058        @Override
23059        public boolean isPackageDataProtected(int userId, String packageName) {
23060            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23061        }
23062
23063        @Override
23064        public boolean isPackageEphemeral(int userId, String packageName) {
23065            synchronized (mPackages) {
23066                final PackageSetting ps = mSettings.mPackages.get(packageName);
23067                return ps != null ? ps.getInstantApp(userId) : false;
23068            }
23069        }
23070
23071        @Override
23072        public boolean wasPackageEverLaunched(String packageName, int userId) {
23073            synchronized (mPackages) {
23074                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23075            }
23076        }
23077
23078        @Override
23079        public void grantRuntimePermission(String packageName, String permName, int userId,
23080                boolean overridePolicy) {
23081            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23082                    permName, packageName, overridePolicy, getCallingUid(), userId,
23083                    mPermissionCallback);
23084        }
23085
23086        @Override
23087        public void revokeRuntimePermission(String packageName, String permName, int userId,
23088                boolean overridePolicy) {
23089            mPermissionManager.revokeRuntimePermission(
23090                    permName, packageName, overridePolicy, getCallingUid(), userId,
23091                    mPermissionCallback);
23092        }
23093
23094        @Override
23095        public String getNameForUid(int uid) {
23096            return PackageManagerService.this.getNameForUid(uid);
23097        }
23098
23099        @Override
23100        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23101                Intent origIntent, String resolvedType, String callingPackage,
23102                Bundle verificationBundle, int userId) {
23103            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23104                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23105                    userId);
23106        }
23107
23108        @Override
23109        public void grantEphemeralAccess(int userId, Intent intent,
23110                int targetAppId, int ephemeralAppId) {
23111            synchronized (mPackages) {
23112                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23113                        targetAppId, ephemeralAppId);
23114            }
23115        }
23116
23117        @Override
23118        public boolean isInstantAppInstallerComponent(ComponentName component) {
23119            synchronized (mPackages) {
23120                return mInstantAppInstallerActivity != null
23121                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23122            }
23123        }
23124
23125        @Override
23126        public void pruneInstantApps() {
23127            mInstantAppRegistry.pruneInstantApps();
23128        }
23129
23130        @Override
23131        public String getSetupWizardPackageName() {
23132            return mSetupWizardPackage;
23133        }
23134
23135        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23136            if (policy != null) {
23137                mExternalSourcesPolicy = policy;
23138            }
23139        }
23140
23141        @Override
23142        public boolean isPackagePersistent(String packageName) {
23143            synchronized (mPackages) {
23144                PackageParser.Package pkg = mPackages.get(packageName);
23145                return pkg != null
23146                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23147                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23148                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23149                        : false;
23150            }
23151        }
23152
23153        @Override
23154        public boolean isLegacySystemApp(Package pkg) {
23155            synchronized (mPackages) {
23156                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23157                return mPromoteSystemApps
23158                        && ps.isSystem()
23159                        && mExistingSystemPackages.contains(ps.name);
23160            }
23161        }
23162
23163        @Override
23164        public List<PackageInfo> getOverlayPackages(int userId) {
23165            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23166            synchronized (mPackages) {
23167                for (PackageParser.Package p : mPackages.values()) {
23168                    if (p.mOverlayTarget != null) {
23169                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23170                        if (pkg != null) {
23171                            overlayPackages.add(pkg);
23172                        }
23173                    }
23174                }
23175            }
23176            return overlayPackages;
23177        }
23178
23179        @Override
23180        public List<String> getTargetPackageNames(int userId) {
23181            List<String> targetPackages = new ArrayList<>();
23182            synchronized (mPackages) {
23183                for (PackageParser.Package p : mPackages.values()) {
23184                    if (p.mOverlayTarget == null) {
23185                        targetPackages.add(p.packageName);
23186                    }
23187                }
23188            }
23189            return targetPackages;
23190        }
23191
23192        @Override
23193        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23194                @Nullable List<String> overlayPackageNames) {
23195            synchronized (mPackages) {
23196                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23197                    Slog.e(TAG, "failed to find package " + targetPackageName);
23198                    return false;
23199                }
23200                ArrayList<String> overlayPaths = null;
23201                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23202                    final int N = overlayPackageNames.size();
23203                    overlayPaths = new ArrayList<>(N);
23204                    for (int i = 0; i < N; i++) {
23205                        final String packageName = overlayPackageNames.get(i);
23206                        final PackageParser.Package pkg = mPackages.get(packageName);
23207                        if (pkg == null) {
23208                            Slog.e(TAG, "failed to find package " + packageName);
23209                            return false;
23210                        }
23211                        overlayPaths.add(pkg.baseCodePath);
23212                    }
23213                }
23214
23215                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23216                ps.setOverlayPaths(overlayPaths, userId);
23217                return true;
23218            }
23219        }
23220
23221        @Override
23222        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23223                int flags, int userId, boolean resolveForStart) {
23224            return resolveIntentInternal(
23225                    intent, resolvedType, flags, userId, resolveForStart);
23226        }
23227
23228        @Override
23229        public ResolveInfo resolveService(Intent intent, String resolvedType,
23230                int flags, int userId, int callingUid) {
23231            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23232        }
23233
23234        @Override
23235        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23236            return PackageManagerService.this.resolveContentProviderInternal(
23237                    name, flags, userId);
23238        }
23239
23240        @Override
23241        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23242            synchronized (mPackages) {
23243                mIsolatedOwners.put(isolatedUid, ownerUid);
23244            }
23245        }
23246
23247        @Override
23248        public void removeIsolatedUid(int isolatedUid) {
23249            synchronized (mPackages) {
23250                mIsolatedOwners.delete(isolatedUid);
23251            }
23252        }
23253
23254        @Override
23255        public int getUidTargetSdkVersion(int uid) {
23256            synchronized (mPackages) {
23257                return getUidTargetSdkVersionLockedLPr(uid);
23258            }
23259        }
23260
23261        @Override
23262        public boolean canAccessInstantApps(int callingUid, int userId) {
23263            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23264        }
23265
23266        @Override
23267        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23268            synchronized (mPackages) {
23269                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23270            }
23271        }
23272
23273        @Override
23274        public void notifyPackageUse(String packageName, int reason) {
23275            synchronized (mPackages) {
23276                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23277            }
23278        }
23279    }
23280
23281    @Override
23282    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23283        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23284        synchronized (mPackages) {
23285            final long identity = Binder.clearCallingIdentity();
23286            try {
23287                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23288                        packageNames, userId);
23289            } finally {
23290                Binder.restoreCallingIdentity(identity);
23291            }
23292        }
23293    }
23294
23295    @Override
23296    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23297        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23298        synchronized (mPackages) {
23299            final long identity = Binder.clearCallingIdentity();
23300            try {
23301                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23302                        packageNames, userId);
23303            } finally {
23304                Binder.restoreCallingIdentity(identity);
23305            }
23306        }
23307    }
23308
23309    private static void enforceSystemOrPhoneCaller(String tag) {
23310        int callingUid = Binder.getCallingUid();
23311        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23312            throw new SecurityException(
23313                    "Cannot call " + tag + " from UID " + callingUid);
23314        }
23315    }
23316
23317    boolean isHistoricalPackageUsageAvailable() {
23318        return mPackageUsage.isHistoricalPackageUsageAvailable();
23319    }
23320
23321    /**
23322     * Return a <b>copy</b> of the collection of packages known to the package manager.
23323     * @return A copy of the values of mPackages.
23324     */
23325    Collection<PackageParser.Package> getPackages() {
23326        synchronized (mPackages) {
23327            return new ArrayList<>(mPackages.values());
23328        }
23329    }
23330
23331    /**
23332     * Logs process start information (including base APK hash) to the security log.
23333     * @hide
23334     */
23335    @Override
23336    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23337            String apkFile, int pid) {
23338        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23339            return;
23340        }
23341        if (!SecurityLog.isLoggingEnabled()) {
23342            return;
23343        }
23344        Bundle data = new Bundle();
23345        data.putLong("startTimestamp", System.currentTimeMillis());
23346        data.putString("processName", processName);
23347        data.putInt("uid", uid);
23348        data.putString("seinfo", seinfo);
23349        data.putString("apkFile", apkFile);
23350        data.putInt("pid", pid);
23351        Message msg = mProcessLoggingHandler.obtainMessage(
23352                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23353        msg.setData(data);
23354        mProcessLoggingHandler.sendMessage(msg);
23355    }
23356
23357    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23358        return mCompilerStats.getPackageStats(pkgName);
23359    }
23360
23361    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23362        return getOrCreateCompilerPackageStats(pkg.packageName);
23363    }
23364
23365    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23366        return mCompilerStats.getOrCreatePackageStats(pkgName);
23367    }
23368
23369    public void deleteCompilerPackageStats(String pkgName) {
23370        mCompilerStats.deletePackageStats(pkgName);
23371    }
23372
23373    @Override
23374    public int getInstallReason(String packageName, int userId) {
23375        final int callingUid = Binder.getCallingUid();
23376        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23377                true /* requireFullPermission */, false /* checkShell */,
23378                "get install reason");
23379        synchronized (mPackages) {
23380            final PackageSetting ps = mSettings.mPackages.get(packageName);
23381            if (filterAppAccessLPr(ps, callingUid, userId)) {
23382                return PackageManager.INSTALL_REASON_UNKNOWN;
23383            }
23384            if (ps != null) {
23385                return ps.getInstallReason(userId);
23386            }
23387        }
23388        return PackageManager.INSTALL_REASON_UNKNOWN;
23389    }
23390
23391    @Override
23392    public boolean canRequestPackageInstalls(String packageName, int userId) {
23393        return canRequestPackageInstallsInternal(packageName, 0, userId,
23394                true /* throwIfPermNotDeclared*/);
23395    }
23396
23397    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23398            boolean throwIfPermNotDeclared) {
23399        int callingUid = Binder.getCallingUid();
23400        int uid = getPackageUid(packageName, 0, userId);
23401        if (callingUid != uid && callingUid != Process.ROOT_UID
23402                && callingUid != Process.SYSTEM_UID) {
23403            throw new SecurityException(
23404                    "Caller uid " + callingUid + " does not own package " + packageName);
23405        }
23406        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23407        if (info == null) {
23408            return false;
23409        }
23410        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23411            return false;
23412        }
23413        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23414        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23415        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23416            if (throwIfPermNotDeclared) {
23417                throw new SecurityException("Need to declare " + appOpPermission
23418                        + " to call this api");
23419            } else {
23420                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23421                return false;
23422            }
23423        }
23424        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23425            return false;
23426        }
23427        if (mExternalSourcesPolicy != null) {
23428            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23429            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23430                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23431            }
23432        }
23433        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23434    }
23435
23436    @Override
23437    public ComponentName getInstantAppResolverSettingsComponent() {
23438        return mInstantAppResolverSettingsComponent;
23439    }
23440
23441    @Override
23442    public ComponentName getInstantAppInstallerComponent() {
23443        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23444            return null;
23445        }
23446        return mInstantAppInstallerActivity == null
23447                ? null : mInstantAppInstallerActivity.getComponentName();
23448    }
23449
23450    @Override
23451    public String getInstantAppAndroidId(String packageName, int userId) {
23452        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
23453                "getInstantAppAndroidId");
23454        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
23455                true /* requireFullPermission */, false /* checkShell */,
23456                "getInstantAppAndroidId");
23457        // Make sure the target is an Instant App.
23458        if (!isInstantApp(packageName, userId)) {
23459            return null;
23460        }
23461        synchronized (mPackages) {
23462            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
23463        }
23464    }
23465
23466    boolean canHaveOatDir(String packageName) {
23467        synchronized (mPackages) {
23468            PackageParser.Package p = mPackages.get(packageName);
23469            if (p == null) {
23470                return false;
23471            }
23472            return p.canHaveOatDir();
23473        }
23474    }
23475
23476    private String getOatDir(PackageParser.Package pkg) {
23477        if (!pkg.canHaveOatDir()) {
23478            return null;
23479        }
23480        File codePath = new File(pkg.codePath);
23481        if (codePath.isDirectory()) {
23482            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
23483        }
23484        return null;
23485    }
23486
23487    void deleteOatArtifactsOfPackage(String packageName) {
23488        final String[] instructionSets;
23489        final List<String> codePaths;
23490        final String oatDir;
23491        final PackageParser.Package pkg;
23492        synchronized (mPackages) {
23493            pkg = mPackages.get(packageName);
23494        }
23495        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
23496        codePaths = pkg.getAllCodePaths();
23497        oatDir = getOatDir(pkg);
23498
23499        for (String codePath : codePaths) {
23500            for (String isa : instructionSets) {
23501                try {
23502                    mInstaller.deleteOdex(codePath, isa, oatDir);
23503                } catch (InstallerException e) {
23504                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
23505                }
23506            }
23507        }
23508    }
23509
23510    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
23511        Set<String> unusedPackages = new HashSet<>();
23512        long currentTimeInMillis = System.currentTimeMillis();
23513        synchronized (mPackages) {
23514            for (PackageParser.Package pkg : mPackages.values()) {
23515                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
23516                if (ps == null) {
23517                    continue;
23518                }
23519                PackageDexUsage.PackageUseInfo packageUseInfo =
23520                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
23521                if (PackageManagerServiceUtils
23522                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
23523                                downgradeTimeThresholdMillis, packageUseInfo,
23524                                pkg.getLatestPackageUseTimeInMills(),
23525                                pkg.getLatestForegroundPackageUseTimeInMills())) {
23526                    unusedPackages.add(pkg.packageName);
23527                }
23528            }
23529        }
23530        return unusedPackages;
23531    }
23532}
23533
23534interface PackageSender {
23535    /**
23536     * @param userIds User IDs where the action occurred on a full application
23537     * @param instantUserIds User IDs where the action occurred on an instant application
23538     */
23539    void sendPackageBroadcast(final String action, final String pkg,
23540        final Bundle extras, final int flags, final String targetPkg,
23541        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
23542    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
23543        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
23544    void notifyPackageAdded(String packageName);
23545    void notifyPackageRemoved(String packageName);
23546}
23547